GameManager is now WorldManager, a resource managed as part of the world

This commit is contained in:
Rob Kelly 2025-04-21 16:48:08 -06:00
parent 033c12365d
commit dcd5d5d57d
22 changed files with 84 additions and 77 deletions

View File

@ -16,7 +16,7 @@ var boosted := false
func _ready() -> void:
Game.manager.alert_raised.connect(_on_alert_raised)
World.instance.manager.alert_raised.connect(_on_alert_raised)
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:
if new_level == Game.manager.MAX_ALERT:
if new_level == World.instance.manager.MAX_ALERT:
suppress(30)
else:
boost(10.0)

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:
Game.manager.grunk_emptied.connect(_on_tank_emptied)
World.instance.manager.grunk_emptied.connect(_on_tank_emptied)
recompute()
func _next_milestone_name() -> String:
var next_milestone := Game.manager.next_milestone()
var next_milestone := World.instance.manager.next_milestone()
return next_milestone.name if next_milestone else "NOTHING"
func _next_milestone_amount() -> String:
var next_milestone_amt := Game.manager.next_milestone_amount()
var next_milestone_amt := World.instance.manager.next_milestone_amount()
return str(next_milestone_amt) if next_milestone_amt >= 0 else "NEVER"
func build_message() -> String:
var msg_lines := Game.manager.latest_milestone().message.split("\n")
var msg_lines := World.instance.manager.latest_milestone().message.split("\n")
var line_1 := msg_lines[0]
var line_2 := msg_lines[1] if len(msg_lines) >= 2 else ""
return MESSAGE_FMT.format(
[
int(Game.manager.grunk_quota),
int(Game.manager.grunk_vault),
int(World.instance.manager.grunk_quota),
int(World.instance.manager.grunk_vault),
line_1,
line_2,
_next_milestone_name(),

View File

@ -13,7 +13,7 @@ const TANK_FILL_TIME := 1.0
func _ready() -> void:
Game.manager.grunk_collected.connect(_enable_tank)
World.instance.manager.grunk_collected.connect(_enable_tank)
func _enable_tank(_delta: float) -> void:
@ -24,9 +24,9 @@ func _enable_tank(_delta: float) -> void:
func deposit_grunk() -> void:
# Tank is disabled until the player collects more grunk.
tank_interactor.enabled = false
Game.manager.deposit_tank()
World.instance.manager.deposit_tank()
set_liquid_level(clampf(Game.manager.grunk_vault / MAX_GRUNK, 0.0, 1.0))
set_liquid_level(clampf(World.instance.manager.grunk_vault / MAX_GRUNK, 0.0, 1.0))
grunk_pump_sfx.play()

View File

@ -28,7 +28,6 @@ BeehaveGlobalDebugger="*res://addons/beehave/debug/global_debugger.gd"
GameRuntime="*res://src/game/game_runtime.gd"
ItemCatalog="*res://src/items/item_catalog.tscn"
GameSettings="*res://src/game/game_settings.gd"
GameManager="*res://src/game/game_manager.tscn"
[debug]

View File

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

View File

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

View File

@ -5,9 +5,6 @@ class_name Game extends Node
@export var world_scene: PackedScene
## Handy typed singleton access.
static var manager: GameManagerType:
get():
return GameManager
static var settings: GameSettingsType:
get():
return GameSettings

View File

@ -75,7 +75,7 @@ static var instance: Player
func _ready() -> void:
Game.manager.milestone_reached.connect(_on_milestone)
World.instance.manager.milestone_reached.connect(_on_milestone)
instance = self
@ -174,7 +174,7 @@ func _on_milestone(milestone: Milestone) -> void:
func _signal_death() -> void:
# Called from the death animation
Game.manager.on_player_death()
World.instance.manager.on_player_death()
#endregion

View File

@ -10,15 +10,15 @@ const TANK_WARNING_BUFFER_PCT := 0.1
func _ready() -> void:
Game.manager.grunk_collected.connect(on_grunk_collected)
Game.manager.grunk_emptied.connect(on_grunk_emptied)
World.instance.manager.grunk_collected.connect(on_grunk_collected)
World.instance.manager.grunk_emptied.connect(on_grunk_emptied)
counter.pivot_offset = Vector2(0, counter.size.y)
func on_grunk_collected(delta: float) -> void:
counter.text = str(int(clampf(Game.manager.grunk_tank, 0.0, Game.manager.grunk_tank_limit)))
counter.text = str(int(clampf(World.instance.manager.grunk_tank, 0.0, World.instance.manager.grunk_tank_limit)))
counter.scale = Vector2.ONE + Vector2.ONE * clampf(delta / 128.0, 0.1, 1.0)
var buffer := remap(Game.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1)
var buffer := remap(World.instance.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 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:
Game.manager.grunk_collected.connect(on_grunk_collected)
Game.manager.grunk_emptied.connect(on_grunk_emptied)
World.instance.manager.grunk_collected.connect(on_grunk_collected)
World.instance.manager.grunk_emptied.connect(on_grunk_emptied)
func get_target_rotation() -> float:
return remap(
Game.manager.grunk_tank,
World.instance.manager.grunk_tank,
0,
Game.manager.grunk_tank_limit,
World.instance.manager.grunk_tank_limit,
NEEDLE_ANGLE_MIN,
NEEDLE_ANGLE_MAX
)
func on_grunk_collected(_delta: float) -> void:
var buffer := remap(Game.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1)
var buffer := remap(World.instance.manager.get_tank_fill_pct(), 1 - TANK_WARNING_BUFFER_PCT, 1, 0, 1)
_base_rumble = BUFFER_RUMBLE_FACTOR * buffer

View File

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

View File

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

View File

@ -264,7 +264,7 @@ func _process(_delta: float) -> void:
clear_total_updated.emit(new_total)
# XXX due to fp error, this will drift from the "true count" over time
# but it probably won't matter :shrug:
Game.manager.collect_grunk(delta)
World.instance.manager.collect_grunk(delta)
_prev_clear_total = new_total
# If paint_continuous wasn't called last frame, stop the current polyline.

View File

@ -49,7 +49,7 @@ func _process(_delta: float) -> void:
## Destroy this node, with the player collecting the grunk value.
func collect() -> void:
Game.manager.collect_grunk(value)
World.instance.manager.collect_grunk(value)
destroy()
@ -57,7 +57,7 @@ func collect() -> void:
##
## Derived types should override `_destroy` as a lifecycle method.
func destroy() -> void:
Game.manager.collect_grunk(value)
World.instance.manager.collect_grunk(value)
var splatter := GrunkSplatter.build(splatter_scale * scale.x)
add_sibling(splatter)
splatter.global_position = global_position

View File

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

View File

@ -0,0 +1,9 @@
[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,12 +7,7 @@ const BEAST_GROUP := "GrunkBeast"
@export var grunkbeast_scene: PackedScene
var debug_set_alert_level: int:
set = _on_alert_raised
func _init() -> void:
Game.manager.alert_raised.connect(_on_alert_raised)
Game.manager.alert_cleared.connect(_on_alert_cleared)
set = on_alert_raised
func _spawn_beast_at_point(spawn_point: Node3D) -> void:
@ -26,7 +21,7 @@ func spawn_beast() -> void:
var spawn_point := SceneTools.pick_unseen_from_group(SPAWN_GROUP)
if not spawn_point:
print_debug("Couldn't find a hidden spawn point... Picking one at random.")
var nodes := Game.manager.get_tree().get_nodes_in_group(SPAWN_GROUP)
var nodes := World.instance.get_tree().get_nodes_in_group(SPAWN_GROUP)
if not nodes:
print_debug("Oh that's why. There aren't any spawn points. Complain to a developer.")
return
@ -38,14 +33,14 @@ func spawn_beast() -> void:
## Spawn beasts at _every_ spawn point the player can't see.
func spawn_many_beasts() -> void:
var nodes := Game.manager.get_tree().get_nodes_in_group(SPAWN_GROUP)
var nodes := World.instance.get_tree().get_nodes_in_group(SPAWN_GROUP)
for node: Node in nodes:
var target := node as Node3D
if is_instance_valid(target) and not SceneTools.player_can_see(target.global_position):
_spawn_beast_at_point(target)
func _on_alert_raised(new_level: int) -> void:
func on_alert_raised(new_level: int) -> void:
match new_level:
0:
# LEVEL 0: UNAWARE
@ -77,9 +72,9 @@ func _on_alert_raised(new_level: int) -> void:
pass # TODO
func _on_alert_cleared() -> void:
func on_alert_cleared() -> void:
# Destroy all but one grunk beasts
var beasts := Game.manager.get_tree().get_nodes_in_group(BEAST_GROUP)
var beasts := World.instance.get_tree().get_nodes_in_group(BEAST_GROUP)
if not beasts:
return

View File

@ -3,6 +3,7 @@ class_name World extends Node
@export var pause_enabled := true
@export var manager: WorldManager
@export var spook_manager: SpookManager
@export_category("Game Scenes")
@ -22,7 +23,9 @@ static var instance: World
func _ready() -> void:
World.instance = self
Game.manager.player_dead.connect(on_player_death)
manager.alert_raised.connect(spook_manager.on_alert_raised)
manager.alert_cleared.connect(spook_manager.on_alert_cleared)
manager.player_dead.connect(on_player_death)
load_level(initial_level)

View File

@ -1,20 +1,16 @@
[gd_scene load_steps=8 format=3 uid="uid://884jqafhtrv0"]
[gd_scene load_steps=7 format=3 uid="uid://884jqafhtrv0"]
[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://ehf5sg3ahvbf" path="res://src/world/grunk_beast/grunk_beast.tscn" id="2_43c6p"]
[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="Resource" uid="uid://0i72bf8ip1lx" path="res://src/world/spook_manager.tres" id="3_l0av5"]
[ext_resource type="PackedScene" uid="uid://c0uitm5cg88h1" path="res://src/ui/menus/kill_screen/kill_screen.tscn" id="6_l0av5"]
[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"]
script = ExtResource("1_1k4gi")
spook_manager = SubResource("Resource_43c6p")
manager = ExtResource("2_5kmgb")
spook_manager = ExtResource("3_l0av5")
initial_level = ExtResource("2_jte2u")
pause_scene = ExtResource("2_6fy3g")
kill_screen_scene = ExtResource("6_l0av5")

View File

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

View File

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