Compare commits

..

No commits in common. "ca58dd65a6ad3f8ebea0163b843b00dde838d6d6" and "033c12365dec616bdd517ac8624ac6c3e0353fb2" have entirely different histories.

86 changed files with 256 additions and 2294 deletions

Binary file not shown.

Binary file not shown.

View File

@ -9,7 +9,6 @@ UI_OFF,Off
UI_BACK,"⏎ Back" UI_BACK,"⏎ Back"
UI_LOCKED,Locked UI_LOCKED,Locked
UI_QUIT,Quit UI_QUIT,Quit
UI_LOADING,Loading
, ,
PAUSE_HEADING,Paused PAUSE_HEADING,Paused
PAUSE_RESUME,Resume PAUSE_RESUME,Resume
@ -18,7 +17,6 @@ PAUSE_END,"Quit to Title"
PAUSE_END_MSG,"End the game and return to the title screen?\nUnsaved progress will be lost." PAUSE_END_MSG,"End the game and return to the title screen?\nUnsaved progress will be lost."
PAUSE_QUIT,"Quit to Desktop" PAUSE_QUIT,"Quit to Desktop"
PAUSE_QUIT_MSG,"Quit to desktop?\nUnsaved progress will be lost." PAUSE_QUIT_MSG,"Quit to desktop?\nUnsaved progress will be lost."
PAUSE_DEBUG,"Debug Menu"
, ,
SETTINGS_GAME,Game SETTINGS_GAME,Game
SETTINGS_GAME_HEADING,"Game Configuration" SETTINGS_GAME_HEADING,"Game Configuration"

1 keys en
9 UI_BACK ⏎ Back
10 UI_LOCKED Locked
11 UI_QUIT Quit
UI_LOADING Loading
12
13 PAUSE_HEADING Paused
14 PAUSE_RESUME Resume
17 PAUSE_END_MSG End the game and return to the title screen?\nUnsaved progress will be lost.
18 PAUSE_QUIT Quit to Desktop
19 PAUSE_QUIT_MSG Quit to desktop?\nUnsaved progress will be lost.
PAUSE_DEBUG Debug Menu
20
21 SETTINGS_GAME Game
22 SETTINGS_GAME_HEADING Game Configuration

