diff --git a/levels/ghost_ship/ambient_drone.gd b/levels/ghost_ship/ambient_drone.gd index 95a9234..81b4432 100644 --- a/levels/ghost_ship/ambient_drone.gd +++ b/levels/ghost_ship/ambient_drone.gd @@ -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) diff --git a/levels/ghost_ship/player_ship/grunk_terminal/grunk_terminal.gd b/levels/ghost_ship/player_ship/grunk_terminal/grunk_terminal.gd index 65f204f..714a0e7 100644 --- a/levels/ghost_ship/player_ship/grunk_terminal/grunk_terminal.gd +++ b/levels/ghost_ship/player_ship/grunk_terminal/grunk_terminal.gd @@ -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(), diff --git a/levels/ghost_ship/player_ship/player_ship.gd b/levels/ghost_ship/player_ship/player_ship.gd index c572579..dbdf881 100644 --- a/levels/ghost_ship/player_ship/player_ship.gd +++ b/levels/ghost_ship/player_ship/player_ship.gd @@ -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() diff --git a/project.godot b/project.godot index d4d67a5..e2e6cbe 100644 --- a/project.godot +++ b/project.godot @@ -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] diff --git a/src/equipment/spray.gd b/src/equipment/spray.gd index 442ba31..708ff68 100644 --- a/src/equipment/spray.gd +++ b/src/equipment/spray.gd @@ -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 diff --git a/src/equipment/toothbrush/toothbrush.gd b/src/equipment/toothbrush/toothbrush.gd index 4504214..26c6bde 100644 --- a/src/equipment/toothbrush/toothbrush.gd +++ b/src/equipment/toothbrush/toothbrush.gd @@ -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: diff --git a/src/game/game.gd b/src/game/game.gd index a876c77..26cdf14 100644 --- a/src/game/game.gd +++ b/src/game/game.gd @@ -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 diff --git a/src/player/player.gd b/src/player/player.gd index d4770aa..48c465f 100644 --- a/src/player/player.gd +++ b/src/player/player.gd @@ -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 diff --git a/src/ui/hud/grunk_counter/grunk_counter.gd b/src/ui/hud/grunk_counter/grunk_counter.gd index 1b31269..0e8eb8b 100644 --- a/src/ui/hud/grunk_counter/grunk_counter.gd +++ b/src/ui/hud/grunk_counter/grunk_counter.gd @@ -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)) diff --git a/src/ui/hud/grunk_gauge/grunk_gauge.gd b/src/ui/hud/grunk_gauge/grunk_gauge.gd index ea46d34..e50a70c 100644 --- a/src/ui/hud/grunk_gauge/grunk_gauge.gd +++ b/src/ui/hud/grunk_gauge/grunk_gauge.gd @@ -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 diff --git a/src/ui/hud/player_hud.gd b/src/ui/hud/player_hud.gd index 0895ff4..2d73ad4 100644 --- a/src/ui/hud/player_hud.gd +++ b/src/ui/hud/player_hud.gd @@ -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: diff --git a/src/world/grunk_beast/behaviors/actions/set_player_priority_target.gd b/src/world/grunk_beast/behaviors/actions/set_player_priority_target.gd index ab7cf59..4e33dcd 100644 --- a/src/world/grunk_beast/behaviors/actions/set_player_priority_target.gd +++ b/src/world/grunk_beast/behaviors/actions/set_player_priority_target.gd @@ -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 diff --git a/src/world/gunk_body/gunk_body.gd b/src/world/gunk_body/gunk_body.gd index 7c7a2c6..c8b16a1 100644 --- a/src/world/gunk_body/gunk_body.gd +++ b/src/world/gunk_body/gunk_body.gd @@ -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. diff --git a/src/world/gunk_node/gunk_node.gd b/src/world/gunk_node/gunk_node.gd index 3d269a9..06af623 100644 --- a/src/world/gunk_node/gunk_node.gd +++ b/src/world/gunk_node/gunk_node.gd @@ -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 diff --git a/src/world/mechanics/alarm/gunk_alarm.gd b/src/world/mechanics/alarm/gunk_alarm.gd index 60d4650..1648525 100644 --- a/src/world/mechanics/alarm/gunk_alarm.gd +++ b/src/world/mechanics/alarm/gunk_alarm.gd @@ -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() diff --git a/src/world/spook_manager.tres b/src/world/spook_manager.tres new file mode 100644 index 0000000..797a565 --- /dev/null +++ b/src/world/spook_manager.tres @@ -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" diff --git a/src/world/spook_manager/spook_manager.gd b/src/world/spook_manager/spook_manager.gd index f8b152b..07d741b 100644 --- a/src/world/spook_manager/spook_manager.gd +++ b/src/world/spook_manager/spook_manager.gd @@ -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 diff --git a/src/world/world.gd b/src/world/world.gd index fee04aa..9095fd2 100644 --- a/src/world/world.gd +++ b/src/world/world.gd @@ -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) diff --git a/src/world/world.tscn b/src/world/world.tscn index 3d23aa4..2559234 100644 --- a/src/world/world.tscn +++ b/src/world/world.tscn @@ -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") diff --git a/src/game/game_manager.gd b/src/world/world_manager.gd similarity index 96% rename from src/game/game_manager.gd rename to src/world/world_manager.gd index 74d7315..add2571 100644 --- a/src/game/game_manager.gd +++ b/src/world/world_manager.gd @@ -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 diff --git a/src/game/game_manager.gd.uid b/src/world/world_manager.gd.uid similarity index 100% rename from src/game/game_manager.gd.uid rename to src/world/world_manager.gd.uid diff --git a/src/game/game_manager.tscn b/src/world/world_manager.tres similarity index 83% rename from src/game/game_manager.tscn rename to src/world/world_manager.tres index 02bc7b7..067cdea 100644 --- a/src/game/game_manager.tscn +++ b/src/world/world_manager.tres @@ -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"