BIN
assets/ui/corpo_logo/corpo_logo_128.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dixpjnlaj86x2"
path="res://.godot/imported/corpo_logo_128.png-3de86c663523882d9e0ebffd7de5c43c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/ui/corpo_logo/corpo_logo_128.png"
dest_files=["res://.godot/imported/corpo_logo_128.png-3de86c663523882d9e0ebffd7de5c43c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

BIN
assets/ui/corpo_logo/corpo_logo_128_bg.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b7ds08rj0yk7j"
path="res://.godot/imported/corpo_logo_128_bg.png-89eb09aa3ea1cb5cb304d1d6904ce810.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/ui/corpo_logo/corpo_logo_128_bg.png"
dest_files=["res://.godot/imported/corpo_logo_128_bg.png-89eb09aa3ea1cb5cb304d1d6904ce810.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

BIN
assets/ui/corpo_logo/corpo_logo_256.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dbr66ubeql7gi"
path="res://.godot/imported/corpo_logo_256.png-58bfe662ab369a650f7147768bd46884.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/ui/corpo_logo/corpo_logo_256.png"
dest_files=["res://.godot/imported/corpo_logo_256.png-58bfe662ab369a650f7147768bd46884.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

BIN
assets/ui/corpo_logo/corpo_logo_512.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cbosbnfdmhu27"
path="res://.godot/imported/corpo_logo_512.png-b05524db051b0e137f14c9416740afff.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/ui/corpo_logo/corpo_logo_512.png"
dest_files=["res://.godot/imported/corpo_logo_512.png-b05524db051b0e137f14c9416740afff.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

BIN
assets/ui/title.png (Stored with Git LFS)

Binary file not shown.

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://buc0oy5col0et"
path="res://.godot/imported/title.png-534804d7bf6a63fbbb0c46e68d8e4660.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/ui/title.png"
dest_files=["res://.godot/imported/title.png-534804d7bf6a63fbbb0c46e68d8e4660.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@ -16,7 +16,7 @@ var boosted := false
func _ready() -> void: func _ready() -> void:
World.instance.manager.alert_raised.connect(_on_alert_raised) Game.manager.alert_raised.connect(_on_alert_raised)
func get_target_volume() -> float: func get_target_volume() -> float:
@ -81,7 +81,7 @@ func _on_player_exits_ship(_body: Node3D) -> void:
func _on_alert_raised(new_level: int) -> void: func _on_alert_raised(new_level: int) -> void:
if new_level == World.instance.manager.MAX_ALERT: if new_level == Game.manager.MAX_ALERT:
suppress(30) suppress(30)
else: else:
boost(10.0) boost(10.0)

View File

@ -1,8 +1,7 @@
[gd_scene load_steps=22 format=3 uid="uid://bov4ok76woyc"] [gd_scene load_steps=21 format=3 uid="uid://bov4ok76woyc"]
[ext_resource type="PackedScene" uid="uid://crydi5cjgfwe5" path="res://levels/ghost_ship/ghost_ship_level.tscn" id="1_aj2m7"] [ext_resource type="PackedScene" uid="uid://crydi5cjgfwe5" path="res://levels/ghost_ship/ghost_ship_level.tscn" id="1_aj2m7"]
[ext_resource type="Environment" uid="uid://bkvij3ljl5ox3" path="res://levels/ghost_ship/environment_3.tres" id="1_h081y"] [ext_resource type="Environment" uid="uid://bkvij3ljl5ox3" path="res://levels/ghost_ship/environment_3.tres" id="1_h081y"]
[ext_resource type="Script" uid="uid://68r4ht5ut1ct" path="res://src/game/level.gd" id="1_law5k"]
[ext_resource type="PackedScene" uid="uid://bwe2jdmvinhqd" path="res://src/player/player.tscn" id="2_0ef5p"] [ext_resource type="PackedScene" uid="uid://bwe2jdmvinhqd" path="res://src/player/player.tscn" id="2_0ef5p"]
[ext_resource type="PackedScene" uid="uid://d1kacn4b60ucy" path="res://src/ui/post_processing.tscn" id="3_o7mxe"] [ext_resource type="PackedScene" uid="uid://d1kacn4b60ucy" path="res://src/ui/post_processing.tscn" id="3_o7mxe"]
[ext_resource type="AudioStream" uid="uid://dx4d8a3mgpws" path="res://assets/sfx/ambient/drone_loop.wav" id="5_ejh2c"] [ext_resource type="AudioStream" uid="uid://dx4d8a3mgpws" path="res://assets/sfx/ambient/drone_loop.wav" id="5_ejh2c"]
@ -43,9 +42,6 @@ stream_10/stream = ExtResource("10_h081y")
stream_10/weight = 0.2 stream_10/weight = 0.2
[node name="GhostShip" type="Node3D"] [node name="GhostShip" type="Node3D"]
script = ExtResource("1_law5k")
id = "ghost_ship"
pretty_name = "The HFCS Gnurk"
[node name="WorldEnvironment" type="WorldEnvironment" parent="."] [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = ExtResource("1_h081y") environment = ExtResource("1_h081y")

View File

@ -22,28 +22,28 @@ const STALLING_MSG := "\n\n\n\n\n. . . C a l c u l a t i n G . . ."
func _ready() -> void: func _ready() -> void:
World.instance.manager.grunk_emptied.connect(_on_tank_emptied) Game.manager.grunk_emptied.connect(_on_tank_emptied)
recompute() recompute()
func _next_milestone_name() -> String: func _next_milestone_name() -> String:
var next_milestone := World.instance.manager.next_milestone() var next_milestone := Game.manager.next_milestone()
return next_milestone.name if next_milestone else "NOTHING" return next_milestone.name if next_milestone else "NOTHING"
func _next_milestone_amount() -> String: func _next_milestone_amount() -> String:
var next_milestone_amt := World.instance.manager.next_milestone_amount() var next_milestone_amt := Game.manager.next_milestone_amount()
return str(next_milestone_amt) if next_milestone_amt >= 0 else "NEVER" return str(next_milestone_amt) if next_milestone_amt >= 0 else "NEVER"
func build_message() -> String: func build_message() -> String:
var msg_lines := World.instance.manager.latest_milestone().message.split("\n") var msg_lines := Game.manager.latest_milestone().message.split("\n")
var line_1 := msg_lines[0] var line_1 := msg_lines[0]
var line_2 := msg_lines[1] if len(msg_lines) >= 2 else "" var line_2 := msg_lines[1] if len(msg_lines) >= 2 else ""
return MESSAGE_FMT.format( return MESSAGE_FMT.format(
[ [
int(World.instance.manager.grunk_quota), int(Game.manager.grunk_quota),
int(World.instance.manager.grunk_vault), int(Game.manager.grunk_vault),
line_1, line_1,
line_2, line_2,
_next_milestone_name(), _next_milestone_name(),

View File

@ -3,7 +3,6 @@ extends Node3D
# TODO figure out whatever this is lol # TODO figure out whatever this is lol
const MAX_GRUNK := 6400000.0 const MAX_GRUNK := 6400000.0
const MIN_LIQUID_PCT := 0.001
const LIQUID_FACTOR := 2.8 const LIQUID_FACTOR := 2.8
const TANK_FILL_TIME := 1.0 const TANK_FILL_TIME := 1.0
@ -14,12 +13,7 @@ const TANK_FILL_TIME := 1.0
func _ready() -> void: func _ready() -> void:
World.instance.manager.grunk_collected.connect(_enable_tank) Game.manager.grunk_collected.connect(_enable_tank)
_deferred_init.call_deferred()
func _deferred_init() -> void:
set_liquid_level(vault_fill_pct())
func _enable_tank(_delta: float) -> void: func _enable_tank(_delta: float) -> void:
@ -30,19 +24,14 @@ func _enable_tank(_delta: float) -> void:
func deposit_grunk() -> void: func deposit_grunk() -> void:
# Tank is disabled until the player collects more grunk. # Tank is disabled until the player collects more grunk.
tank_interactor.enabled = false tank_interactor.enabled = false
World.instance.manager.deposit_tank() Game.manager.deposit_tank()
set_liquid_level(vault_fill_pct()) set_liquid_level(clampf(Game.manager.grunk_vault / MAX_GRUNK, 0.0, 1.0))
grunk_pump_sfx.play() grunk_pump_sfx.play()
func vault_fill_pct() -> float:
return clampf(World.instance.manager.grunk_vault / MAX_GRUNK, 0.0, 1.0)
func set_liquid_level(proportion: float) -> void: func set_liquid_level(proportion: float) -> void:
if proportion > MIN_LIQUID_PCT:
( (
create_tween() create_tween()
. tween_property(grunk_liquid, "position:y", proportion * LIQUID_FACTOR, TANK_FILL_TIME) . tween_property(grunk_liquid, "position:y", proportion * LIQUID_FACTOR, TANK_FILL_TIME)

View File

@ -1,4 +1,4 @@
extends Level extends Node3D
## Game mechanic testing level ## Game mechanic testing level
@onready var gunk_hall: GunkBody = %GunkHallBody @onready var gunk_hall: GunkBody = %GunkHallBody

View File

@ -1,7 +1,6 @@
[gd_scene load_steps=13 format=4 uid="uid://cfqirm2o3uo4k"] [gd_scene load_steps=12 format=4 uid="uid://cfqirm2o3uo4k"]
[ext_resource type="PackedScene" uid="uid://c2omlx4ptrc01" path="res://src/world/gunk_body/gunk_body.tscn" id="1_cr8wn"] [ext_resource type="PackedScene" uid="uid://c2omlx4ptrc01" path="res://src/world/gunk_body/gunk_body.tscn" id="1_cr8wn"]
[ext_resource type="Texture2D" uid="uid://8cm835h4gxwe" path="res://assets/debug_mask.png" id="2_7477u"]
[ext_resource type="Shader" uid="uid://ckxc0ngd37rtk" path="res://src/shaders/gunk.gdshader" id="2_lrgpr"] [ext_resource type="Shader" uid="uid://ckxc0ngd37rtk" path="res://src/shaders/gunk.gdshader" id="2_lrgpr"]
[ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="3_7477u"] [ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="3_7477u"]
@ -58,7 +57,7 @@ seamless = true
seamless_blend_skirt = 0.5 seamless_blend_skirt = 0.5
noise = ExtResource("3_7477u") noise = ExtResource("3_7477u")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lrgpr"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_qjnj2"]
resource_local_to_scene = true resource_local_to_scene = true
render_priority = 0 render_priority = 0
shader = ExtResource("2_lrgpr") shader = ExtResource("2_lrgpr")
@ -70,7 +69,6 @@ shader_parameter/time_pixellation = 30.0
shader_parameter/roughness = 0.15 shader_parameter/roughness = 0.15
shader_parameter/specular_contribution = 0.8 shader_parameter/specular_contribution = 0.8
shader_parameter/emission_strength = 0.02 shader_parameter/emission_strength = 0.02
shader_parameter/normal_scale = 1.0
shader_parameter/uv_scale = Vector2(4, 4) shader_parameter/uv_scale = Vector2(4, 4)
shader_parameter/time_scale = 0.2 shader_parameter/time_scale = 0.2
shader_parameter/edge_bleed = 0.25 shader_parameter/edge_bleed = 0.25
@ -81,7 +79,6 @@ shader_parameter/jitter_magnitude = 0.0
shader_parameter/jitter_time_scale = 0.1 shader_parameter/jitter_time_scale = 0.1
shader_parameter/vertex_inflation = 0.0 shader_parameter/vertex_inflation = 0.0
shader_parameter/inflation_pixellation = 10.0 shader_parameter/inflation_pixellation = 10.0
shader_parameter/overlay_emission_scale = 1.0
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_x2vho"] [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_x2vho"]
data = PackedVector3Array(-1, 1, 0.1, -1, -0.8, 0.1, -1, 1, -0.1, -1, 1, -0.1, -1, -0.8, 0.1, -1, -0.8, -0.1, -1, -1, 0.1, -1, -0.8, -0.1, -1, -0.8, 0.1, -1, -1, -2.3, -1, -0.8, -0.1, -1, -1, 0.1, -1, -0.8, -2.3, -1, -0.8, -0.1, -1, -1, -2.3, -1, -0.8, -2.1, -1, -0.8, -0.1, -1, -0.8, -2.3, -1, -0.8, -2.1, -1, -0.8, -2.3, -1, 1, -2.1, -1, 1, -2.1, -1, -0.8, -2.3, -1, 1, -2.3, -1, 1, -0.1, -1, -0.8, -0.1, 1, 1, -0.1, 1, 1, -0.1, -1, -0.8, -0.1, 1, -0.8, -0.1, 1, 1, -0.1, 1, -0.8, -0.1, 1, 1, 0.1, 1, 1, 0.1, 1, -0.8, -0.1, 1, -0.8, 0.1, 1, -0.8, -0.1, 1, -1, 0.1, 1, -0.8, 0.1, 1, -0.8, -2.1, 1, -1, 0.1, 1, -0.8, -0.1, 1, -0.8, -2.3, 1, -1, 0.1, 1, -0.8, -2.1, 1, -1, -2.3, 1, -1, 0.1, 1, -0.8, -2.3, 1, -0.8, -2.3, 1, -0.8, -2.1, 1, 1, -2.3, 1, 1, -2.3, 1, -0.8, -2.1, 1, 1, -2.1, 1, 1, 0.1, 1, -0.8, 0.1, -1, 1, 0.1, -1, 1, 0.1, 1, -0.8, 0.1, -1, -0.8, 0.1, 1, -0.8, 0.1, 1, -1, 0.1, -1, -0.8, 0.1, -1, -0.8, 0.1, 1, -1, 0.1, -1, -1, 0.1, -1, -1, -2.3, -1, -1, 0.1, 1, -1, -2.3, 1, -1, -2.3, -1, -1, 0.1, 1, -1, 0.1, -1, 1, -0.1, 1, 1, -0.1, -1, 1, 0.1, -1, 1, 0.1, 1, 1, -0.1, 1, 1, 0.1, 1, -0.8, -0.1, -1, -0.8, -0.1, 1, -0.8, -2.1, 1, -0.8, -2.1, -1, -0.8, -0.1, -1, -0.8, -2.1, -1, -0.8, -2.3, -1, -1, -2.3, 1, -0.8, -2.3, 1, -0.8, -2.3, -1, -1, -2.3, 1, -1, -2.3, -1, -0.8, -2.3, 1, -0.8, -2.3, -1, 1, -2.3, -1, 1, -2.3, 1, -0.8, -2.3, 1, 1, -2.3, 1, 1, -2.1, -1, 1, -2.1, 1, 1, -2.3, 1, 1, -2.3, -1, 1, -2.1, -1, 1, -2.3, 1, -0.8, -2.1, -1, -0.8, -2.1, 1, 1, -2.1, 1, 1, -2.1, -1, -0.8, -2.1, -1, 1, -2.1) data = PackedVector3Array(-1, 1, 0.1, -1, -0.8, 0.1, -1, 1, -0.1, -1, 1, -0.1, -1, -0.8, 0.1, -1, -0.8, -0.1, -1, -1, 0.1, -1, -0.8, -0.1, -1, -0.8, 0.1, -1, -1, -2.3, -1, -0.8, -0.1, -1, -1, 0.1, -1, -0.8, -2.3, -1, -0.8, -0.1, -1, -1, -2.3, -1, -0.8, -2.1, -1, -0.8, -0.1, -1, -0.8, -2.3, -1, -0.8, -2.1, -1, -0.8, -2.3, -1, 1, -2.1, -1, 1, -2.1, -1, -0.8, -2.3, -1, 1, -2.3, -1, 1, -0.1, -1, -0.8, -0.1, 1, 1, -0.1, 1, 1, -0.1, -1, -0.8, -0.1, 1, -0.8, -0.1, 1, 1, -0.1, 1, -0.8, -0.1, 1, 1, 0.1, 1, 1, 0.1, 1, -0.8, -0.1, 1, -0.8, 0.1, 1, -0.8, -0.1, 1, -1, 0.1, 1, -0.8, 0.1, 1, -0.8, -2.1, 1, -1, 0.1, 1, -0.8, -0.1, 1, -0.8, -2.3, 1, -1, 0.1, 1, -0.8, -2.1, 1, -1, -2.3, 1, -1, 0.1, 1, -0.8, -2.3, 1, -0.8, -2.3, 1, -0.8, -2.1, 1, 1, -2.3, 1, 1, -2.3, 1, -0.8, -2.1, 1, 1, -2.1, 1, 1, 0.1, 1, -0.8, 0.1, -1, 1, 0.1, -1, 1, 0.1, 1, -0.8, 0.1, -1, -0.8, 0.1, 1, -0.8, 0.1, 1, -1, 0.1, -1, -0.8, 0.1, -1, -0.8, 0.1, 1, -1, 0.1, -1, -1, 0.1, -1, -1, -2.3, -1, -1, 0.1, 1, -1, -2.3, 1, -1, -2.3, -1, -1, 0.1, 1, -1, 0.1, -1, 1, -0.1, 1, 1, -0.1, -1, 1, 0.1, -1, 1, 0.1, 1, 1, -0.1, 1, 1, 0.1, 1, -0.8, -0.1, -1, -0.8, -0.1, 1, -0.8, -2.1, 1, -0.8, -2.1, -1, -0.8, -0.1, -1, -0.8, -2.1, -1, -0.8, -2.3, -1, -1, -2.3, 1, -0.8, -2.3, 1, -0.8, -2.3, -1, -1, -2.3, 1, -1, -2.3, -1, -0.8, -2.3, 1, -0.8, -2.3, -1, 1, -2.3, -1, 1, -2.3, 1, -0.8, -2.3, 1, 1, -2.3, 1, 1, -2.1, -1, 1, -2.1, 1, 1, -2.3, 1, 1, -2.3, -1, 1, -2.1, -1, 1, -2.3, 1, -0.8, -2.1, -1, -0.8, -2.1, 1, 1, -2.1, 1, 1, -2.1, -1, -0.8, -2.1, -1, 1, -2.1)
@ -95,8 +92,7 @@ skeleton = NodePath("GunkBody")
[node name="GunkBody" parent="Parallel" instance=ExtResource("1_cr8wn")] [node name="GunkBody" parent="Parallel" instance=ExtResource("1_cr8wn")]
mask_dim = 128 mask_dim = 128
initial_mask = ExtResource("2_7477u") source_gunk_material = SubResource("ShaderMaterial_qjnj2")
source_gunk_material = SubResource("ShaderMaterial_lrgpr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Parallel/GunkBody"] [node name="CollisionShape3D" type="CollisionShape3D" parent="Parallel/GunkBody"]
shape = SubResource("ConcavePolygonShape3D_x2vho") shape = SubResource("ConcavePolygonShape3D_x2vho")

View File

@ -16,7 +16,7 @@ warnings/threads/thread_model=2
[application] [application]
config/name="Grunk" config/name="Grunk"
run/main_scene="uid://qpq2cm1hgeha" run/main_scene="uid://884jqafhtrv0"
config/project_settings_override="user://settings.godot" config/project_settings_override="user://settings.godot"
config/features=PackedStringArray("4.4", "Forward Plus") config/features=PackedStringArray("4.4", "Forward Plus")
run/max_fps=60 run/max_fps=60
@ -28,6 +28,7 @@ BeehaveGlobalDebugger="*res://addons/beehave/debug/global_debugger.gd"
GameRuntime="*res://src/game/game_runtime.gd" GameRuntime="*res://src/game/game_runtime.gd"
ItemCatalog="*res://src/items/item_catalog.tscn" ItemCatalog="*res://src/items/item_catalog.tscn"
GameSettings="*res://src/game/game_settings.gd" GameSettings="*res://src/game/game_settings.gd"
GameManager="*res://src/game/game_manager.tscn"
[debug] [debug]
@ -41,6 +42,7 @@ gdscript/warnings/unsafe_call_argument=2
window/size/viewport_width=1920 window/size/viewport_width=1920
window/size/viewport_height=1080 window/size/viewport_height=1080
window/stretch/mode="canvas_items"
[dotnet] [dotnet]
@ -78,8 +80,6 @@ config/accessibility/enable_head_bob=true
config/input/hold_to_sneak=true config/input/hold_to_sneak=true
debug/enable_navigation_agent_debug=false debug/enable_navigation_agent_debug=false
debug/enable_navigation_agent_debug.editor_runtime=true debug/enable_navigation_agent_debug.editor_runtime=true
debug/enable_debug_menu=false
debug/enable_debug_menu.debug=true
[global_group] [global_group]
@ -89,7 +89,6 @@ MeetSpookSource="meet-spook event sources"
LurkPoint="Point which a lurking beast may wander to." LurkPoint="Point which a lurking beast may wander to."
BeastSpawnPoint="Spawn point for a grunkbeast" BeastSpawnPoint="Spawn point for a grunkbeast"
GrunkBeast="GrunkBeast instances." GrunkBeast="GrunkBeast instances."
Persistent="Nodes which implement save and load methods"
[importer_defaults] [importer_defaults]

View File

@ -1,12 +0,0 @@
@tool
extends ColorRect
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
_update_aspect_ratio()
func _update_aspect_ratio() -> void:
var aspect_ratio := size.y / size.x
(material as ShaderMaterial).set_shader_parameter("aspect_ratio", aspect_ratio)

View File

@ -1 +0,0 @@
uid://06n7qs3l4tf6

View File

@ -1,58 +0,0 @@
[gd_scene load_steps=9 format=3 uid="uid://b6dx0ovy15g5o"]
[ext_resource type="Shader" uid="uid://dnytoirugot2e" path="res://src/shaders/canvas_grunk.gdshader" id="1_pgbvb"]
[ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="2_g1nf5"]
[ext_resource type="Script" uid="uid://06n7qs3l4tf6" path="res://src/effects/grunk_2d/grunk_2d.gd" id="3_g1nf5"]
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_7v5ka"]
width = 256
height = 256
seamless = true
seamless_blend_skirt = 0.5
noise = ExtResource("2_g1nf5")
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_d72jk"]
width = 256
height = 256
seamless = true
seamless_blend_skirt = 0.5
noise = ExtResource("2_g1nf5")
[sub_resource type="FastNoiseLite" id="FastNoiseLite_qsvii"]
frequency = 0.0006
fractal_type = 2
fractal_octaves = 4
fractal_gain = 0.667
domain_warp_type = 2
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_pgbvb"]
width = 1024
height = 1024
noise = SubResource("FastNoiseLite_qsvii")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_rq45f"]
resource_local_to_scene = true
shader = ExtResource("1_pgbvb")
shader_parameter/color_1 = Color(0, 0.03, 0.1, 1)
shader_parameter/color_2 = Color(0, 0.1, 0.3, 1)
shader_parameter/emission_color = Color(0.25, 0.88, 1, 1)
shader_parameter/pixellation = 30.0
shader_parameter/time_pixellation = 30.0
shader_parameter/emission_strength = 0.05
shader_parameter/aspect_ratio = 0.5625
shader_parameter/time_scale = 0.01
shader_parameter/gunk_noise = SubResource("NoiseTexture3D_7v5ka")
shader_parameter/gunk_normal_map = SubResource("NoiseTexture3D_d72jk")
shader_parameter/mask_progress = 1.0
shader_parameter/mask_noise = SubResource("NoiseTexture2D_pgbvb")
[node name="Grunk2D" type="ColorRect"]
material = SubResource("ShaderMaterial_rq45f")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("3_g1nf5")
[connection signal="item_rect_changed" from="." to="." method="_update_aspect_ratio"]

View File

@ -18,7 +18,7 @@ func _spray() -> void:
func _fire() -> void: func _fire() -> void:
rumbler.intensity = RUMBLE_INTENSITY rumbler.intensity = RUMBLE_INTENSITY
if World.instance.manager.is_tank_full(): if Game.manager.is_tank_full():
Player.instance.hud.play_tank_full_alert() Player.instance.hud.play_tank_full_alert()
idle() idle()
return return

View File

@ -16,11 +16,11 @@ const BRUSH_SCALE := 0.2
func unlocked() -> bool: func unlocked() -> bool:
return World.instance.manager.toothbrush_unlocked return Game.manager.toothbrush_unlocked
func _fire() -> void: func _fire() -> void:
if raycast.is_colliding() and not World.instance.manager.is_tank_full(): if raycast.is_colliding() and not Game.manager.is_tank_full():
brush_animation.play("brush") brush_animation.play("brush")
var collider := raycast.get_collider() var collider := raycast.get_collider()
if collider is GunkBody: if collider is GunkBody:

View File

@ -1,14 +1,13 @@
class_name Game extends Node class_name Game extends Node
## Interface to the game as an application. ## Interface to the game as an application.
@export_file("*.tscn") var start_scene: String @export_category("Game Scenes")
@export var world_scene: PackedScene
var _loading_resources: Dictionary[String, Promise] = {}
@onready var content: Node = %Content
@onready var loading_screen: Control = %LoadingScreen
## Handy typed singleton access. ## Handy typed singleton access.
static var manager: GameManagerType:
get():
return GameManager
static var settings: GameSettingsType: static var settings: GameSettingsType:
get(): get():
return GameSettings return GameSettings
@ -20,92 +19,5 @@ static var runtime: GameRuntimeType:
static var instance: Game static var instance: Game
class Promise:
var _callbacks: Array[Callable] = []
var _end_callbacks: Array[Callable] = []
func then(fn: Callable) -> Promise:
_callbacks.push_back(fn)
return self
func finally(fn: Callable) -> Promise:
_end_callbacks.push_back(fn)
return self
func resolve(res: Variant) -> void:
for fn: Callable in _callbacks + _end_callbacks:
fn.call(res)
class ScenePromise:
extends Promise
func resolve(res: Variant) -> void:
@warning_ignore("unsafe_cast")
var instance: Node = (res as PackedScene).instantiate()
super.resolve(instance)
func _ready() -> void: func _ready() -> void:
Game.instance = self Game.instance = self
_initial_load.call_deferred()
func _initial_load() -> void:
queue_scene(start_scene)
## Unload the running scene & queue up a new scene to be loaded in the background.
##
## The loading screen will be shown until the scene is loaded.
func queue_scene(path: String) -> Promise:
_unload_content()
return queue_load(path, ScenePromise.new(), "PackedScene").finally(_finish_scene_load)
## Queue a resource to be loaded in the background.
##
## Returns a `Promise` which can be used to attach callbacks
## which will be called with the resource after it is loaded.
func queue_load(path: String, promise: Promise = null, type_hint: String = "") -> Promise:
if not promise:
promise = Promise.new()
_loading_resources[path] = promise
ResourceLoader.load_threaded_request(path, type_hint)
return promise
func _unload_content() -> void:
for child: Node in content.get_children():
child.queue_free()
func _finish_scene_load(scene_instance: Node) -> void:
# Unpause in case the previous scene was paused.
get_tree().paused = false
# Reset time scale in case it's been changed.
Engine.time_scale = 1.0
content.add_child(scene_instance)
scene_instance.reparent(content)
func _process(_delta: float) -> void:
if _loading_resources:
loading_screen.visible = true
for key: String in _loading_resources.keys():
match ResourceLoader.load_threaded_get_status(key):
ResourceLoader.THREAD_LOAD_LOADED:
_loading_resources[key].resolve(ResourceLoader.load_threaded_get(key))
_loading_resources.erase(key)
ResourceLoader.THREAD_LOAD_FAILED:
assert(false, "Failed loading resource: " + key)
ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
assert(false, "Can't load invalid resource: " + key)
_:
# Continue loading
pass
if not _loading_resources:
loading_screen.visible = false

View File

@ -1,236 +1,8 @@
[gd_scene load_steps=14 format=3 uid="uid://qpq2cm1hgeha"] [gd_scene load_steps=3 format=3 uid="uid://qpq2cm1hgeha"]
[ext_resource type="Script" uid="uid://dxl25lkyped4" path="res://src/game/game.gd" id="1_qnjlk"] [ext_resource type="Script" uid="uid://dxl25lkyped4" path="res://src/game/game.gd" id="1_qnjlk"]
[ext_resource type="FontFile" uid="uid://oq8ue2qrfijg" path="res://assets/fonts/Silkscreen/Silkscreen-Regular.ttf" id="2_s6lek"] [ext_resource type="PackedScene" uid="uid://884jqafhtrv0" path="res://src/world/world.tscn" id="2_s6lek"]
[ext_resource type="Script" uid="uid://ctf1if4ly6nun" path="res://src/game/loading_screen.gd" id="3_kgj8g"]
[sub_resource type="Theme" id="Theme_s6lek"]
Label/colors/font_color = Color(0.137255, 0.984314, 0.34902, 1)
Label/constants/outline_size = 16
Label/font_sizes/font_size = 32
Label/fonts/font = ExtResource("2_s6lek")
[sub_resource type="Animation" id="Animation_kgj8g"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("MarginContainer/HBoxContainer/Loading:visible_ratio")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("MarginContainer/HBoxContainer/Ellipsis:visible_characters")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MarginContainer/HBoxContainer/Blinker:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_l80un"]
resource_name = "ellipsis_loop"
length = 1.2
loop_mode = 1
step = 0.05
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("MarginContainer/HBoxContainer/Loading:visible_ratio")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [1.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("MarginContainer/HBoxContainer/Blinker:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MarginContainer/HBoxContainer/Ellipsis:visible_characters")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.3, 0.6, 0.9),
"transitions": PackedFloat32Array(1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3]
}
[sub_resource type="Animation" id="Animation_s6lek"]
resource_name = "initial_display"
step = 0.05
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("MarginContainer/HBoxContainer/Loading:visible_ratio")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.8, 1),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.0, 0.0, 1.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("MarginContainer/HBoxContainer/Ellipsis:visible_characters")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MarginContainer/HBoxContainer/Blinker:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [false, true, false, true, false, true, false, true, false]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_kgj8g"]
_data = {
&"RESET": SubResource("Animation_kgj8g"),
&"ellipsis_loop": SubResource("Animation_l80un"),
&"initial_display": SubResource("Animation_s6lek")
}
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_s6lek"]
animation = &"ellipsis_loop"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_kgj8g"]
animation = &"initial_display"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_l80un"]
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_xptat"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_l80un"]
states/ellipsis_loop/node = SubResource("AnimationNodeAnimation_s6lek")
states/ellipsis_loop/position = Vector2(630, 100)
states/initial_display/node = SubResource("AnimationNodeAnimation_kgj8g")
states/initial_display/position = Vector2(399, 100)
transitions = ["Start", "initial_display", SubResource("AnimationNodeStateMachineTransition_l80un"), "initial_display", "ellipsis_loop", SubResource("AnimationNodeStateMachineTransition_xptat")]
[node name="Game" type="Node"] [node name="Game" type="Node"]
script = ExtResource("1_qnjlk") script = ExtResource("1_qnjlk")
start_scene = "uid://bctwol681jdk0" world_scene = ExtResource("2_s6lek")
[node name="Content" type="Node" parent="."]
unique_name_in_owner = true
[node name="LoadingScreen" type="Control" parent="."]
unique_name_in_owner = true
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = SubResource("Theme_s6lek")
script = ExtResource("3_kgj8g")
[node name="ColorRect" type="ColorRect" parent="LoadingScreen"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.0196078, 0.0431373, 0.0627451, 1)
[node name="MarginContainer" type="MarginContainer" parent="LoadingScreen"]
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_top = -40.0
offset_right = 40.0
grow_vertical = 0
theme_override_constants/margin_left = 32
theme_override_constants/margin_bottom = 32
[node name="HBoxContainer" type="HBoxContainer" parent="LoadingScreen/MarginContainer"]
layout_mode = 2
[node name="Prompt" type="Label" parent="LoadingScreen/MarginContainer/HBoxContainer"]
layout_mode = 2
text = ">"
[node name="Blinker" type="Label" parent="LoadingScreen/MarginContainer/HBoxContainer"]
visible = false
layout_mode = 2
text = "_"
[node name="Loading" type="Label" parent="LoadingScreen/MarginContainer/HBoxContainer"]
layout_mode = 2
text = "UI_LOADING"
visible_characters = 0
visible_characters_behavior = 1
visible_ratio = 0.0
[node name="Ellipsis" type="Label" parent="LoadingScreen/MarginContainer/HBoxContainer"]
layout_mode = 2
text = "..."
visible_characters = 0
visible_characters_behavior = 1
visible_ratio = 0.0
[node name="LoaderAnimation" type="AnimationPlayer" parent="LoadingScreen"]
libraries = {
&"": SubResource("AnimationLibrary_kgj8g")
}
[node name="LoaderTree" type="AnimationTree" parent="LoadingScreen/LoaderAnimation"]
unique_name_in_owner = true
root_node = NodePath("%LoaderTree/../..")
tree_root = SubResource("AnimationNodeStateMachine_l80un")
anim_player = NodePath("..")
[connection signal="visibility_changed" from="LoadingScreen" to="LoadingScreen" method="_on_visibility_changed"]

View File

@ -1,5 +1,5 @@
class_name WorldManager extends Resource class_name GameManagerType extends Node
## Autoloaded singleton encapsulating game world state. ## Autoloaded singleton encapsulating game state.
# TODO a lot of this should really be a property of the world. # TODO a lot of this should really be a property of the world.
@ -59,10 +59,6 @@ var grunk_vault := 0.0
var alert_level := 0 var alert_level := 0
func _init() -> void:
milestone_reached.connect(_on_milestone)
## Add to the player's grunk tank. ## Add to the player's grunk tank.
func collect_grunk(delta: float) -> void: func collect_grunk(delta: float) -> void:
grunk_tank += delta grunk_tank += delta
@ -87,8 +83,6 @@ func deposit_tank() -> void:
if alert_level >= CLEAR_LEVEL: if alert_level >= CLEAR_LEVEL:
clear_alert() clear_alert()
World.instance.save_progress()
func is_tank_full() -> bool: func is_tank_full() -> bool:
return grunk_tank >= grunk_tank_limit return grunk_tank >= grunk_tank_limit

View File

@ -1,10 +1,10 @@
[gd_resource type="Resource" script_class="WorldManager" load_steps=13 format=3 uid="uid://tgac5tnfx56r"] [gd_scene load_steps=13 format=3 uid="uid://cnrtgmanw40ei"]
[ext_resource type="Script" uid="uid://c1i5gnht15x0e" path="res://src/world/world_manager.gd" id="1_i77rl"] [ext_resource type="Script" uid="uid://c1i5gnht15x0e" path="res://src/game/game_manager.gd" id="1_08e4a"]
[ext_resource type="Script" uid="uid://ufxoxupdvyd5" path="res://src/game/milestone.gd" id="2_c37ff"] [ext_resource type="Script" uid="uid://ufxoxupdvyd5" path="res://src/game/milestone.gd" id="2_b83gw"]
[sub_resource type="Resource" id="Resource_h4r54"] [sub_resource type="Resource" id="Resource_h4r54"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "[no reward]" name = "[no reward]"
message = "Check the MANUAL for SWEET TIPZ message = "Check the MANUAL for SWEET TIPZ
from the GRUNKIN' MASTERS!" from the GRUNKIN' MASTERS!"
@ -20,7 +20,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_b83gw"] [sub_resource type="Resource" id="Resource_b83gw"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "MP3 PLAYER" name = "MP3 PLAYER"
message = "MP3 PLAYER DECRYPTED. Enjoy some message = "MP3 PLAYER DECRYPTED. Enjoy some
light music whilst you GRUNK." light music whilst you GRUNK."
@ -36,7 +36,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_o6um0"] [sub_resource type="Resource" id="Resource_o6um0"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "TOOTHBRUSH" name = "TOOTHBRUSH"
message = "TOOTHBRUSH DECRYPTED. message = "TOOTHBRUSH DECRYPTED.
Enjoy teethbrushing in moderation!" Enjoy teethbrushing in moderation!"
@ -52,7 +52,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_vebb4"] [sub_resource type="Resource" id="Resource_vebb4"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "BONUS TRACK" name = "BONUS TRACK"
message = "BONUS TRACK DELIVERED message = "BONUS TRACK DELIVERED
[TODO]" [TODO]"
@ -68,7 +68,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_aolyc"] [sub_resource type="Resource" id="Resource_aolyc"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "WELLNESS SEMINAR" name = "WELLNESS SEMINAR"
message = "SEMINAR DECRYPTED. message = "SEMINAR DECRYPTED.
The FUTURE of WELLNESS is TODAY!" The FUTURE of WELLNESS is TODAY!"
@ -84,7 +84,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_36cpv"] [sub_resource type="Resource" id="Resource_36cpv"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "EL TANK GRANDE" name = "EL TANK GRANDE"
message = "\"EL TANK GRANDE\" DECRYPTED. message = "\"EL TANK GRANDE\" DECRYPTED.
GRUNK carrying capacity increased." GRUNK carrying capacity increased."
@ -100,7 +100,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_pfnwj"] [sub_resource type="Resource" id="Resource_pfnwj"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "STICKER PACK" name = "STICKER PACK"
message = "NOW PRINTING... You can use message = "NOW PRINTING... You can use
STICKERS to EXPRESS your \"SELF\"" STICKERS to EXPRESS your \"SELF\""
@ -116,7 +116,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_p7jc6"] [sub_resource type="Resource" id="Resource_p7jc6"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "QUOTA" name = "QUOTA"
message = "QUOTA SATISFIED. message = "QUOTA SATISFIED.
FINE WORK GRUNKER !" FINE WORK GRUNKER !"
@ -132,7 +132,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_2eyq5"] [sub_resource type="Resource" id="Resource_2eyq5"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "???" name = "???"
message = "????? ?" message = "????? ?"
bonus_track = false bonus_track = false
@ -147,7 +147,7 @@ fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_2qxxw"] [sub_resource type="Resource" id="Resource_2qxxw"]
script = ExtResource("2_c37ff") script = ExtResource("2_b83gw")
name = "taco fiesta" name = "taco fiesta"
message = "ENJOY THE FIESTA GRUNKER !" message = "ENJOY THE FIESTA GRUNKER !"
bonus_track = false bonus_track = false
@ -161,11 +161,9 @@ mystery = false
fiesta = true fiesta = true
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[resource] [node name="GameManager" type="Node"]
script = ExtResource("1_i77rl") script = ExtResource("1_08e4a")
grunk_tank_limit = 96000 vault_milestones = Dictionary[int, ExtResource("2_b83gw")]({
grunk_quota = 2000000
vault_milestones = Dictionary[int, ExtResource("2_c37ff")]({
0: SubResource("Resource_h4r54"), 0: SubResource("Resource_h4r54"),
100000: SubResource("Resource_b83gw"), 100000: SubResource("Resource_b83gw"),
200000: SubResource("Resource_o6um0"), 200000: SubResource("Resource_o6um0"),
@ -182,7 +180,5 @@ vault_milestones = Dictionary[int, ExtResource("2_c37ff")]({
4200000: SubResource("Resource_vebb4"), 4200000: SubResource("Resource_vebb4"),
6400000: SubResource("Resource_2qxxw") 6400000: SubResource("Resource_2qxxw")
}) })
mp3_player_unlocked = false
toothbrush_unlocked = false [connection signal="milestone_reached" from="." to="." method="_on_milestone"]
stickers_unlocked = false
metadata/_custom_type_script = "uid://c1i5gnht15x0e"

View File

@ -15,8 +15,6 @@ var hold_to_sneak: bool
var enable_screen_shake: bool var enable_screen_shake: bool
var enable_head_bob: bool var enable_head_bob: bool
var enable_debug_menu: bool
func _init() -> void: func _init() -> void:
ProjectSettings.settings_changed.connect(_read_settings) ProjectSettings.settings_changed.connect(_read_settings)
@ -41,8 +39,6 @@ func _read_settings() -> void:
) )
enable_head_bob = ProjectSettings.get_setting("game/config/accessibility/enable_head_bob") enable_head_bob = ProjectSettings.get_setting("game/config/accessibility/enable_head_bob")
enable_debug_menu = ProjectSettings.get_setting_with_override("game/debug/enable_debug_menu")
func _load_audio_bus_override() -> void: func _load_audio_bus_override() -> void:
# Load override audio bus file # Load override audio bus file

View File

@ -1,14 +0,0 @@
class_name Level extends Node3D
## A level with associated metadata
const SAVE_PATH_FMT := "user://{0}.state.res"
## Internal ID string
@export var id: String
## Human-readable name
@export var pretty_name: String
func get_save_path() -> String:
return SAVE_PATH_FMT.format([id])

View File

@ -1 +0,0 @@
uid://68r4ht5ut1ct

View File

@ -1,9 +0,0 @@
extends Control
@onready var loader_tree: AnimationTree = %LoaderTree
@onready var state_machine: AnimationNodeStateMachinePlayback = loader_tree["parameters/playback"]
func _on_visibility_changed() -> void:
if state_machine:
state_machine.start("initial_display", true)

View File

@ -1 +0,0 @@
uid://ctf1if4ly6nun

View File

@ -4,12 +4,14 @@ const PITCH_LIMIT := deg_to_rad(85.0)
const FOCUS_SENSITIVITY := 0.2 const FOCUS_SENSITIVITY := 0.2
const FOCUS_ACCELERATION := 8 const FOCUS_ACCELERATION := 8
@onready var player: Player = owner
@onready var _target := Vector2(rotation.x, rotation.y) @onready var _target := Vector2(rotation.x, rotation.y)
func _unhandled_input(event: InputEvent) -> void: func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion: if event is InputEventMouseMotion:
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED and Player.instance.look_enabled: if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED and player.look_enabled:
camera_motion((event as InputEventMouseMotion).relative) camera_motion((event as InputEventMouseMotion).relative)
elif event is InputEventMouseButton: elif event is InputEventMouseButton:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
@ -19,7 +21,7 @@ func camera_motion(motion: Vector2) -> void:
var x_sensitivity: float = Game.settings.mouse_sensitivity_x var x_sensitivity: float = Game.settings.mouse_sensitivity_x
var y_sensitivity: float = Game.settings.mouse_sensitivity_y var y_sensitivity: float = Game.settings.mouse_sensitivity_y
var invert_pitch: bool = Game.settings.invert_pitch var invert_pitch: bool = Game.settings.invert_pitch
if Player.instance.firing: if player.firing:
# Focus movement when firing # Focus movement when firing
# Game mechanic, should not be user-configurable. # Game mechanic, should not be user-configurable.
x_sensitivity = FOCUS_SENSITIVITY x_sensitivity = FOCUS_SENSITIVITY
@ -40,7 +42,7 @@ func reset_pitch(tween_duration: float) -> void:
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
var mouse_accel: float = Game.settings.mouse_acceleration var mouse_accel: float = Game.settings.mouse_acceleration
if Player.instance.firing: if player.firing:
mouse_accel = FOCUS_ACCELERATION mouse_accel = FOCUS_ACCELERATION
var weight := 1 - exp(-mouse_accel * delta) var weight := 1 - exp(-mouse_accel * delta)

View File

@ -6,6 +6,7 @@ const VELOCITY_FACTOR := 2.0
var _on_right_foot := false var _on_right_foot := false
@onready var player: Player = owner
@onready var left_foot: FootController = %LeftFoot @onready var left_foot: FootController = %LeftFoot
@onready var right_foot: FootController = %RightFoot @onready var right_foot: FootController = %RightFoot
@ -15,12 +16,12 @@ var _on_right_foot := false
func play_footstep() -> void: func play_footstep() -> void:
if Player.instance.sneaking: if player.sneaking:
return return
var foot := right_foot if _on_right_foot else left_foot var foot := right_foot if _on_right_foot else left_foot
var relative_speed := Player.instance.velocity.length() - MUTE_VELOCITY var relative_speed := player.velocity.length() - MUTE_VELOCITY
if relative_speed < 0: if relative_speed < 0:
return return

View File

@ -16,11 +16,13 @@ var timescale: float:
get: get:
return self["parameters/timescale/scale"] return self["parameters/timescale/scale"]
@onready var player: Player = owner
func _process(delta: float) -> void: func _process(delta: float) -> void:
var speed := Player.instance.velocity.length() var speed := player.velocity.length()
var weight := 1 - exp(-BLEND_ACCELERATION * delta) var weight := 1 - exp(-BLEND_ACCELERATION * delta)
if Player.instance.is_on_floor(): if player.is_on_floor():
var timescale_target := speed * VELOCITY_TIMESCALE_FACTOR var timescale_target := speed * VELOCITY_TIMESCALE_FACTOR
timescale = lerpf(timescale, timescale_target, weight) timescale = lerpf(timescale, timescale_target, weight)
else: else:
@ -28,7 +30,7 @@ func _process(delta: float) -> void:
if Game.settings.enable_head_bob: if Game.settings.enable_head_bob:
var blend_target := 0.0 var blend_target := 0.0
if Player.instance.is_on_floor(): if player.is_on_floor():
blend_target = speed * VELOCITY_BLEND_FACTOR blend_target = speed * VELOCITY_BLEND_FACTOR
blend = lerpf(blend, blend_target, weight) blend = lerpf(blend, blend_target, weight)

View File

@ -2,9 +2,6 @@ class_name Player extends CharacterBody3D
#region Exported Properties #region Exported Properties
@export_category("HAX!!")
@export var godmode := false
@export_category("Status") @export_category("Status")
@export var dead := false @export var dead := false
@export var movement_enabled := true @export var movement_enabled := true
@ -78,7 +75,7 @@ static var instance: Player
func _ready() -> void: func _ready() -> void:
World.instance.manager.milestone_reached.connect(_on_milestone) Game.manager.milestone_reached.connect(_on_milestone)
instance = self instance = self
@ -148,7 +145,7 @@ func toggle_crouch() -> void:
## Get fuckign grabbed, idiot! ## Get fuckign grabbed, idiot!
## Begin grab death sequence animation. ## Begin grab death sequence animation.
func get_grabbed() -> void: func get_grabbed() -> void:
if dead or godmode: # No double-grabsies if dead: # No double-grabsies
return return
movement_enabled = false movement_enabled = false
@ -177,7 +174,7 @@ func _on_milestone(milestone: Milestone) -> void:
func _signal_death() -> void: func _signal_death() -> void:
# Called from the death animation # Called from the death animation
World.instance.manager.on_player_death() Game.manager.on_player_death()
#endregion #endregion
@ -261,18 +258,4 @@ func _physics_process(delta: float) -> void:
move_and_slide() move_and_slide()
#endregion
#region Persistence
func serialize() -> Dictionary:
return {
"inventory": inventory,
}
func deserialize(state: Dictionary) -> void:
@warning_ignore("unsafe_cast")
inventory.assign(state["inventory"] as Dictionary)
#endregion #endregion

View File

@ -592,7 +592,7 @@ _data = {
[sub_resource type="PlaneMesh" id="PlaneMesh_p6grl"] [sub_resource type="PlaneMesh" id="PlaneMesh_p6grl"]
[node name="Player" type="CharacterBody3D" groups=["Persistent"]] [node name="Player" type="CharacterBody3D"]
collision_layer = 8 collision_layer = 8
collision_mask = 33 collision_mask = 33
script = ExtResource("1_npueo") script = ExtResource("1_npueo")

View File

@ -1,8 +1,5 @@
extends Node3D extends Node3D
@export var start_open := false
@export_category("Editor Tools")
@export var debug_open: bool: @export var debug_open: bool:
set(value): set(value):
open() open()
@ -18,32 +15,6 @@ extends Node3D
@onready var nav_link: NavigationLink3D = %NavLink @onready var nav_link: NavigationLink3D = %NavLink
func _ready() -> void:
_deferred_init.call_deferred()
func _deferred_init() -> void:
if start_open:
_instant_open()
func _instant_open() -> void:
nav_link.enabled = true
animation.play("open")
animation.advance(100)
func _instant_close() -> void:
nav_link.enabled = false
animation.play("open")
animation.advance(0)
animation.stop()
func is_open() -> bool:
return nav_link.enabled
func open() -> void: func open() -> void:
nav_link.enabled = true nav_link.enabled = true
animation.play("open") animation.play("open")
@ -56,11 +27,3 @@ func close() -> void:
# TODO bespoke close anim? # TODO bespoke close anim?
animation.play_backwards("open") animation.play_backwards("open")
nav_link.enabled = false nav_link.enabled = false
func serialize() -> Dictionary:
return {"open": is_open()}
func deserialize(state: Dictionary) -> void:
start_open = state["open"]

View File

@ -281,7 +281,7 @@ _data = {
&"spray": SubResource("Animation_88qrs") &"spray": SubResource("Animation_88qrs")
} }
[node name="Bulkhead" groups=["Persistent"] instance=ExtResource("1_77udb")] [node name="Bulkhead" instance=ExtResource("1_77udb")]
script = ExtResource("2_hknvo") script = ExtResource("2_hknvo")
[node name="Frame" parent="." index="0"] [node name="Frame" parent="." index="0"]

View File

@ -2,15 +2,6 @@ extends Node3D
@export var threshold := 100.0 @export var threshold := 100.0
@onready var spot_light_3d: SpotLight3D = %SpotLight3D @onready var spot_light_3d: SpotLight3D = %SpotLight3D
@onready var gunk_body: GunkBody = %GunkBody
func _ready() -> void:
_deferred_init.call_deferred()
func _deferred_init() -> void:
gunk_body.trigger_recompute()
func _on_clear_total_updated(clear_total: float) -> void: func _on_clear_total_updated(clear_total: float) -> void:

View File

@ -116,7 +116,6 @@ libraries = {
autoplay = "flicker" autoplay = "flicker"
[node name="GunkBody" parent="MeshInstance3D" instance=ExtResource("6_3gl0p")] [node name="GunkBody" parent="MeshInstance3D" instance=ExtResource("6_3gl0p")]
unique_name_in_owner = true
mask_dim = 32 mask_dim = 32
source_gunk_material = ExtResource("8_3gl0p") source_gunk_material = ExtResource("8_3gl0p")

View File

@ -8,10 +8,6 @@ signal activated
func _ready() -> void: func _ready() -> void:
_deferred_init.call_deferred()
func _deferred_init() -> void:
if enabled: if enabled:
enable() enable()
else: else:
@ -44,11 +40,3 @@ func _activate() -> void:
func _on_interactive_selected() -> void: func _on_interactive_selected() -> void:
if enabled: if enabled:
interactive.enabled = _has_item() interactive.enabled = _has_item()
func serialize() -> Dictionary:
return {"enabled": enabled}
func deserialize(state: Dictionary) -> void:
enabled = state["enabled"]

View File

@ -9,7 +9,7 @@ size = Vector3(0.475, 0.65, 0.2)
[sub_resource type="BoxShape3D" id="BoxShape3D_5bfyo"] [sub_resource type="BoxShape3D" id="BoxShape3D_5bfyo"]
size = Vector3(0.475, 0.65, 0.2) size = Vector3(0.475, 0.65, 0.2)
[node name="RetinalScanner" type="Node3D" groups=["Persistent"]] [node name="RetinalScanner" type="Node3D"]
script = ExtResource("1_c71b5") script = ExtResource("1_c71b5")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."] [node name="MeshInstance3D" type="MeshInstance3D" parent="."]

View File

@ -22,10 +22,6 @@ const CLEAN_THRESHOLD := 1400
func _ready() -> void: func _ready() -> void:
interactive.label = label interactive.label = label
_deferred_init.call_deferred()
func _deferred_init() -> void:
if clean: if clean:
gunk_body.clear_all() gunk_body.clear_all()
_on_clean() _on_clean()
@ -89,15 +85,3 @@ func _on_gunk_body_clear_total_updated(clear_total: float) -> void:
func _on_action_delay_timeout() -> void: func _on_action_delay_timeout() -> void:
activated.emit() activated.emit()
func serialize() -> Dictionary:
return {
"clean": clean,
"enabled": enabled,
}
func deserialize(state: Dictionary) -> void:
clean = state["clean"]
enabled = state["enabled"]

View File

@ -189,7 +189,7 @@ size = Vector3(0.475, 0.65, 0.2)
[sub_resource type="SphereShape3D" id="SphereShape3D_mxsyy"] [sub_resource type="SphereShape3D" id="SphereShape3D_mxsyy"]
radius = 3.0 radius = 3.0
[node name="WallSwitch" groups=["Persistent"] instance=ExtResource("2_whafo")] [node name="WallSwitch" instance=ExtResource("2_whafo")]
script = ExtResource("2_kfvqd") script = ExtResource("2_kfvqd")
enabled = true enabled = true
label = "INTERACTIVE_SWITCH_LABEL" label = "INTERACTIVE_SWITCH_LABEL"

View File

@ -11,7 +11,8 @@ uniform float time_pixellation = 30.0;
uniform float emission_strength = 0.05; uniform float emission_strength = 0.05;
uniform float aspect_ratio = 1.0; // Used ONLY by the gunk, does not affect the gunk mask.
uniform vec2 uv_scale = vec2(1.0);
uniform float time_scale = 1.0; uniform float time_scale = 1.0;
@ -28,8 +29,9 @@ float hardstep(float value) {
} }
void fragment() { void fragment() {
vec2 scaled_pixellation = pixellation * vec2(1.0, aspect_ratio); vec2 aspect_ratio = vec2(SCREEN_PIXEL_SIZE.y / SCREEN_PIXEL_SIZE.x, 1.0);
vec2 local_uv = floor(UV * scaled_pixellation) / scaled_pixellation; vec2 scaled_pixellation = pixellation * aspect_ratio;
vec2 local_uv = floor(UV * uv_scale * scaled_pixellation) / scaled_pixellation;
float local_time = floor(TIME * time_scale * time_pixellation) / time_pixellation; float local_time = floor(TIME * time_scale * time_pixellation) / time_pixellation;
// swirl // swirl

View File

@ -1,76 +0,0 @@
[gd_scene load_steps=12 format=3 uid="uid://brknr57xc2cp0"]
[ext_resource type="Texture2D" uid="uid://b7ds08rj0yk7j" path="res://assets/ui/corpo_logo/corpo_logo_128_bg.png" id="1_1oh6t"]
[ext_resource type="Texture2D" uid="uid://dixpjnlaj86x2" path="res://assets/ui/corpo_logo/corpo_logo_128.png" id="1_p2l3a"]
[ext_resource type="Shader" uid="uid://dnytoirugot2e" path="res://src/shaders/canvas_grunk.gdshader" id="2_q367f"]
[ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="3_8o5hc"]
[ext_resource type="PackedScene" uid="uid://b6dx0ovy15g5o" path="res://src/effects/grunk_2d/grunk_2d.tscn" id="5_xrtbx"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_8o5hc"]
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_7v5ka"]
width = 256
height = 256
seamless = true
seamless_blend_skirt = 0.5
noise = ExtResource("3_8o5hc")
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_d72jk"]
width = 256
height = 256
seamless = true
seamless_blend_skirt = 0.5
noise = ExtResource("3_8o5hc")
[sub_resource type="FastNoiseLite" id="FastNoiseLite_qsvii"]
frequency = 0.0006
fractal_type = 2
fractal_octaves = 4
fractal_gain = 0.667
domain_warp_type = 2
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_pgbvb"]
width = 1024
height = 1024
noise = SubResource("FastNoiseLite_qsvii")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_t8g1i"]
resource_local_to_scene = true
shader = ExtResource("2_q367f")
shader_parameter/color_1 = Color(0, 0, 0, 1)
shader_parameter/color_2 = Color(0.137255, 0.984314, 0.34902, 1)
shader_parameter/emission_color = Color(0.486275, 1, 0.25098, 1)
shader_parameter/pixellation = 32.0
shader_parameter/time_pixellation = 60.0
shader_parameter/emission_strength = 0.05
shader_parameter/aspect_ratio = 1.0
shader_parameter/time_scale = 1.0
shader_parameter/gunk_noise = SubResource("NoiseTexture3D_7v5ka")
shader_parameter/gunk_normal_map = SubResource("NoiseTexture3D_d72jk")
shader_parameter/mask_progress = 1.0
shader_parameter/mask_noise = SubResource("NoiseTexture2D_pgbvb")
[node name="SaveIcon" type="MarginContainer"]
offset_right = 40.0
offset_bottom = 40.0
[node name="IconBG" type="TextureRect" parent="."]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
texture = ExtResource("1_1oh6t")
stretch_mode = 2
[node name="SaveIcon" type="TextureRect" parent="."]
clip_children = 2
texture_filter = 3
material = SubResource("ShaderMaterial_8o5hc")
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
texture = ExtResource("1_p2l3a")
stretch_mode = 2
[node name="Grunk2D" parent="SaveIcon" instance=ExtResource("5_xrtbx")]
material = SubResource("ShaderMaterial_t8g1i")
layout_mode = 1

View File

@ -10,15 +10,15 @@ const TANK_WARNING_BUFFER_PCT := 0.1
func _ready() -> void: func _ready() -> void:
World.instance.manager.grunk_collected.connect(on_grunk_collected) Game.manager.grunk_collected.connect(on_grunk_collected)
World.instance.manager.grunk_emptied.connect(on_grunk_emptied) Game.manager.grunk_emptied.connect(on_grunk_emptied)
counter.pivot_offset = Vector2(0, counter.size.y) counter.pivot_offset = Vector2(0, counter.size.y)
func on_grunk_collected(delta: float) -> void: func on_grunk_collected(delta: float) -> void:
counter.text = str(int(clampf(World.instance.manager.grunk_tank, 0.0, World.instance.manager.grunk_tank_limit))) counter.text = str(int(clampf(Game.manager.grunk_tank, 0.0, Game.manager.grunk_tank_limit)))
counter.scale = Vector2.ONE + Vector2.ONE * clampf(delta / 128.0, 0.1, 1.0) counter.scale = Vector2.ONE + Vector2.ONE * clampf(delta / 128.0, 0.1, 1.0)
var buffer := remap(World.instance.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1) var buffer := remap(Game.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1)
counter.modulate = Color.WHITE.lerp(Color.RED, clampf(buffer, 0, 1)) counter.modulate = Color.WHITE.lerp(Color.RED, clampf(buffer, 0, 1))

View File

@ -23,22 +23,22 @@ var _base_rumble := 0.0
func _ready() -> void: func _ready() -> void:
World.instance.manager.grunk_collected.connect(on_grunk_collected) Game.manager.grunk_collected.connect(on_grunk_collected)
World.instance.manager.grunk_emptied.connect(on_grunk_emptied) Game.manager.grunk_emptied.connect(on_grunk_emptied)
func get_target_rotation() -> float: func get_target_rotation() -> float:
return remap( return remap(
World.instance.manager.grunk_tank, Game.manager.grunk_tank,
0, 0,
World.instance.manager.grunk_tank_limit, Game.manager.grunk_tank_limit,
NEEDLE_ANGLE_MIN, NEEDLE_ANGLE_MIN,
NEEDLE_ANGLE_MAX NEEDLE_ANGLE_MAX
) )
func on_grunk_collected(_delta: float) -> void: func on_grunk_collected(_delta: float) -> void:
var buffer := remap(World.instance.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1) var buffer := remap(Game.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1)
_base_rumble = BUFFER_RUMBLE_FACTOR * buffer _base_rumble = BUFFER_RUMBLE_FACTOR * buffer

View File

@ -6,8 +6,8 @@ class_name PlayerHUD extends Control
func _ready() -> void: func _ready() -> void:
World.instance.manager.alert_raised.connect(_on_raise_alert) Game.manager.alert_raised.connect(_on_raise_alert)
World.instance.manager.alert_cleared.connect(_on_clear_alert) Game.manager.alert_cleared.connect(_on_clear_alert)
func select_interactive(prop: Interactive) -> void: func select_interactive(prop: Interactive) -> void:

View File

@ -344,10 +344,10 @@ anchor_left = 0.5
anchor_top = 0.5 anchor_top = 0.5
anchor_right = 0.5 anchor_right = 0.5
anchor_bottom = 0.5 anchor_bottom = 0.5
offset_left = -399.906 offset_left = -401.486
offset_top = -299.03 offset_top = -302.289
offset_right = -399.906 offset_right = -401.486
offset_bottom = -299.03 offset_bottom = -302.289
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("4_ud8na") script = ExtResource("4_ud8na")

View File

@ -1,31 +0,0 @@
extends PanelContainer
@onready var god_mode: CheckButton = %GodMode
@onready var collect_grunk_input: SpinBox = %CollectGrunkInput
func _ready() -> void:
# Initialize controls
if Player.instance:
god_mode.set_pressed_no_signal(Player.instance.godmode)
func kill_player() -> void:
Player.instance.get_grabbed()
func save_game() -> void:
World.instance.save_progress()
func load_game() -> void:
World.instance.on_game_over()
func collect_grunk() -> void:
World.instance.manager.collect_grunk(collect_grunk_input.value)
collect_grunk_input.value = 0.0
func empty_tank() -> void:
World.instance.manager.empty_tank()

View File

@ -1 +0,0 @@
uid://cekwr6enxknpn

View File

@ -1,97 +0,0 @@
[gd_scene load_steps=4 format=3 uid="uid://dofr2ebmvnwxf"]
[ext_resource type="Theme" uid="uid://doq7ay6f7dgfo" path="res://src/ui/menus/menu.theme" id="1_spfxq"]
[ext_resource type="Script" uid="uid://cekwr6enxknpn" path="res://src/ui/menus/debug_menu/debug_menu.gd" id="2_p20ux"]
[ext_resource type="FontFile" uid="uid://qadtckvw0t3l" path="res://assets/fonts/fontawesome-free-6.7.2-desktop/otfs/Font Awesome 6 Free-Solid-900.otf" id="3_rw5h6"]
[node name="DebugMenu" type="PanelContainer"]
custom_minimum_size = Vector2(1000, 600)
theme = ExtResource("1_spfxq")
script = ExtResource("2_p20ux")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 16
theme_override_constants/margin_top = 16
theme_override_constants/margin_right = 16
theme_override_constants/margin_bottom = 16
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="Header" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="Heading" type="Label" parent="MarginContainer/VBoxContainer/Header"]
layout_mode = 2
size_flags_horizontal = 3
theme_type_variation = &"HeaderLarge"
text = "DEBUG MENU"
[node name="CloseButton" type="Button" parent="MarginContainer/VBoxContainer/Header"]
layout_mode = 2
theme_override_fonts/font = ExtResource("3_rw5h6")
theme_override_font_sizes/font_size = 50
text = ""
flat = true
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/margin_right = 12
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
alignment = 2
[node name="GodMode" type="CheckButton" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "God mode"
alignment = 2
[node name="KillPlayer" type="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "Kill player"
[node name="SaveButton" type="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "Save game"
[node name="LoadButton" type="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "Load game"
[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
alignment = 2
[node name="CollectGrunkInput" type="SpinBox" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
max_value = 6.4e+07
alignment = 2
suffix = "g"
[node name="CollectGrunkButton" type="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer2"]
layout_mode = 2
text = "Collect grunk"
[node name="EmptyTankButton" type="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer2"]
layout_mode = 2
text = "Empty tank"
[connection signal="pressed" from="MarginContainer/VBoxContainer/Header/CloseButton" to="." method="queue_free"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer/KillPlayer" to="." method="kill_player"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer/SaveButton" to="." method="save_game"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer/LoadButton" to="." method="load_game"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer2/CollectGrunkButton" to="." method="collect_grunk"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer2/EmptyTankButton" to="." method="empty_tank"]

View File

@ -1,19 +1,18 @@
[gd_scene load_steps=14 format=3 uid="uid://c0uitm5cg88h1"] [gd_scene load_steps=13 format=3 uid="uid://c0uitm5cg88h1"]
[ext_resource type="Shader" uid="uid://dnytoirugot2e" path="res://src/shaders/canvas_grunk.gdshader" id="1_28vyc"] [ext_resource type="Shader" uid="uid://dnytoirugot2e" path="res://src/shaders/canvas_grunk.gdshader" id="1_28vyc"]
[ext_resource type="PackedScene" uid="uid://b6dx0ovy15g5o" path="res://src/effects/grunk_2d/grunk_2d.tscn" id="1_sv5d8"]
[ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="2_qsvii"] [ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="2_qsvii"]
[ext_resource type="Theme" uid="uid://b07fevr214mmr" path="res://src/ui/hud/hud_theme.tres" id="3_a6m17"] [ext_resource type="Theme" uid="uid://b07fevr214mmr" path="res://src/ui/hud/hud_theme.tres" id="3_a6m17"]
[ext_resource type="Script" uid="uid://cjs2fen6jo0g0" path="res://src/ui/rumbler.gd" id="4_sv5d8"] [ext_resource type="Script" uid="uid://cjs2fen6jo0g0" path="res://src/ui/rumbler.gd" id="4_sv5d8"]
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_7v5ka"] [sub_resource type="NoiseTexture3D" id="NoiseTexture3D_et0xc"]
width = 256 width = 256
height = 256 height = 256
seamless = true seamless = true
seamless_blend_skirt = 0.5 seamless_blend_skirt = 0.5
noise = ExtResource("2_qsvii") noise = ExtResource("2_qsvii")
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_d72jk"] [sub_resource type="NoiseTexture3D" id="NoiseTexture3D_a6m17"]
width = 256 width = 256
height = 256 height = 256
seamless = true seamless = true
@ -27,13 +26,12 @@ fractal_octaves = 4
fractal_gain = 0.667 fractal_gain = 0.667
domain_warp_type = 2 domain_warp_type = 2
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_pgbvb"] [sub_resource type="NoiseTexture2D" id="NoiseTexture2D_et0xc"]
width = 1024 width = 1024
height = 1024 height = 1024
noise = SubResource("FastNoiseLite_qsvii") noise = SubResource("FastNoiseLite_qsvii")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_3jt4s"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_qsvii"]
resource_local_to_scene = true
shader = ExtResource("1_28vyc") shader = ExtResource("1_28vyc")
shader_parameter/color_1 = Color(0, 0.03, 0.1, 1) shader_parameter/color_1 = Color(0, 0.03, 0.1, 1)
shader_parameter/color_2 = Color(0, 0.1, 0.3, 1) shader_parameter/color_2 = Color(0, 0.1, 0.3, 1)
@ -41,51 +39,12 @@ shader_parameter/emission_color = Color(0.25, 0.88, 1, 1)
shader_parameter/pixellation = 50.0 shader_parameter/pixellation = 50.0
shader_parameter/time_pixellation = 30.0 shader_parameter/time_pixellation = 30.0
shader_parameter/emission_strength = 0.0 shader_parameter/emission_strength = 0.0
shader_parameter/aspect_ratio = 0.5625 shader_parameter/uv_scale = Vector2(1, 1)
shader_parameter/time_scale = 0.2 shader_parameter/time_scale = 0.2
shader_parameter/gunk_noise = SubResource("NoiseTexture3D_7v5ka") shader_parameter/gunk_noise = SubResource("NoiseTexture3D_et0xc")
shader_parameter/gunk_normal_map = SubResource("NoiseTexture3D_d72jk") shader_parameter/gunk_normal_map = SubResource("NoiseTexture3D_a6m17")
shader_parameter/mask_progress = 0.0 shader_parameter/mask_progress = 0.0
shader_parameter/mask_noise = SubResource("NoiseTexture2D_pgbvb") shader_parameter/mask_noise = SubResource("NoiseTexture2D_et0xc")
[sub_resource type="Animation" id="Animation_et0xc"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Grunk2D:material:shader_parameter/mask_progress")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Grunk2D/Rumbler:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Blackout:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_qsvii"] [sub_resource type="Animation" id="Animation_qsvii"]
resource_name = "transition_in" resource_name = "transition_in"
@ -93,7 +52,7 @@ length = 14.0
tracks/0/type = "value" tracks/0/type = "value"
tracks/0/imported = false tracks/0/imported = false
tracks/0/enabled = true tracks/0/enabled = true
tracks/0/path = NodePath("Grunk2D:material:shader_parameter/mask_progress") tracks/0/path = NodePath("Grunk:material:shader_parameter/mask_progress")
tracks/0/interp = 2 tracks/0/interp = 2
tracks/0/loop_wrap = false tracks/0/loop_wrap = false
tracks/0/keys = { tracks/0/keys = {
@ -105,7 +64,7 @@ tracks/0/keys = {
tracks/1/type = "value" tracks/1/type = "value"
tracks/1/imported = false tracks/1/imported = false
tracks/1/enabled = true tracks/1/enabled = true
tracks/1/path = NodePath("Grunk2D/Rumbler:visible") tracks/1/path = NodePath("Grunk/Rumbler:visible")
tracks/1/interp = 1 tracks/1/interp = 1
tracks/1/loop_wrap = true tracks/1/loop_wrap = true
tracks/1/keys = { tracks/1/keys = {
@ -141,6 +100,45 @@ tracks/3/keys = {
}] }]
} }
[sub_resource type="Animation" id="Animation_et0xc"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Grunk:material:shader_parameter/mask_progress")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Grunk/Rumbler:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Blackout:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_a6m17"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_a6m17"]
_data = { _data = {
&"RESET": SubResource("Animation_et0xc"), &"RESET": SubResource("Animation_et0xc"),
@ -155,20 +153,27 @@ anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
[node name="Grunk2D" parent="." instance=ExtResource("1_sv5d8")] [node name="Grunk" type="ColorRect" parent="."]
material = SubResource("ShaderMaterial_3jt4s") clip_children = 2
material = SubResource("ShaderMaterial_qsvii")
layout_mode = 1 layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="Rumbler" type="Control" parent="Grunk2D"] [node name="Rumbler" type="Control" parent="Grunk"]
visible = false visible = false
layout_mode = 1 layout_mode = 1
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
offset_left = -7.49218 offset_left = 3.04544
offset_top = -3.99316 offset_top = -0.292352
offset_right = -7.49219 offset_right = 3.04541
offset_bottom = -3.99316 offset_bottom = -0.292358
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2 mouse_filter = 2
@ -176,7 +181,7 @@ script = ExtResource("4_sv5d8")
intensity = 6.0 intensity = 6.0
metadata/_custom_type_script = "uid://cjs2fen6jo0g0" metadata/_custom_type_script = "uid://cjs2fen6jo0g0"
[node name="DeathMessage" type="Label" parent="Grunk2D/Rumbler"] [node name="DeathMessage" type="Label" parent="Grunk/Rumbler"]
layout_mode = 1 layout_mode = 1
anchors_preset = 8 anchors_preset = 8
anchor_left = 0.5 anchor_left = 0.5

View File

@ -1,10 +1,7 @@
extends Control extends Control
## Menu shown in-game when the user presses pause. ## Menu shown in-game when the user presses pause.
@export_category("Game Scenes")
@export_file("*.tscn") var title_scene: String
@export var settings_scene: PackedScene @export var settings_scene: PackedScene
@export var debug_scene: PackedScene
var _freeze_input := false var _freeze_input := false
@ -13,15 +10,10 @@ var _freeze_input := false
@onready var end_game_confirm: Control = %EndGameConfirm @onready var end_game_confirm: Control = %EndGameConfirm
@onready var settings_container: Container = %SettingsContainer @onready var settings_container: Container = %SettingsContainer
@onready var debug_button: Button = %DebugButton
@onready var debug_container: MarginContainer = %DebugContainer
func _ready() -> void: func _ready() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
Engine.time_scale = 1.0 Engine.time_scale = 1.0
if Game.settings.enable_debug_menu:
debug_button.show()
func _unhandled_key_input(event: InputEvent) -> void: func _unhandled_key_input(event: InputEvent) -> void:
@ -71,12 +63,5 @@ func cancel_end_game() -> void:
func confirm_end_game() -> void: func confirm_end_game() -> void:
# TODO transition print_debug("TODO")
Game.instance.queue_scene(title_scene) #world.fade_to_title()
func debug_menu() -> void:
var instance: Control = debug_scene.instantiate()
debug_container.add_child(instance)
instance.tree_exited.connect(_unhide)
_hide()

View File

@ -1,9 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://byvjsvavbg5xe"] [gd_scene load_steps=4 format=3 uid="uid://byvjsvavbg5xe"]
[ext_resource type="Theme" uid="uid://doq7ay6f7dgfo" path="res://src/ui/menus/menu.theme" id="1_b4t8b"] [ext_resource type="Theme" uid="uid://doq7ay6f7dgfo" path="res://src/ui/menus/menu.theme" id="1_b4t8b"]
[ext_resource type="Script" uid="uid://cllx5glqld8wn" path="res://src/ui/menus/pause_menu/pause_menu.gd" id="1_rd0j2"] [ext_resource type="Script" uid="uid://cllx5glqld8wn" path="res://src/ui/menus/pause_menu/pause_menu.gd" id="1_rd0j2"]
[ext_resource type="PackedScene" uid="uid://d3eaqw2rdurct" path="res://src/ui/menus/settings_menu/settings_menu.tscn" id="3_dowgp"] [ext_resource type="PackedScene" uid="uid://d3eaqw2rdurct" path="res://src/ui/menus/settings_menu/settings_menu.tscn" id="3_dowgp"]
[ext_resource type="PackedScene" uid="uid://dofr2ebmvnwxf" path="res://src/ui/menus/debug_menu/debug_menu.tscn" id="4_1bm4j"]
[node name="PauseMenu" type="Control"] [node name="PauseMenu" type="Control"]
process_mode = 3 process_mode = 3
@ -15,9 +14,7 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
theme = ExtResource("1_b4t8b") theme = ExtResource("1_b4t8b")
script = ExtResource("1_rd0j2") script = ExtResource("1_rd0j2")
title_scene = "uid://bctwol681jdk0"
settings_scene = ExtResource("3_dowgp") settings_scene = ExtResource("3_dowgp")
debug_scene = ExtResource("4_1bm4j")
[node name="Shade" type="ColorRect" parent="."] [node name="Shade" type="ColorRect" parent="."]
layout_mode = 1 layout_mode = 1
@ -88,13 +85,6 @@ layout_mode = 2
theme_type_variation = &"DangerButton" theme_type_variation = &"DangerButton"
text = "PAUSE_QUIT" text = "PAUSE_QUIT"
[node name="DebugButton" type="Button" parent="MenuList/VBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
theme_override_colors/font_color = Color(0.14, 1, 0.355, 1)
text = "PAUSE_DEBUG"
[node name="SettingsContainer" type="MarginContainer" parent="."] [node name="SettingsContainer" type="MarginContainer" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(1000, 600) custom_minimum_size = Vector2(1000, 600)
@ -112,23 +102,6 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2 mouse_filter = 2
[node name="DebugContainer" type="MarginContainer" parent="."]
unique_name_in_owner = true
custom_minimum_size = Vector2(1000, 600)
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -485.0
offset_top = -300.0
offset_right = 515.0
offset_bottom = 300.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="QuitConfirm" type="CenterContainer" parent="."] [node name="QuitConfirm" type="CenterContainer" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false
@ -223,7 +196,6 @@ text = "UI_QUIT"
[connection signal="pressed" from="MenuList/VBoxContainer/SettingsButton" to="." method="settings"] [connection signal="pressed" from="MenuList/VBoxContainer/SettingsButton" to="." method="settings"]
[connection signal="pressed" from="MenuList/VBoxContainer/EndGameButton" to="." method="end_game"] [connection signal="pressed" from="MenuList/VBoxContainer/EndGameButton" to="." method="end_game"]
[connection signal="pressed" from="MenuList/VBoxContainer/QuitButton" to="." method="quit"] [connection signal="pressed" from="MenuList/VBoxContainer/QuitButton" to="." method="quit"]
[connection signal="pressed" from="MenuList/VBoxContainer/DebugButton" to="." method="debug_menu"]
[connection signal="pressed" from="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/CancelButton" to="." method="cancel_quit"] [connection signal="pressed" from="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/CancelButton" to="." method="cancel_quit"]
[connection signal="pressed" from="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ConfirmQuitButton" to="." method="confirm_quit"] [connection signal="pressed" from="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ConfirmQuitButton" to="." method="confirm_quit"]
[connection signal="pressed" from="EndGameConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/CancelButton" to="." method="cancel_end_game"] [connection signal="pressed" from="EndGameConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/CancelButton" to="." method="cancel_end_game"]

View File

@ -1,46 +0,0 @@
extends Control
## Title screen!
# TODO is there a way to get this path without loading the level scene?
@export var save_path: String
@export_category("Game Scenes")
# TODO is there a way to get the appropriate level scene path here without loading the world scene?
@export_file("*.tscn") var level_scene: String
@export_file("*.tscn") var world_scene: String
@export var settings_scene: PackedScene
@onready var continue_button: Button = %Continue
@onready var settings_container: Control = %SettingsContainer
@onready var title_sfx: AudioStreamPlayer = %TitleSFX
@onready var title_drone: AudioStreamPlayer = %TitleDrone
func _ready() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
if FileAccess.file_exists(save_path):
continue_button.disabled = false
func continue_game() -> void:
LoadingTools.load_save(save_path)
func new_game() -> void:
LoadingTools.load_level(level_scene)
func show_settings() -> void:
var instance: Control = settings_scene.instantiate()
settings_container.add_child(instance)
func quit() -> void:
get_tree().root.propagate_notification(NOTIFICATION_WM_CLOSE_REQUEST)
func _exit_tree() -> void:
title_sfx.stop()
title_drone.stop()

View File

@ -1 +0,0 @@
uid://dysldhadfr4oj

View File

@ -1,833 +0,0 @@
[gd_scene load_steps=20 format=3 uid="uid://bctwol681jdk0"]
[ext_resource type="Theme" uid="uid://dj2ij1b2yjicr" path="res://src/ui/menus/title_screen/title_screen.theme" id="1_3lcvc"]
[ext_resource type="PackedScene" uid="uid://b6dx0ovy15g5o" path="res://src/effects/grunk_2d/grunk_2d.tscn" id="2_7vchy"]
[ext_resource type="Script" uid="uid://dysldhadfr4oj" path="res://src/ui/menus/title_screen/title_screen.gd" id="2_rjwhj"]
[ext_resource type="Texture2D" uid="uid://buc0oy5col0et" path="res://assets/ui/title.png" id="2_uxv0r"]
[ext_resource type="PackedScene" uid="uid://d3eaqw2rdurct" path="res://src/ui/menus/settings_menu/settings_menu.tscn" id="3_wqn52"]
[ext_resource type="Shader" uid="uid://dnytoirugot2e" path="res://src/shaders/canvas_grunk.gdshader" id="3_yrys0"]
[ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="4_cgiy0"]
[ext_resource type="Texture2D" uid="uid://dixpjnlaj86x2" path="res://assets/ui/corpo_logo/corpo_logo_128.png" id="5_yrys0"]
[ext_resource type="FontFile" uid="uid://bgy7odoob7xyl" path="res://assets/fonts/Silkscreen/Silkscreen-Bold.ttf" id="6_cgiy0"]
[ext_resource type="AudioStream" uid="uid://c838ofbu4bqrn" path="res://assets/sfx/computer_noise.wav" id="10_x67pi"]
[ext_resource type="AudioStream" uid="uid://dx4d8a3mgpws" path="res://assets/sfx/ambient/drone_loop.wav" id="11_gdkv4"]
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_7v5ka"]
width = 256
height = 256
seamless = true
seamless_blend_skirt = 0.5
noise = ExtResource("4_cgiy0")
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_d72jk"]
width = 256
height = 256
seamless = true
seamless_blend_skirt = 0.5
noise = ExtResource("4_cgiy0")
[sub_resource type="FastNoiseLite" id="FastNoiseLite_qsvii"]
frequency = 0.0006
fractal_type = 2
fractal_octaves = 4
fractal_gain = 0.667
domain_warp_type = 2
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_pgbvb"]
width = 1024
height = 1024
noise = SubResource("FastNoiseLite_qsvii")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_rjwhj"]
resource_local_to_scene = true
shader = ExtResource("3_yrys0")
shader_parameter/color_1 = Color(0, 0.03, 0.1, 1)
shader_parameter/color_2 = Color(0, 0.1, 0.3, 1)
shader_parameter/emission_color = Color(0.25, 0.88, 1, 1)
shader_parameter/pixellation = 30.0
shader_parameter/time_pixellation = 30.0
shader_parameter/emission_strength = 0.0
shader_parameter/aspect_ratio = 0.5625
shader_parameter/time_scale = 0.4
shader_parameter/gunk_noise = SubResource("NoiseTexture3D_7v5ka")
shader_parameter/gunk_normal_map = SubResource("NoiseTexture3D_d72jk")
shader_parameter/mask_progress = 0.0
shader_parameter/mask_noise = SubResource("NoiseTexture2D_pgbvb")
[sub_resource type="Animation" id="Animation_iv5x5"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("VBoxContainer/Loader/Done:visible_ratio")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("VBoxContainer/TitleContainer:custom_minimum_size")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(800, 0)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("VBoxContainer/WarningMessage/LogoContainer:custom_minimum_size")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(128, 0)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1/Warning:visible_ratio")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1/Warning2:visible_ratio")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line2/Warning3:visible_ratio")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/6/type = "value"
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1/Blinker:visible")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/7/type = "value"
tracks/7/imported = false
tracks/7/enabled = true
tracks/7/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line2/Blinker2:visible")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/8/type = "value"
tracks/8/imported = false
tracks/8/enabled = true
tracks/8/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1:visible")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/9/type = "value"
tracks/9/imported = false
tracks/9/enabled = true
tracks/9/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line2:visible")
tracks/9/interp = 1
tracks/9/loop_wrap = true
tracks/9/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/10/type = "value"
tracks/10/imported = false
tracks/10/enabled = true
tracks/10/path = NodePath("VBoxContainer/BufferSpace:custom_minimum_size")
tracks/10/interp = 1
tracks/10/loop_wrap = true
tracks/10/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(1024, 0)]
}
tracks/11/type = "value"
tracks/11/imported = false
tracks/11/enabled = true
tracks/11/path = NodePath("../Grunk2D:material:shader_parameter/mask_progress")
tracks/11/interp = 1
tracks/11/loop_wrap = true
tracks/11/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/12/type = "value"
tracks/12/imported = false
tracks/12/enabled = true
tracks/12/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/Continue:visible")
tracks/12/interp = 1
tracks/12/loop_wrap = true
tracks/12/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/13/type = "value"
tracks/13/imported = false
tracks/13/enabled = true
tracks/13/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/NewGame:visible")
tracks/13/interp = 1
tracks/13/loop_wrap = true
tracks/13/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/14/type = "value"
tracks/14/imported = false
tracks/14/enabled = true
tracks/14/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/Settings:visible")
tracks/14/interp = 1
tracks/14/loop_wrap = true
tracks/14/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/15/type = "value"
tracks/15/imported = false
tracks/15/enabled = true
tracks/15/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/Quit:visible")
tracks/15/interp = 1
tracks/15/loop_wrap = true
tracks/15/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/16/type = "value"
tracks/16/imported = false
tracks/16/enabled = true
tracks/16/path = NodePath("VBoxContainer/MarginContainer:visible")
tracks/16/interp = 1
tracks/16/loop_wrap = true
tracks/16/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/17/type = "value"
tracks/17/imported = false
tracks/17/enabled = true
tracks/17/path = NodePath("VBoxContainer/TitleContainer:visible")
tracks/17/interp = 1
tracks/17/loop_wrap = true
tracks/17/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/18/type = "value"
tracks/18/imported = false
tracks/18/enabled = true
tracks/18/path = NodePath("VBoxContainer/BufferSpace:visible")
tracks/18/interp = 1
tracks/18/loop_wrap = true
tracks/18/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/19/type = "value"
tracks/19/imported = false
tracks/19/enabled = true
tracks/19/path = NodePath("VBoxContainer/WarningMessage:visible")
tracks/19/interp = 1
tracks/19/loop_wrap = true
tracks/19/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/20/type = "value"
tracks/20/imported = false
tracks/20/enabled = true
tracks/20/path = NodePath("TitleDrone:playing")
tracks/20/interp = 1
tracks/20/loop_wrap = true
tracks/20/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/21/type = "value"
tracks/21/imported = false
tracks/21/enabled = true
tracks/21/path = NodePath("TitleDrone:volume_db")
tracks/21/interp = 1
tracks/21/loop_wrap = true
tracks/21/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [-40.0]
}
[sub_resource type="Animation" id="Animation_uxv0r"]
resource_name = "display"
length = 10.0
step = 0.05
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("VBoxContainer/Loader/Done:visible_ratio")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.0, 1.0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("VBoxContainer/TitleContainer:custom_minimum_size")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 6.15, 6.2, 6.25, 6.3, 6.35, 6.4, 6.45, 6.5, 6.55, 6.6, 6.65),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [Vector2(1024, 0), Vector2(1024, 48), Vector2(1024, 96), Vector2(1024, 144), Vector2(1024, 192), Vector2(1024, 240), Vector2(1024, 288), Vector2(1024, 336), Vector2(1024, 384), Vector2(1024, 432), Vector2(1024, 480), Vector2(1024, 528)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("VBoxContainer/WarningMessage/LogoContainer:custom_minimum_size")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 1, 1.1, 1.2, 1.3),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 1,
"values": [Vector2(128, 0), Vector2(128, 32), Vector2(128, 64), Vector2(128, 96), Vector2(128, 128)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1/Warning:visible_ratio")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 1.35, 1.45),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.0, 0.0, 1.0]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1/Warning2:visible_ratio")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 2.35, 2.75),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.0, 0.0, 1.0]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line2/Warning3:visible_ratio")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0, 3.65, 4.15),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.0, 0.0, 1.0]
}
tracks/6/type = "value"
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1/Blinker:visible")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(0, 1.45, 1.6, 1.75139, 1.9, 2.05139, 2.2, 2.35, 2.75, 2.90139, 3.05, 3.20139, 3.35, 3.5, 3.65),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [false, true, false, true, false, true, false, true, false, true, false, true, false, true, false]
}
tracks/7/type = "value"
tracks/7/imported = false
tracks/7/enabled = true
tracks/7/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line2/Blinker2:visible")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
"times": PackedFloat32Array(0, 4.15, 4.3, 4.45139, 4.6, 4.75139, 4.9, 5.05, 5.2, 5.35139, 5.5, 5.65, 5.79861, 5.95, 6.09861),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [false, true, false, true, false, true, false, true, false, true, false, true, false, true, false]
}
tracks/8/type = "value"
tracks/8/imported = false
tracks/8/enabled = true
tracks/8/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line1:visible")
tracks/8/interp = 1
tracks/8/loop_wrap = true
tracks/8/keys = {
"times": PackedFloat32Array(0, 1.3),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/9/type = "value"
tracks/9/imported = false
tracks/9/enabled = true
tracks/9/path = NodePath("VBoxContainer/WarningMessage/VBoxContainer/Line2:visible")
tracks/9/interp = 1
tracks/9/loop_wrap = true
tracks/9/keys = {
"times": PackedFloat32Array(0, 3.65),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/10/type = "value"
tracks/10/imported = false
tracks/10/enabled = true
tracks/10/path = NodePath("VBoxContainer/BufferSpace:custom_minimum_size")
tracks/10/interp = 1
tracks/10/loop_wrap = true
tracks/10/keys = {
"times": PackedFloat32Array(0, 7.75, 7.8, 7.85, 7.9, 7.95, 8, 8.05, 8.1, 8.15, 8.2, 8.25, 8.3, 8.35, 8.4, 8.45, 8.5, 8.55, 8.6, 8.65, 8.7, 8.75, 8.8, 8.85),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [Vector2(1024, 0), Vector2(1024, 48), Vector2(1024, 96), Vector2(1024, 144), Vector2(1024, 192), Vector2(1024, 240), Vector2(1024, 288), Vector2(1024, 336), Vector2(1024, 384), Vector2(1024, 432), Vector2(1024, 480), Vector2(1024, 528), Vector2(1024, 576), Vector2(1024, 624), Vector2(1024, 672), Vector2(1024, 720), Vector2(1024, 768), Vector2(1024, 816), Vector2(1024, 864), Vector2(1024, 912), Vector2(1024, 960), Vector2(1024, 1008), Vector2(1024, 1056), Vector2(1024, 1104)]
}
tracks/11/type = "value"
tracks/11/imported = false
tracks/11/enabled = true
tracks/11/path = NodePath("../Grunk2D:material:shader_parameter/mask_progress")
tracks/11/interp = 1
tracks/11/loop_wrap = true
tracks/11/keys = {
"times": PackedFloat32Array(0, 6.15, 10),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.0, 0.0, 1.0]
}
tracks/12/type = "value"
tracks/12/imported = false
tracks/12/enabled = true
tracks/12/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/Continue:visible")
tracks/12/interp = 1
tracks/12/loop_wrap = true
tracks/12/keys = {
"times": PackedFloat32Array(0, 6.75),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/13/type = "value"
tracks/13/imported = false
tracks/13/enabled = true
tracks/13/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/NewGame:visible")
tracks/13/interp = 1
tracks/13/loop_wrap = true
tracks/13/keys = {
"times": PackedFloat32Array(0, 7),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/14/type = "value"
tracks/14/imported = false
tracks/14/enabled = true
tracks/14/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/Settings:visible")
tracks/14/interp = 1
tracks/14/loop_wrap = true
tracks/14/keys = {
"times": PackedFloat32Array(0, 7.25),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/15/type = "value"
tracks/15/imported = false
tracks/15/enabled = true
tracks/15/path = NodePath("VBoxContainer/MarginContainer/MenuButtons/Quit:visible")
tracks/15/interp = 1
tracks/15/loop_wrap = true
tracks/15/keys = {
"times": PackedFloat32Array(0, 7.5),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/16/type = "value"
tracks/16/imported = false
tracks/16/enabled = true
tracks/16/path = NodePath("VBoxContainer/MarginContainer:visible")
tracks/16/interp = 1
tracks/16/loop_wrap = true
tracks/16/keys = {
"times": PackedFloat32Array(0, 6.75),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/17/type = "value"
tracks/17/imported = false
tracks/17/enabled = true
tracks/17/path = NodePath("VBoxContainer/TitleContainer:visible")
tracks/17/interp = 1
tracks/17/loop_wrap = true
tracks/17/keys = {
"times": PackedFloat32Array(0, 6.15),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/18/type = "value"
tracks/18/imported = false
tracks/18/enabled = true
tracks/18/path = NodePath("VBoxContainer/BufferSpace:visible")
tracks/18/interp = 1
tracks/18/loop_wrap = true
tracks/18/keys = {
"times": PackedFloat32Array(0, 7.75),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/19/type = "value"
tracks/19/imported = false
tracks/19/enabled = true
tracks/19/path = NodePath("VBoxContainer/WarningMessage:visible")
tracks/19/interp = 1
tracks/19/loop_wrap = true
tracks/19/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/20/type = "audio"
tracks/20/imported = false
tracks/20/enabled = true
tracks/20/path = NodePath("TitleSFX")
tracks/20/interp = 1
tracks/20/loop_wrap = true
tracks/20/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("10_x67pi")
}],
"times": PackedFloat32Array(0)
}
tracks/20/use_blend = true
tracks/21/type = "value"
tracks/21/imported = false
tracks/21/enabled = true
tracks/21/path = NodePath("TitleDrone:playing")
tracks/21/interp = 1
tracks/21/loop_wrap = true
tracks/21/keys = {
"times": PackedFloat32Array(0, 6.15),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, true]
}
tracks/22/type = "value"
tracks/22/imported = false
tracks/22/enabled = true
tracks/22/path = NodePath("TitleDrone:volume_db")
tracks/22/interp = 1
tracks/22/loop_wrap = true
tracks/22/keys = {
"times": PackedFloat32Array(6.15, 10),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [-40.0, -10.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_3qdtd"]
_data = {
&"RESET": SubResource("Animation_iv5x5"),
&"display": SubResource("Animation_uxv0r")
}
[node name="TitleScreen" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("2_rjwhj")
save_path = "user://ghost_ship.state.res"
level_scene = "uid://bov4ok76woyc"
world_scene = "uid://884jqafhtrv0"
settings_scene = ExtResource("3_wqn52")
[node name="ColorRect" type="ColorRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.0196078, 0.0431373, 0.0627451, 1)
[node name="Grunk2D" parent="." instance=ExtResource("2_7vchy")]
material = SubResource("ShaderMaterial_rjwhj")
layout_mode = 1
[node name="TitleScreenContent" type="MarginContainer" parent="."]
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_top = -73.0
offset_right = 440.0
grow_vertical = 0
theme = ExtResource("1_3lcvc")
theme_override_constants/margin_left = 32
theme_override_constants/margin_bottom = 32
[node name="VBoxContainer" type="VBoxContainer" parent="TitleScreenContent"]
layout_mode = 2
theme_override_constants/separation = 32
[node name="Loader" type="HBoxContainer" parent="TitleScreenContent/VBoxContainer"]
layout_mode = 2
[node name="Prompt" type="Label" parent="TitleScreenContent/VBoxContainer/Loader"]
layout_mode = 2
text = ">"
[node name="Loading" type="Label" parent="TitleScreenContent/VBoxContainer/Loader"]
layout_mode = 2
text = "UI_LOADING"
visible_characters_behavior = 1
[node name="Ellipsis" type="Label" parent="TitleScreenContent/VBoxContainer/Loader"]
layout_mode = 2
text = "... "
visible_characters_behavior = 1
[node name="Done" type="Label" parent="TitleScreenContent/VBoxContainer/Loader"]
layout_mode = 2
text = "Done!"
visible_characters = 0
visible_characters_behavior = 1
visible_ratio = 0.0
[node name="WarningMessage" type="HBoxContainer" parent="TitleScreenContent/VBoxContainer"]
visible = false
layout_mode = 2
theme_override_constants/separation = 32
[node name="LogoContainer" type="Control" parent="TitleScreenContent/VBoxContainer/WarningMessage"]
clip_contents = true
custom_minimum_size = Vector2(128, 0)
layout_mode = 2
size_flags_vertical = 0
[node name="Logo" type="TextureRect" parent="TitleScreenContent/VBoxContainer/WarningMessage/LogoContainer"]
modulate = Color(0.137255, 0.984314, 0.34902, 1)
layout_mode = 1
offset_right = 128.0
offset_bottom = 128.0
texture = ExtResource("5_yrys0")
[node name="VBoxContainer" type="VBoxContainer" parent="TitleScreenContent/VBoxContainer/WarningMessage"]
layout_mode = 2
theme_override_constants/separation = 16
alignment = 2
[node name="Line1" type="HBoxContainer" parent="TitleScreenContent/VBoxContainer/WarningMessage/VBoxContainer"]
visible = false
layout_mode = 2
[node name="Warning" type="Label" parent="TitleScreenContent/VBoxContainer/WarningMessage/VBoxContainer/Line1"]
layout_mode = 2
theme_override_fonts/font = ExtResource("6_cgiy0")
text = "!WARNING!"
visible_characters = 0
visible_ratio = 0.0
[node name="Warning2" type="Label" parent="TitleScreenContent/VBoxContainer/WarningMessage/VBoxContainer/Line1"]
layout_mode = 2
text = " This is a secure terminal system."
visible_characters = 0
visible_ratio = 0.0
[node name="Blinker" type="Label" parent="TitleScreenContent/VBoxContainer/WarningMessage/VBoxContainer/Line1"]
visible = false
layout_mode = 2
text = "_"
[node name="Line2" type="HBoxContainer" parent="TitleScreenContent/VBoxContainer/WarningMessage/VBoxContainer"]
visible = false
layout_mode = 2
[node name="Warning3" type="Label" parent="TitleScreenContent/VBoxContainer/WarningMessage/VBoxContainer/Line2"]
layout_mode = 2
text = "Unauthorized access is prohibited under penalty of"
visible_characters = 0
visible_ratio = 0.0
[node name="Blinker2" type="Label" parent="TitleScreenContent/VBoxContainer/WarningMessage/VBoxContainer/Line2"]
visible = false
layout_mode = 2
text = "_"
[node name="BufferSpace" type="Control" parent="TitleScreenContent/VBoxContainer"]
visible = false
custom_minimum_size = Vector2(1024, 0)
layout_mode = 2
[node name="TitleContainer" type="Control" parent="TitleScreenContent/VBoxContainer"]
visible = false
clip_contents = true
custom_minimum_size = Vector2(800, 0)
layout_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="TitleScreenContent/VBoxContainer/TitleContainer"]
layout_mode = 1
offset_right = 968.0
offset_bottom = 432.0
theme_override_constants/margin_left = 64
[node name="Title" type="TextureRect" parent="TitleScreenContent/VBoxContainer/TitleContainer/MarginContainer"]
modulate = Color(0.137255, 0.984314, 0.34902, 1)
texture_filter = 3
layout_mode = 2
texture = ExtResource("2_uxv0r")
stretch_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="TitleScreenContent/VBoxContainer"]
visible = false
layout_mode = 2
theme_override_constants/margin_left = 64
[node name="MenuButtons" type="VBoxContainer" parent="TitleScreenContent/VBoxContainer/MarginContainer"]
custom_minimum_size = Vector2(300, 0)
layout_mode = 2
size_flags_horizontal = 0
theme_override_constants/separation = 32
[node name="Continue" type="Button" parent="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons"]
unique_name_in_owner = true
visible = false
layout_mode = 2
disabled = true
text = "Continue"
[node name="NewGame" type="Button" parent="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons"]
visible = false
layout_mode = 2
text = "New Game"
[node name="Settings" type="Button" parent="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons"]
visible = false
layout_mode = 2
text = "Settings"
[node name="Quit" type="Button" parent="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons"]
visible = false
layout_mode = 2
theme_type_variation = &"DangerButton"
text = "Quit"
[node name="AnimationPlayer" type="AnimationPlayer" parent="TitleScreenContent"]
libraries = {
&"": SubResource("AnimationLibrary_3qdtd")
}
autoplay = "display"
[node name="TitleSFX" type="AudioStreamPlayer" parent="TitleScreenContent"]
unique_name_in_owner = true
volume_db = -20.0
bus = &"SFX"
[node name="TitleDrone" type="AudioStreamPlayer" parent="TitleScreenContent"]
unique_name_in_owner = true
stream = ExtResource("11_gdkv4")
volume_db = -40.0
bus = &"Music"
[node name="SettingsContainer" type="Control" parent="."]
unique_name_in_owner = true
custom_minimum_size = Vector2(1000, 600)
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -500.0
offset_right = 500.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[connection signal="pressed" from="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons/Continue" to="." method="continue_game"]
[connection signal="pressed" from="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons/NewGame" to="." method="new_game"]
[connection signal="pressed" from="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons/Settings" to="." method="show_settings"]
[connection signal="pressed" from="TitleScreenContent/VBoxContainer/MarginContainer/MenuButtons/Quit" to="." method="quit"]

View File

@ -1,22 +0,0 @@
class_name LoadingTools
## Utilities for loading game states
const WORLD_SCENE := "res://src/world/world.tscn"
static func _load_world(level: PackedScene, save: SaveState = null) -> void:
var finish_load := func(world: World) -> void:
world.save_state = save
world.initial_level = level
Game.instance.queue_scene(WORLD_SCENE).then(finish_load)
static func load_level(level_path: String, save: SaveState = null) -> void:
var chain_load := func(level: PackedScene) -> void: LoadingTools._load_world(level, save)
Game.instance.queue_load(level_path).then(chain_load)
static func load_save(save_path: String) -> void:
var chain_load := func(save: SaveState) -> void: load_level(save.level_path, save)
Game.instance.queue_load(save_path).then(chain_load)

View File

@ -1 +0,0 @@
uid://b1hmb3efjqldu

View File

@ -10,7 +10,7 @@ class_name SetPlayerPriorityTarget extends ActionLeaf
func tick(_actor: Node, blackboard: Blackboard) -> int: func tick(_actor: Node, blackboard: Blackboard) -> int:
if World.instance.manager.alert_level >= alert_threshold and is_instance_valid(Player.instance): if Game.manager.alert_level >= alert_threshold and is_instance_valid(Player.instance):
blackboard.set_value(blackboard_key, Player.instance) blackboard.set_value(blackboard_key, Player.instance)
return SUCCESS return SUCCESS
return FAILURE return FAILURE

View File

@ -61,7 +61,8 @@ func _ready() -> void:
# Overlay mesh with gunk material # Overlay mesh with gunk material
mesh_instance.material_overlay = mat_instance mesh_instance.material_overlay = mat_instance
_deferred_init.call_deferred() if initial_mask:
mask_texture.texture = initial_mask
# Initialize meshtool # Initialize meshtool
meshtool.create_from_surface(mesh_instance.mesh as ArrayMesh, 0) meshtool.create_from_surface(mesh_instance.mesh as ArrayMesh, 0)
@ -70,10 +71,12 @@ func _ready() -> void:
_thread.start(_async_compute_clear_total) _thread.start(_async_compute_clear_total)
func _deferred_init() -> void: func _trigger_recompute_deferred() -> void:
if initial_mask: _mutex.lock()
mask_texture.texture = initial_mask _mask_tx = mask_viewport.get_texture()
mask_texture.visible = true #_mask_img = mask_viewport.get_texture().get_image()
_mutex.unlock()
_semaphore.post()
func _async_compute_clear_total() -> void: func _async_compute_clear_total() -> void:
@ -255,13 +258,13 @@ func _process(_delta: float) -> void:
_mutex.unlock() _mutex.unlock()
var delta := new_total - _prev_clear_total var delta := new_total - _prev_clear_total
if abs(delta) > CLEAR_TOTAL_EPSILON: if abs(delta) > CLEAR_TOTAL_EPSILON:
clear_total_updated.emit(new_total)
# Do not fire signal on first compute after initialization # Do not fire signal on first compute after initialization
# This prevents the player from collecting the grunk from the initial mask. # This prevents the player from collecting the grunk from the initial mask.
if _prev_clear_total >= 0: if _prev_clear_total >= 0:
clear_total_updated.emit(new_total)
# XXX due to fp error, this will drift from the "true count" over time # XXX due to fp error, this will drift from the "true count" over time
# but it probably won't matter :shrug: # but it probably won't matter :shrug:
World.instance.manager.collect_grunk(delta) Game.manager.collect_grunk(delta)
_prev_clear_total = new_total _prev_clear_total = new_total
# If paint_continuous wasn't called last frame, stop the current polyline. # If paint_continuous wasn't called last frame, stop the current polyline.
@ -280,23 +283,6 @@ func _process(_delta: float) -> void:
_multiline_buffer = PackedVector2Array() _multiline_buffer = PackedVector2Array()
func trigger_recompute() -> void:
_mutex.lock()
_mask_tx = mask_viewport.get_texture()
_mutex.unlock()
_semaphore.post()
func _on_mask_painted() -> void: func _on_mask_painted() -> void:
# XXX any problem with posting each frame? # XXX any problem with posting each frame?
trigger_recompute.call_deferred() _trigger_recompute_deferred.call_deferred()
func serialize() -> Dictionary:
var state := {"mask": mask_viewport.get_texture().get_image()}
return state
func deserialize(state: Dictionary) -> void:
@warning_ignore("unsafe_cast")
initial_mask = ImageTexture.create_from_image(state["mask"] as Image)

View File

@ -5,7 +5,7 @@
[ext_resource type="Script" uid="uid://bom5qysgfvap1" path="res://src/world/gunk_body/draw_controller.gd" id="2_kkcjw"] [ext_resource type="Script" uid="uid://bom5qysgfvap1" path="res://src/world/gunk_body/draw_controller.gd" id="2_kkcjw"]
[ext_resource type="Script" uid="uid://ba7480ara8eo" path="res://levels/sandbox/debug_draw.gd" id="3_m8wx4"] [ext_resource type="Script" uid="uid://ba7480ara8eo" path="res://levels/sandbox/debug_draw.gd" id="3_m8wx4"]
[node name="GunkBody" type="StaticBody3D" groups=["Persistent"]] [node name="GunkBody" type="StaticBody3D"]
collision_layer = 5 collision_layer = 5
collision_mask = 0 collision_mask = 0
script = ExtResource("1_qqbpr") script = ExtResource("1_qqbpr")

View File

@ -19,7 +19,7 @@ stream_1/stream = ExtResource("5_omayi")
stream_2/stream = ExtResource("6_yg8lg") stream_2/stream = ExtResource("6_yg8lg")
stream_3/stream = ExtResource("7_4kci5") stream_3/stream = ExtResource("7_4kci5")
[node name="GrunkNodule" type="StaticBody3D" groups=["Persistent"]] [node name="GrunkNodule" type="StaticBody3D"]
collision_layer = 36 collision_layer = 36
collision_mask = 0 collision_mask = 0
script = ExtResource("1_iyr82") script = ExtResource("1_iyr82")

View File

@ -20,10 +20,6 @@ var _sustained_damage := 0.0
var _hit_this_frame := false var _hit_this_frame := false
func _enter_tree() -> void:
add_to_group("Persistent", true)
## Called each frame this node takes a hit. ## Called each frame this node takes a hit.
## ##
## Derived types should override `_hit()` as a lifecycle method. ## Derived types should override `_hit()` as a lifecycle method.
@ -53,7 +49,7 @@ func _process(_delta: float) -> void:
## Destroy this node, with the player collecting the grunk value. ## Destroy this node, with the player collecting the grunk value.
func collect() -> void: func collect() -> void:
World.instance.manager.collect_grunk(value) Game.manager.collect_grunk(value)
destroy() destroy()
@ -61,7 +57,7 @@ func collect() -> void:
## ##
## Derived types should override `_destroy` as a lifecycle method. ## Derived types should override `_destroy` as a lifecycle method.
func destroy() -> void: func destroy() -> void:
World.instance.manager.collect_grunk(value) Game.manager.collect_grunk(value)
var splatter := GrunkSplatter.build(splatter_scale * scale.x) var splatter := GrunkSplatter.build(splatter_scale * scale.x)
add_sibling(splatter) add_sibling(splatter)
splatter.global_position = global_position splatter.global_position = global_position
@ -72,13 +68,3 @@ func destroy() -> void:
func _destroy() -> void: func _destroy() -> void:
pass # Implemented in derived type pass # Implemented in derived type
func serialize() -> Dictionary:
# Nothing to serialize, but we need a placeholder value to show we haven't been destroyed.
return {}
func deserialize(_state: Dictionary) -> void:
# Nothing to deserialize, but we won't be freed!
pass

View File

@ -1,16 +1,16 @@
[gd_scene load_steps=31 format=4 uid="uid://b8rv6dg4tgaeb"] [gd_scene load_steps=31 format=4 uid="uid://b8rv6dg4tgaeb"]
[ext_resource type="Script" uid="uid://bvua1l2hb3an6" path="res://levels/mechanic_test/mechanic_test.gd" id="1_iyuyb"] [ext_resource type="Script" uid="uid://bvua1l2hb3an6" path="res://levels/mechanic_test/mechanic_test.gd" id="1_umjw2"]
[ext_resource type="PackedScene" uid="uid://bwe2jdmvinhqd" path="res://src/player/player.tscn" id="2_qjnj2"] [ext_resource type="PackedScene" uid="uid://bwe2jdmvinhqd" path="res://src/player/player.tscn" id="2_gut8u"]
[ext_resource type="PackedScene" uid="uid://b6eg8t04rkh0c" path="res://src/props/wall_switch/wall_switch.tscn" id="3_awnx0"] [ext_resource type="PackedScene" uid="uid://b6eg8t04rkh0c" path="res://src/props/wall_switch/wall_switch.tscn" id="3_4okgx"]
[ext_resource type="PackedScene" uid="uid://c2omlx4ptrc01" path="res://src/world/gunk_body/gunk_body.tscn" id="4_cgmn0"] [ext_resource type="PackedScene" uid="uid://c2omlx4ptrc01" path="res://src/world/gunk_body/gunk_body.tscn" id="4_7v7un"]
[ext_resource type="Texture2D" uid="uid://8cm835h4gxwe" path="res://assets/debug_mask.png" id="5_aix42"] [ext_resource type="Texture2D" uid="uid://8cm835h4gxwe" path="res://assets/debug_mask.png" id="5_llot1"]
[ext_resource type="Shader" uid="uid://ckxc0ngd37rtk" path="res://src/shaders/gunk.gdshader" id="6_6frcc"] [ext_resource type="Shader" uid="uid://ckxc0ngd37rtk" path="res://src/shaders/gunk.gdshader" id="6_6agnv"]
[ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="7_7cbja"] [ext_resource type="FastNoiseLite" uid="uid://cnlvdtx68giv6" path="res://assets/materials/gunk_noise.tres" id="7_aqwgb"]
[ext_resource type="PackedScene" uid="uid://cubwniraol1qn" path="res://src/props/bulkhead/bulkhead.tscn" id="8_ujrcv"] [ext_resource type="PackedScene" uid="uid://cubwniraol1qn" path="res://src/props/bulkhead/bulkhead.tscn" id="8_ny31q"]
[ext_resource type="PackedScene" uid="uid://b5jubpjj3d277" path="res://levels/mechanic_test/signal_test.tscn" id="9_ix0jw"] [ext_resource type="PackedScene" uid="uid://b5jubpjj3d277" path="res://levels/mechanic_test/signal_test.tscn" id="9_dub8r"]
[ext_resource type="PackedScene" uid="uid://cfqirm2o3uo4k" path="res://levels/mechanic_test/prop_test.tscn" id="10_xrfi2"] [ext_resource type="PackedScene" uid="uid://cfqirm2o3uo4k" path="res://levels/mechanic_test/prop_test.tscn" id="10_ovu60"]
[ext_resource type="PackedScene" uid="uid://dbabcsp38wmid" path="res://levels/mechanic_test/item_test.tscn" id="11_8natv"] [ext_resource type="PackedScene" uid="uid://dbabcsp38wmid" path="res://levels/mechanic_test/item_test.tscn" id="11_crh2u"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_goufh"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_goufh"]
@ -93,7 +93,7 @@ height = 256
depth = 32 depth = 32
seamless = true seamless = true
seamless_blend_skirt = 0.5 seamless_blend_skirt = 0.5
noise = ExtResource("7_7cbja") noise = ExtResource("7_aqwgb")
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_2pd8h"] [sub_resource type="NoiseTexture3D" id="NoiseTexture3D_2pd8h"]
width = 256 width = 256
@ -101,12 +101,12 @@ height = 256
depth = 32 depth = 32
seamless = true seamless = true
seamless_blend_skirt = 0.5 seamless_blend_skirt = 0.5
noise = ExtResource("7_7cbja") noise = ExtResource("7_aqwgb")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_iyuyb"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_umjw2"]
resource_local_to_scene = true resource_local_to_scene = true
render_priority = 0 render_priority = 0
shader = ExtResource("6_6frcc") shader = ExtResource("6_6agnv")
shader_parameter/color_1 = Color(0, 0.03, 0.1, 1) shader_parameter/color_1 = Color(0, 0.03, 0.1, 1)
shader_parameter/color_2 = Color(0, 0.1, 0.3, 1) shader_parameter/color_2 = Color(0, 0.1, 0.3, 1)
shader_parameter/emission_color = Color(0.25, 0.88, 1, 1) shader_parameter/emission_color = Color(0.25, 0.88, 1, 1)
@ -132,11 +132,9 @@ shader_parameter/overlay_emission_scale = 1.0
data = PackedVector3Array(-1.5, 0, -6, -1.5, 0, 6, -1.5, 3, -6, -1.5, 3, -6, -1.5, 0, 6, -1.5, 3, 6, 1.5, 0, 6, 1.5, 0, -6, 1.5, 3, 6, 1.5, 3, 6, 1.5, 0, -6, 1.5, 3, -6, -1.5, 0, 6, -1.5, 0, -6, 1.5, 0, 6, 1.5, 0, 6, -1.5, 0, -6, 1.5, 0, -6, 1.5, 3, 6, 1.5, 3, -6, -1.5, 3, 6, -1.5, 3, 6, 1.5, 3, -6, -1.5, 3, -6) data = PackedVector3Array(-1.5, 0, -6, -1.5, 0, 6, -1.5, 3, -6, -1.5, 3, -6, -1.5, 0, 6, -1.5, 3, 6, 1.5, 0, 6, 1.5, 0, -6, 1.5, 3, 6, 1.5, 3, 6, 1.5, 0, -6, 1.5, 3, -6, -1.5, 0, 6, -1.5, 0, -6, 1.5, 0, 6, 1.5, 0, 6, -1.5, 0, -6, 1.5, 0, -6, 1.5, 3, 6, 1.5, 3, -6, -1.5, 3, 6, -1.5, 3, 6, 1.5, 3, -6, -1.5, 3, -6)
[node name="MechanicTest" type="Node3D"] [node name="MechanicTest" type="Node3D"]
script = ExtResource("1_iyuyb") script = ExtResource("1_umjw2")
id = "mechanic_test"
pretty_name = "Mechanics Test Sandbox"
[node name="Player" parent="." instance=ExtResource("2_qjnj2")] [node name="Player" parent="." instance=ExtResource("2_gut8u")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.65, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.65, 0)
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
@ -163,7 +161,7 @@ mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="ResetPodium"] [node name="CollisionShape3D" type="CollisionShape3D" parent="ResetPodium"]
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="ResetSwitch" parent="ResetPodium" instance=ExtResource("3_awnx0")] [node name="ResetSwitch" parent="ResetPodium" instance=ExtResource("3_4okgx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
clean = true clean = true
@ -180,7 +178,7 @@ mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="NoduleSpawner"] [node name="CollisionShape3D" type="CollisionShape3D" parent="NoduleSpawner"]
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="WallSwitch" parent="NoduleSpawner" instance=ExtResource("3_awnx0")] [node name="WallSwitch" parent="NoduleSpawner" instance=ExtResource("3_4okgx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
clean = true clean = true
@ -202,7 +200,7 @@ mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="AlarmSpawner"] [node name="CollisionShape3D" type="CollisionShape3D" parent="AlarmSpawner"]
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="WallSwitch" parent="AlarmSpawner" instance=ExtResource("3_awnx0")] [node name="WallSwitch" parent="AlarmSpawner" instance=ExtResource("3_4okgx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
clean = true clean = true
@ -224,7 +222,7 @@ mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="AlarmTrigger"] [node name="CollisionShape3D" type="CollisionShape3D" parent="AlarmTrigger"]
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="AlarmTriggerSwitch" parent="AlarmTrigger" instance=ExtResource("3_awnx0")] [node name="AlarmTriggerSwitch" parent="AlarmTrigger" instance=ExtResource("3_4okgx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
clean = true clean = true
@ -237,15 +235,15 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, -31)
mesh = SubResource("ArrayMesh_x2vho") mesh = SubResource("ArrayMesh_x2vho")
skeleton = NodePath("GunkHallBody") skeleton = NodePath("GunkHallBody")
[node name="GunkHallBody" parent="GunkHall" instance=ExtResource("4_cgmn0")] [node name="GunkHallBody" parent="GunkHall" instance=ExtResource("4_7v7un")]
unique_name_in_owner = true unique_name_in_owner = true
initial_mask = ExtResource("5_aix42") initial_mask = ExtResource("5_llot1")
source_gunk_material = SubResource("ShaderMaterial_iyuyb") source_gunk_material = SubResource("ShaderMaterial_umjw2")
[node name="CollisionShape3D" type="CollisionShape3D" parent="GunkHall/GunkHallBody"] [node name="CollisionShape3D" type="CollisionShape3D" parent="GunkHall/GunkHallBody"]
shape = SubResource("ConcavePolygonShape3D_qjnj2") shape = SubResource("ConcavePolygonShape3D_qjnj2")
[node name="Bulkhead" parent="." instance=ExtResource("8_ujrcv")] [node name="Bulkhead" parent="." instance=ExtResource("8_ny31q")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.5, 0, -2) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.5, 0, -2)
[node name="Podium" type="StaticBody3D" parent="Bulkhead"] [node name="Podium" type="StaticBody3D" parent="Bulkhead"]
@ -257,7 +255,7 @@ mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Bulkhead/Podium"] [node name="CollisionShape3D" type="CollisionShape3D" parent="Bulkhead/Podium"]
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="OpenSwitch" parent="Bulkhead/Podium" instance=ExtResource("3_awnx0")] [node name="OpenSwitch" parent="Bulkhead/Podium" instance=ExtResource("3_4okgx")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
clean = true clean = true
@ -275,7 +273,7 @@ mesh = SubResource("BoxMesh_goufh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Bulkhead/Podium2"] [node name="CollisionShape3D" type="CollisionShape3D" parent="Bulkhead/Podium2"]
shape = SubResource("ConcavePolygonShape3D_bg05n") shape = SubResource("ConcavePolygonShape3D_bg05n")
[node name="CloseSwitch" parent="Bulkhead/Podium2" instance=ExtResource("3_awnx0")] [node name="CloseSwitch" parent="Bulkhead/Podium2" instance=ExtResource("3_4okgx")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0.35)
clean = true clean = true
@ -289,19 +287,19 @@ text = "Close"
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 0, -6) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 0, -6)
[node name="SignalTest" parent="SignalTestSpawnPoint" instance=ExtResource("9_ix0jw")] [node name="SignalTest" parent="SignalTestSpawnPoint" instance=ExtResource("9_dub8r")]
[node name="PropTestSpawnPoint" type="Marker3D" parent="."] [node name="PropTestSpawnPoint" type="Marker3D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 0, 4.5) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 0, 4.5)
[node name="PropTest" parent="PropTestSpawnPoint" instance=ExtResource("10_xrfi2")] [node name="PropTest" parent="PropTestSpawnPoint" instance=ExtResource("10_ovu60")]
[node name="ItemTestSpawnPoint" type="Marker3D" parent="."] [node name="ItemTestSpawnPoint" type="Marker3D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13, 0, -2) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13, 0, -2)
[node name="ItemTest" parent="ItemTestSpawnPoint" instance=ExtResource("11_8natv")] [node name="ItemTest" parent="ItemTestSpawnPoint" instance=ExtResource("11_crh2u")]
[connection signal="activated" from="ResetPodium/ResetSwitch" to="." method="reset"] [connection signal="activated" from="ResetPodium/ResetSwitch" to="." method="reset"]
[connection signal="activated" from="NoduleSpawner/WallSwitch" to="." method="spawn_nodule"] [connection signal="activated" from="NoduleSpawner/WallSwitch" to="." method="spawn_nodule"]

View File

@ -24,7 +24,7 @@ var _busy := false
func trigger() -> void: func trigger() -> void:
if not _busy: if not _busy:
_busy = true _busy = true
World.instance.manager.raise_alert(ALERT_DELTA) Game.manager.raise_alert(ALERT_DELTA)
animation_player.play("trigger") animation_player.play("trigger")
trigger_animation.play("trigger") trigger_animation.play("trigger")
alarm_sfx.play() alarm_sfx.play()

View File

@ -243,7 +243,7 @@ _data = {
&"pulse": SubResource("Animation_vokcn") &"pulse": SubResource("Animation_vokcn")
} }
[node name="GunkAlarm" type="StaticBody3D" groups=["Persistent"]] [node name="GunkAlarm" type="StaticBody3D"]
collision_layer = 36 collision_layer = 36
collision_mask = 0 collision_mask = 0
script = ExtResource("1_piaxx") script = ExtResource("1_piaxx")

View File

@ -99,7 +99,7 @@ _data = {
&"pulse": SubResource("Animation_eu6st") &"pulse": SubResource("Animation_eu6st")
} }
[node name="GunkHeart" type="StaticBody3D" groups=["Persistent"]] [node name="GunkHeart" type="StaticBody3D"]
collision_layer = 36 collision_layer = 36
collision_mask = 0 collision_mask = 0
script = ExtResource("1_ftym0") script = ExtResource("1_ftym0")

View File

@ -53,7 +53,7 @@ _data = {
&"trigger": SubResource("Animation_htscg") &"trigger": SubResource("Animation_htscg")
} }
[node name="Listener" type="StaticBody3D" groups=["Persistent"]] [node name="Listener" type="StaticBody3D"]
collision_layer = 36 collision_layer = 36
collision_mask = 0 collision_mask = 0
script = ExtResource("1_htscg") script = ExtResource("1_htscg")

View File

@ -111,7 +111,7 @@ _data = {
&"trigger": SubResource("Animation_rdv5j") &"trigger": SubResource("Animation_rdv5j")
} }
[node name="GunkRelay" type="StaticBody3D" groups=["Persistent"]] [node name="GunkRelay" type="StaticBody3D"]
collision_layer = 36 collision_layer = 36
collision_mask = 0 collision_mask = 0
script = ExtResource("1_rdv5j") script = ExtResource("1_rdv5j")

View File

@ -13,7 +13,7 @@ emission_energy_multiplier = 0.0
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_t1c4j"] [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_t1c4j"]
data = PackedVector3Array(0.7236, -0.4472, 0.5257, 0, -1, 0, -0.2764, -0.4472, 0.8506, 0, -1, 0, 0.7236, -0.4472, 0.5257, 0.7236, -0.4472, -0.5257, -0.2764, -0.4472, 0.8506, 0, -1, 0, -0.8944, -0.4472, 0, -0.8944, -0.4472, 0, 0, -1, 0, -0.2764, -0.4472, -0.8506, -0.2764, -0.4472, -0.8506, 0, -1, 0, 0.7236, -0.4472, -0.5257, 0.7236, -0.4472, -0.5257, 0.7236, -0.4472, 0.5257, 0.8944, 0.4472, 0, 0.7236, -0.4472, 0.5257, -0.2764, -0.4472, 0.8506, 0.2764, 0.4472, 0.8506, -0.2764, -0.4472, 0.8506, -0.8944, -0.4472, 0, -0.7236, 0.4472, 0.5257, -0.8944, -0.4472, 0, -0.2764, -0.4472, -0.8506, -0.7236, 0.4472, -0.5257, -0.2764, -0.4472, -0.8506, 0.7236, -0.4472, -0.5257, 0.2764, 0.4472, -0.8506, 0.8944, 0.4472, 0, 0.7236, -0.4472, 0.5257, 0.2764, 0.4472, 0.8506, 0.2764, 0.4472, 0.8506, -0.2764, -0.4472, 0.8506, -0.7236, 0.4472, 0.5257, -0.7236, 0.4472, 0.5257, -0.8944, -0.4472, 0, -0.7236, 0.4472, -0.5257, -0.7236, 0.4472, -0.5257, -0.2764, -0.4472, -0.8506, 0.2764, 0.4472, -0.8506, 0.2764, 0.4472, -0.8506, 0.7236, -0.4472, -0.5257, 0.8944, 0.4472, 0, 0.8944, 0.4472, 0, 0.2764, 0.4472, 0.8506, 0, 1, 0, 0.2764, 0.4472, 0.8506, -0.7236, 0.4472, 0.5257, 0, 1, 0, -0.7236, 0.4472, 0.5257, -0.7236, 0.4472, -0.5257, 0, 1, 0, -0.7236, 0.4472, -0.5257, 0.2764, 0.4472, -0.8506, 0, 1, 0, 0.2764, 0.4472, -0.8506, 0.8944, 0.4472, 0, 0, 1, 0) data = PackedVector3Array(0.7236, -0.4472, 0.5257, 0, -1, 0, -0.2764, -0.4472, 0.8506, 0, -1, 0, 0.7236, -0.4472, 0.5257, 0.7236, -0.4472, -0.5257, -0.2764, -0.4472, 0.8506, 0, -1, 0, -0.8944, -0.4472, 0, -0.8944, -0.4472, 0, 0, -1, 0, -0.2764, -0.4472, -0.8506, -0.2764, -0.4472, -0.8506, 0, -1, 0, 0.7236, -0.4472, -0.5257, 0.7236, -0.4472, -0.5257, 0.7236, -0.4472, 0.5257, 0.8944, 0.4472, 0, 0.7236, -0.4472, 0.5257, -0.2764, -0.4472, 0.8506, 0.2764, 0.4472, 0.8506, -0.2764, -0.4472, 0.8506, -0.8944, -0.4472, 0, -0.7236, 0.4472, 0.5257, -0.8944, -0.4472, 0, -0.2764, -0.4472, -0.8506, -0.7236, 0.4472, -0.5257, -0.2764, -0.4472, -0.8506, 0.7236, -0.4472, -0.5257, 0.2764, 0.4472, -0.8506, 0.8944, 0.4472, 0, 0.7236, -0.4472, 0.5257, 0.2764, 0.4472, 0.8506, 0.2764, 0.4472, 0.8506, -0.2764, -0.4472, 0.8506, -0.7236, 0.4472, 0.5257, -0.7236, 0.4472, 0.5257, -0.8944, -0.4472, 0, -0.7236, 0.4472, -0.5257, -0.7236, 0.4472, -0.5257, -0.2764, -0.4472, -0.8506, 0.2764, 0.4472, -0.8506, 0.2764, 0.4472, -0.8506, 0.7236, -0.4472, -0.5257, 0.8944, 0.4472, 0, 0.8944, 0.4472, 0, 0.2764, 0.4472, 0.8506, 0, 1, 0, 0.2764, 0.4472, 0.8506, -0.7236, 0.4472, 0.5257, 0, 1, 0, -0.7236, 0.4472, 0.5257, -0.7236, 0.4472, -0.5257, 0, 1, 0, -0.7236, 0.4472, -0.5257, 0.2764, 0.4472, -0.8506, 0, 1, 0, 0.2764, 0.4472, -0.8506, 0.8944, 0.4472, 0, 0, 1, 0)
[node name="GunkTrigger" type="StaticBody3D" groups=["Persistent"]] [node name="GunkTrigger" type="StaticBody3D"]
collision_layer = 36 collision_layer = 36
collision_mask = 0 collision_mask = 0
script = ExtResource("1_t1c4j") script = ExtResource("1_t1c4j")

View File

@ -1,81 +0,0 @@
class_name SaveState extends Resource
## Serializable container for gameplay state.
const CURRENT_VERSION := 0
const PERSISTENT_GROUP := "Persistent"
const SERIALIZE_METHOD := "serialize"
const DESERIALIZE_METHOD := "deserialize"
@export var save_version := CURRENT_VERSION
@export var level_path: String
@export var persistent_state: Dictionary[String, Dictionary] = {}
@export_group("WorldManager State")
@export var grunk_tank_limit: int
@export var mp3_player_unlocked: bool
@export var toothbrush_unlocked: bool
@export var stickers_unlocked: bool
@export var grunk_tank: float
@export var grunk_vault: float
@export var alert_level: int
static func node_key(node: Node, world: World) -> String:
return str(world.level_root.get_path_to(node))
func load_to_world(world: World) -> void:
if level_path != world.current_level_scene.resource_path:
push_warning(
"This save is for ",
level_path,
" but the loaded level is for ",
world.current_level_scene.resource_path
)
world.manager.grunk_tank_limit = grunk_tank_limit
world.manager.mp3_player_unlocked = mp3_player_unlocked
world.manager.toothbrush_unlocked = toothbrush_unlocked
world.manager.stickers_unlocked = stickers_unlocked
world.manager.grunk_tank = grunk_tank
world.manager.grunk_vault = grunk_vault
world.manager.alert_level = alert_level
var persistent := world.get_tree().get_nodes_in_group(PERSISTENT_GROUP)
for node: Node in persistent:
var key := SaveState.node_key(node, world)
if key in persistent_state:
# Node is in our persistent state, so load it with data.
Callable(node, DESERIALIZE_METHOD).call(persistent_state[key])
else:
# Node isn't in our persistent state, so it must have been destroyed.
node.queue_free()
static func serialize(world: World) -> SaveState:
var save := SaveState.new()
save.level_path = world.current_level_scene.resource_path
save.grunk_tank_limit = world.manager.grunk_tank_limit
save.mp3_player_unlocked = world.manager.mp3_player_unlocked
save.toothbrush_unlocked = world.manager.toothbrush_unlocked
save.stickers_unlocked = world.manager.stickers_unlocked
save.grunk_tank = world.manager.grunk_tank
save.grunk_vault = world.manager.grunk_vault
save.alert_level = world.manager.alert_level
# NOTE: I'm assuming that `persistent` will have the same order ever time the world is loaded.
# This may not be the case. If so, we need to find a different way to uniquely identify nodes.
var persistent := world.get_tree().get_nodes_in_group(PERSISTENT_GROUP)
for node: Node in persistent:
var key := SaveState.node_key(node, world)
var data: Dictionary = Callable(node, SERIALIZE_METHOD).call()
save.persistent_state[key] = data
return save

View File

@ -1 +0,0 @@
uid://dsyyk7muaabf5

View File

@ -1,9 +0,0 @@
[gd_resource type="Resource" script_class="SpookManager" load_steps=3 format=3 uid="uid://0i72bf8ip1lx"]
[ext_resource type="PackedScene" uid="uid://ehf5sg3ahvbf" path="res://src/world/grunk_beast/grunk_beast.tscn" id="1_8hd1x"]
[ext_resource type="Script" uid="uid://bsn026pxqwkbc" path="res://src/world/spook_manager/spook_manager.gd" id="2_01euv"]
[resource]
script = ExtResource("2_01euv")
grunkbeast_scene = ExtResource("1_8hd1x")
metadata/_custom_type_script = "uid://bsn026pxqwkbc"

View File

@ -7,7 +7,12 @@ const BEAST_GROUP := "GrunkBeast"
@export var grunkbeast_scene: PackedScene @export var grunkbeast_scene: PackedScene
var debug_set_alert_level: int: var debug_set_alert_level: int:
set = on_alert_raised set = _on_alert_raised
func _init() -> void:
Game.manager.alert_raised.connect(_on_alert_raised)
Game.manager.alert_cleared.connect(_on_alert_cleared)
func _spawn_beast_at_point(spawn_point: Node3D) -> void: func _spawn_beast_at_point(spawn_point: Node3D) -> void:
@ -21,7 +26,7 @@ func spawn_beast() -> void:
var spawn_point := SceneTools.pick_unseen_from_group(SPAWN_GROUP) var spawn_point := SceneTools.pick_unseen_from_group(SPAWN_GROUP)
if not spawn_point: if not spawn_point:
print_debug("Couldn't find a hidden spawn point... Picking one at random.") print_debug("Couldn't find a hidden spawn point... Picking one at random.")
var nodes := World.instance.get_tree().get_nodes_in_group(SPAWN_GROUP) var nodes := Game.manager.get_tree().get_nodes_in_group(SPAWN_GROUP)
if not nodes: if not nodes:
print_debug("Oh that's why. There aren't any spawn points. Complain to a developer.") print_debug("Oh that's why. There aren't any spawn points. Complain to a developer.")
return return
@ -33,14 +38,14 @@ func spawn_beast() -> void:
## Spawn beasts at _every_ spawn point the player can't see. ## Spawn beasts at _every_ spawn point the player can't see.
func spawn_many_beasts() -> void: func spawn_many_beasts() -> void:
var nodes := World.instance.get_tree().get_nodes_in_group(SPAWN_GROUP) var nodes := Game.manager.get_tree().get_nodes_in_group(SPAWN_GROUP)
for node: Node in nodes: for node: Node in nodes:
var target := node as Node3D var target := node as Node3D
if is_instance_valid(target) and not SceneTools.player_can_see(target.global_position): if is_instance_valid(target) and not SceneTools.player_can_see(target.global_position):
_spawn_beast_at_point(target) _spawn_beast_at_point(target)
func on_alert_raised(new_level: int) -> void: func _on_alert_raised(new_level: int) -> void:
match new_level: match new_level:
0: 0:
# LEVEL 0: UNAWARE # LEVEL 0: UNAWARE
@ -51,11 +56,8 @@ func on_alert_raised(new_level: int) -> void:
# Set up meet-spook. # Set up meet-spook.
# Get closest MeetSpook point to player. # Get closest MeetSpook point to player.
if Player.instance: if Player.instance:
var closest := ( var closest := SceneTools.closest_in_group(Player.instance, MeetSpook.GROUP)
SceneTools.closest_in_group(Player.instance, MeetSpook.GROUP) as MeetSpook (closest as MeetSpook).prepare()
)
if closest:
closest.prepare()
2: 2:
# LEVEL 2: AGGRESSIVE # LEVEL 2: AGGRESSIVE
# Beast pursues player on sight. # Beast pursues player on sight.
@ -75,16 +77,16 @@ func on_alert_raised(new_level: int) -> void:
pass # TODO pass # TODO
func on_alert_cleared() -> void: func _on_alert_cleared() -> void:
# Destroy all grunk beasts # Destroy all but one grunk beasts
for b: Node in World.instance.get_tree().get_nodes_in_group(BEAST_GROUP): var beasts := Game.manager.get_tree().get_nodes_in_group(BEAST_GROUP)
b.queue_free() if not beasts:
return
# And spawn one back in, if needed @warning_ignore("unsafe_cast")
if World.instance.manager.alert_level >= 2: var survivor := beasts.pick_random() as GrunkBeast
spawn_beast() for beast: Node in beasts:
if beast != survivor:
beast.queue_free()
survivor.clear_aggro()
## Set the state of spooky effects after a level is initialized & any save state is loaded.
func after_level_init() -> void:
on_alert_cleared()

View File

@ -3,9 +3,6 @@ class_name World extends Node
@export var pause_enabled := true @export var pause_enabled := true
@export var save_state: SaveState
@export var manager: WorldManager
@export var spook_manager: SpookManager @export var spook_manager: SpookManager
@export_category("Game Scenes") @export_category("Game Scenes")
@ -15,22 +12,17 @@ class_name World extends Node
@export var kill_screen_scene: PackedScene @export var kill_screen_scene: PackedScene
var current_level_scene: PackedScene var current_level: PackedScene
var current_level: Level
@onready var level_root: Node3D = %LevelRoot @onready var level_root: Node3D = %LevelRoot
@onready var ui_root: Control = %UIRoot @onready var ui_root: Control = %UIRoot
@onready var save_icon: MarginContainer = %SaveIcon
static var instance: World static var instance: World
func _ready() -> void: func _ready() -> void:
World.instance = self World.instance = self
manager.alert_raised.connect(spook_manager.on_alert_raised) Game.manager.player_dead.connect(on_player_death)
manager.alert_cleared.connect(spook_manager.on_alert_cleared)
manager.player_dead.connect(on_player_death)
if initial_level:
load_level(initial_level) load_level(initial_level)
@ -53,15 +45,8 @@ func unpause() -> void:
func load_level(level: PackedScene) -> void: func load_level(level: PackedScene) -> void:
for c: Node in level_root.get_children(): for c: Node in level_root.get_children():
c.queue_free() c.queue_free()
level_root.remove_child(c) current_level = level
current_level_scene = level level_root.add_child(level.instantiate())
print("Instantiating level from ", level.resource_path)
current_level = level.instantiate()
level_root.add_child(current_level)
if save_state:
save_state.load_to_world(self)
print("Done!")
spook_manager.after_level_init()
func on_player_death() -> void: func on_player_death() -> void:
@ -70,26 +55,7 @@ func on_player_death() -> void:
ui_root.add_child(kill_screen) ui_root.add_child(kill_screen)
func _reload_saved(save: SaveState) -> void:
save_state = save
load_level(current_level_scene)
func on_game_over() -> void: func on_game_over() -> void:
# reload the level from the last save # TODO: reload from last checkpoint
var save_path := current_level.get_save_path() # in the mean time, just reload the level
if FileAccess.file_exists(save_path): load_level(current_level)
Game.instance.queue_load(save_path).finally(_reload_saved)
else:
load_level(current_level_scene)
func save_progress() -> void:
print("Preparing save state...")
save_icon.show()
var save := SaveState.serialize(self)
var save_path := current_level.get_save_path()
print("Writing save to ", save_path)
ResourceSaver.save(save, save_path)
save_icon.hide()
print("Done!")

View File

@ -1,18 +1,21 @@
[gd_scene load_steps=8 format=3 uid="uid://884jqafhtrv0"] [gd_scene load_steps=8 format=3 uid="uid://884jqafhtrv0"]
[ext_resource type="Script" uid="uid://cgqmhtemibxc5" path="res://src/world/world.gd" id="1_1k4gi"] [ext_resource type="Script" uid="uid://cgqmhtemibxc5" path="res://src/world/world.gd" id="1_1k4gi"]
[ext_resource type="Resource" uid="uid://tgac5tnfx56r" path="res://src/world/world_manager.tres" id="2_5kmgb"]
[ext_resource type="PackedScene" uid="uid://byvjsvavbg5xe" path="res://src/ui/menus/pause_menu/pause_menu.tscn" id="2_6fy3g"] [ext_resource type="PackedScene" uid="uid://byvjsvavbg5xe" path="res://src/ui/menus/pause_menu/pause_menu.tscn" id="2_6fy3g"]
[ext_resource type="Resource" uid="uid://0i72bf8ip1lx" path="res://src/world/spook_manager.tres" id="3_l0av5"] [ext_resource type="PackedScene" uid="uid://ehf5sg3ahvbf" path="res://src/world/grunk_beast/grunk_beast.tscn" id="2_43c6p"]
[ext_resource type="PackedScene" uid="uid://b8rv6dg4tgaeb" path="res://levels/mechanic_test/mechanic_test.tscn" id="4_5kmgb"] [ext_resource type="Script" uid="uid://bsn026pxqwkbc" path="res://src/world/spook_manager/spook_manager.gd" id="2_bsf3i"]
[ext_resource type="PackedScene" uid="uid://bov4ok76woyc" path="res://levels/ghost_ship/ghost_ship.tscn" id="2_jte2u"]
[ext_resource type="PackedScene" uid="uid://c0uitm5cg88h1" path="res://src/ui/menus/kill_screen/kill_screen.tscn" id="6_l0av5"] [ext_resource type="PackedScene" uid="uid://c0uitm5cg88h1" path="res://src/ui/menus/kill_screen/kill_screen.tscn" id="6_l0av5"]
[ext_resource type="PackedScene" uid="uid://brknr57xc2cp0" path="res://src/ui/elements/save_icon/save_icon.tscn" id="7_5kmgb"]
[sub_resource type="Resource" id="Resource_43c6p"]
script = ExtResource("2_bsf3i")
grunkbeast_scene = ExtResource("2_43c6p")
metadata/_custom_type_script = "uid://bsn026pxqwkbc"
[node name="World" type="Node"] [node name="World" type="Node"]
script = ExtResource("1_1k4gi") script = ExtResource("1_1k4gi")
manager = ExtResource("2_5kmgb") spook_manager = SubResource("Resource_43c6p")
spook_manager = ExtResource("3_l0av5") initial_level = ExtResource("2_jte2u")
initial_level = ExtResource("4_5kmgb")
pause_scene = ExtResource("2_6fy3g") pause_scene = ExtResource("2_6fy3g")
kill_screen_scene = ExtResource("6_l0av5") kill_screen_scene = ExtResource("6_l0av5")
@ -28,17 +31,3 @@ anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2 mouse_filter = 2
[node name="SaveIcon" parent="UIRoot" instance=ExtResource("7_5kmgb")]
unique_name_in_owner = true
visible = false
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_top = -140.0
offset_right = 140.0
offset_bottom = 0.0
grow_vertical = 0
theme_override_constants/margin_left = 32
theme_override_constants/margin_bottom = 32

View File

@ -32,13 +32,3 @@ func _on_interactive_activated() -> void:
Player.instance.add_item(item) Player.instance.add_item(item)
# TODO: animation, sfx on collect? # TODO: animation, sfx on collect?
queue_free() queue_free()
func serialize() -> Dictionary:
# Nothing to serialize, but we need a placeholder value to show we haven't been destroyed.
return {}
func deserialize(_state: Dictionary) -> void:
# Nothing to deserialize, but we won't be freed!
pass

View File

@ -6,7 +6,7 @@
[sub_resource type="SphereShape3D" id="SphereShape3D_0mein"] [sub_resource type="SphereShape3D" id="SphereShape3D_0mein"]
radius = 0.25 radius = 0.25
[node name="WorldItem" type="MeshInstance3D" groups=["Persistent"]] [node name="WorldItem" type="MeshInstance3D"]
script = ExtResource("1_sptcj") script = ExtResource("1_sptcj")
[node name="Interactive" type="StaticBody3D" parent="."] [node name="Interactive" type="StaticBody3D" parent="."]