Compare commits

...

3 Commits

Author SHA1 Message Date
dc26836020 MP3 player has force feedback
All checks were successful
linting & formatting / build (push) Successful in 24s
2025-06-27 12:56:50 -06:00
36e5bcf099 Revised World debug functions 2025-06-27 12:47:06 -06:00
0de77c8595 Added MP3 player functionality 2025-06-27 12:22:17 -06:00
23 changed files with 476 additions and 46 deletions

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://bp1dv4lv3344w"
path="res://.godot/imported/chorus_01.wav-08b913ed895775e6776d50f6bebe6a94.sample"
[deps]
source_file="res://assets/music/chorus_01.wav"
dest_files=["res://.godot/imported/chorus_01.wav-08b913ed895775e6776d50f6bebe6a94.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://ccqmeqw3moxfd"
path="res://.godot/imported/descending_04.wav-d6765ea0a0cafe097da2847bcc202f16.sample"
[deps]
source_file="res://assets/music/descending_04.wav"
dest_files=["res://.godot/imported/descending_04.wav-d6765ea0a0cafe097da2847bcc202f16.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dgxko5ds8u2lk"
path="res://.godot/imported/desert_01.wav-581b6d94c48b10543d281e48b9fba2bb.sample"
[deps]
source_file="res://assets/music/desert_01.wav"
dest_files=["res://.godot/imported/desert_01.wav-581b6d94c48b10543d281e48b9fba2bb.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://d4qqqrnplej6"
path="res://.godot/imported/driving_01.wav-cd2dee17817d890d256fe4c14c9be367.sample"
[deps]
source_file="res://assets/music/driving_01.wav"
dest_files=["res://.godot/imported/driving_01.wav-cd2dee17817d890d256fe4c14c9be367.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://b1rmpakal8l6j"
path="res://.godot/imported/driving_02.wav-ab678e7fa7549ee6f71278ea940b33ae.sample"
[deps]
source_file="res://assets/music/driving_02.wav"
dest_files=["res://.godot/imported/driving_02.wav-ab678e7fa7549ee6f71278ea940b33ae.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dgvknkfvoqk8r"
path="res://.godot/imported/simple_sample_01.wav-f44635820b5ba74709e951468def2cb5.sample"
[deps]
source_file="res://assets/music/simple_sample_01.wav"
dest_files=["res://.godot/imported/simple_sample_01.wav-f44635820b5ba74709e951468def2cb5.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://b6wrx5fibaujw"
path="res://.godot/imported/thaw_v1_fast.wav-69deab9ac1a9e8ba32290fbad3f5a8f6.sample"
[deps]
source_file="res://assets/music/thaw_v1_fast.wav"
dest_files=["res://.godot/imported/thaw_v1_fast.wav-69deab9ac1a9e8ba32290fbad3f5a8f6.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://b3ktgjeq6fupj"
path="res://.godot/imported/thaw_v1_slow.wav-28769b14b2030e9c75166aac3c81680a.sample"
[deps]
source_file="res://assets/music/thaw_v1_slow.wav"
dest_files=["res://.godot/imported/thaw_v1_slow.wav-28769b14b2030e9c75166aac3c81680a.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://p14r7l44dahr"
path="res://.godot/imported/thaw_v2_fast.wav-86f532708c35d5089df8e52aecf29505.sample"
[deps]
source_file="res://assets/music/thaw_v2_fast.wav"
dest_files=["res://.godot/imported/thaw_v2_fast.wav-86f532708c35d5089df8e52aecf29505.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://bkvjtdlhjfr7n"
path="res://.godot/imported/thaw_v2_slow.wav-f845bbe60946eed225876fcc22e1147c.sample"
[deps]
source_file="res://assets/music/thaw_v2_slow.wav"
dest_files=["res://.godot/imported/thaw_v2_slow.wav-f845bbe60946eed225876fcc22e1147c.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2

View File

@ -13,6 +13,11 @@ var selecting := true
@onready var transition_player: AnimationPlayer = %TransitionPlayer @onready var transition_player: AnimationPlayer = %TransitionPlayer
func set_track_list(track_list: Array[String]) -> void:
retro_selector_list.options = track_list
retro_selector_list.rebuild_list()
func set_paused(paused: bool) -> void: func set_paused(paused: bool) -> void:
play_label.visible = not paused play_label.visible = not paused
pause_label.visible = paused pause_label.visible = paused

View File

@ -1,7 +1,16 @@
extends Tool extends Tool
## Pump up the jamz! ## Pump up the jamz!
const RUMBLE_INTENSITY = 0.006
const RUMBLE_DROPOFF = 0.8
@onready var mp3_controller: MP3Controller = %MP3Controller @onready var mp3_controller: MP3Controller = %MP3Controller
@onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer
@onready var rumbler: Rumbler3D = %Rumbler
func _ready() -> void:
World.instance.manager.mp3_collected.connect(_on_mp3_collected)
func unlocked() -> bool: func unlocked() -> bool:
@ -11,8 +20,38 @@ func unlocked() -> bool:
func fire() -> void: func fire() -> void:
if not firing: if not firing:
firing = true firing = true
rumbler.intensity = RUMBLE_INTENSITY
mp3_controller.select() mp3_controller.select()
func switch_mode() -> void: func switch_mode() -> void:
rumbler.intensity = RUMBLE_INTENSITY
mp3_controller.cancel() mp3_controller.cancel()
func _physics_process(delta: float) -> void:
rumbler.intensity *= RUMBLE_DROPOFF
super._physics_process(delta)
func _on_mp3_collected(_track: MP3Track) -> void:
# TODO we may want to dynamically build the player tracklist
# rather than rebuilding the whole thing each time a track is collected
var mp3_list: Array[String] = []
mp3_list.assign(
World.instance.manager.mp3_collection.map(func(mp3: MP3Track) -> String: return mp3.title)
)
mp3_controller.set_track_list(mp3_list)
func pause_playback() -> void:
audio_stream_player.stream_paused = true
func resume_playback() -> void:
audio_stream_player.stream_paused = false
func select_track(idx: int) -> void:
audio_stream_player.stream = World.instance.manager.mp3_collection[idx].track
audio_stream_player.play()

View File

@ -82,3 +82,11 @@ skew = 0.0331613
unique_name_in_owner = true unique_name_in_owner = true
offset_right = 70.0 offset_right = 70.0
offset_bottom = 76.0 offset_bottom = 76.0
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
bus = &"Music"
[connection signal="pause" from="HUDTool/Rumbler/Position/HUDElement/DeviceScreenMask/SubViewportContainer/SubViewport/ScreenTransform/MP3Controller" to="." method="pause_playback"]
[connection signal="resume" from="HUDTool/Rumbler/Position/HUDElement/DeviceScreenMask/SubViewportContainer/SubViewport/ScreenTransform/MP3Controller" to="." method="resume_playback"]
[connection signal="select_track" from="HUDTool/Rumbler/Position/HUDElement/DeviceScreenMask/SubViewportContainer/SubViewport/ScreenTransform/MP3Controller" to="." method="select_track"]

View File

@ -0,0 +1,5 @@
class_name MP3Track extends Resource
## Tracks for the MP3 player
@export var title: String
@export var track: AudioStream

View File

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

View File

@ -1,4 +1,3 @@
@tool
class_name RetroSelectorList extends Control class_name RetroSelectorList extends Control
const DEFAULT_HEIGHT := 76.0 const DEFAULT_HEIGHT := 76.0
@ -23,11 +22,6 @@ const BLINK_INTERVAL := 0.2
@export var tween_scale := 0.24 @export var tween_scale := 0.24
@export var debug_update_list: bool:
set(value):
if value:
_build_list()
var _active_tween: Tween var _active_tween: Tween
@onready var screen_bounds_container: Control = %ScreenBoundsContainer @onready var screen_bounds_container: Control = %ScreenBoundsContainer
@onready var title_list: VBoxContainer = %TitleList @onready var title_list: VBoxContainer = %TitleList
@ -35,10 +29,10 @@ var _active_tween: Tween
func _ready() -> void: func _ready() -> void:
_build_list() rebuild_list()
func _build_list() -> void: func rebuild_list() -> void:
# Remove any existing items # Remove any existing items
for c: Node in title_list.get_children(): for c: Node in title_list.get_children():
c.queue_free() c.queue_free()
@ -49,7 +43,7 @@ func _build_list() -> void:
item_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER item_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
title_list.add_child(item_label) title_list.add_child(item_label)
selection_idx = selection_idx % options.size() selection_idx = (selection_idx % options.size()) if options else 0
func _new_tween() -> Tween: func _new_tween() -> Tween:

View File

@ -19,7 +19,6 @@ offset_right = 70.0
offset_bottom = 76.0 offset_bottom = 76.0
theme = ExtResource("2_4rnpc") theme = ExtResource("2_4rnpc")
script = ExtResource("1_kvinm") script = ExtResource("1_kvinm")
options = Array[String](["thing1", "thing2", "uhh", "thing4"])
[node name="ScreenBoundsContainer" type="Control" parent="."] [node name="ScreenBoundsContainer" type="Control" parent="."]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -5,7 +5,7 @@ class_name Milestone extends Resource
@export_multiline var message: String @export_multiline var message: String
@export_group("Effects") @export_group("Effects")
@export var bonus_track := false @export var bonus_track: MP3Track
@export var mp3_player := false @export var mp3_player := false
@export var toothbrush := false @export var toothbrush := false
@export var seminar := false @export var seminar := false

View File

@ -1,7 +1,7 @@
class_name SaveState extends Resource class_name SaveState extends Resource
## Serializable container for gameplay state. ## Serializable container for gameplay state.
const CURRENT_VERSION := 1 const CURRENT_VERSION := 2
const PERSISTENT_GROUP := "Persistent" const PERSISTENT_GROUP := "Persistent"
const SERIALIZE_METHOD := "serialize" const SERIALIZE_METHOD := "serialize"
const DESERIALIZE_METHOD := "deserialize" const DESERIALIZE_METHOD := "deserialize"
@ -18,6 +18,7 @@ const DESERIALIZE_METHOD := "deserialize"
@export var mp3_player_unlocked: bool @export var mp3_player_unlocked: bool
@export var toothbrush_unlocked: bool @export var toothbrush_unlocked: bool
@export var stickers_unlocked: bool @export var stickers_unlocked: bool
@export var mp3_collection: Array[MP3Track]
@export var grunk_tank: float @export var grunk_tank: float
@export var grunk_vault: float @export var grunk_vault: float
@ -61,6 +62,7 @@ func load_to_world(world: World) -> void:
world.manager.mp3_player_unlocked = mp3_player_unlocked world.manager.mp3_player_unlocked = mp3_player_unlocked
world.manager.toothbrush_unlocked = toothbrush_unlocked world.manager.toothbrush_unlocked = toothbrush_unlocked
world.manager.stickers_unlocked = stickers_unlocked world.manager.stickers_unlocked = stickers_unlocked
world.manager.mp3_collection = mp3_collection
world.manager.grunk_tank = grunk_tank world.manager.grunk_tank = grunk_tank
world.manager.grunk_vault = grunk_vault world.manager.grunk_vault = grunk_vault
world.manager.alert_level = alert_level world.manager.alert_level = alert_level
@ -88,6 +90,7 @@ static func serialize(world: World) -> SaveState:
save.mp3_player_unlocked = world.manager.mp3_player_unlocked save.mp3_player_unlocked = world.manager.mp3_player_unlocked
save.toothbrush_unlocked = world.manager.toothbrush_unlocked save.toothbrush_unlocked = world.manager.toothbrush_unlocked
save.stickers_unlocked = world.manager.stickers_unlocked save.stickers_unlocked = world.manager.stickers_unlocked
save.mp3_collection = world.manager.mp3_collection
save.grunk_tank = world.manager.grunk_tank save.grunk_tank = world.manager.grunk_tank
save.grunk_vault = world.manager.grunk_vault save.grunk_vault = world.manager.grunk_vault
save.alert_level = world.manager.alert_level save.alert_level = world.manager.alert_level

View File

@ -17,6 +17,18 @@ class_name World extends Node
@export var save_icon_scene: PackedScene @export var save_icon_scene: PackedScene
## Debug tools
var debug_emit_alert_signal: int:
set(value):
manager.alert_raised.emit(value)
var debug_unlock_next_milestone: bool:
set(value):
if value:
var milestone := manager.next_milestone()
manager.grunk_vault = manager.next_milestone_amount()
manager.milestone_reached.emit(milestone)
var current_level_scene: PackedScene var current_level_scene: PackedScene
var current_level: Level var current_level: Level

View File

@ -4,7 +4,7 @@
[ext_resource type="Resource" uid="uid://tgac5tnfx56r" path="res://src/world/world_manager.tres" id="2_5kmgb"] [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="Resource" uid="uid://0i72bf8ip1lx" path="res://src/world/spook_manager.tres" id="3_l0av5"]
[ext_resource type="PackedScene" uid="uid://dc4tts6342cuj" path="res://levels/prop_test/prop_test.tscn" id="4_5kmgb"] [ext_resource type="PackedScene" uid="uid://bov4ok76woyc" path="res://levels/ghost_ship/ghost_ship.tscn" id="4_5kmgb"]
[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"] [ext_resource type="PackedScene" uid="uid://brknr57xc2cp0" path="res://src/ui/elements/save_icon/save_icon.tscn" id="7_5kmgb"]

View File

@ -18,6 +18,9 @@ signal alert_cleared
## Emitted after the player's grunk vault reaches a new milestone. ## Emitted after the player's grunk vault reaches a new milestone.
signal milestone_reached(milestone: Milestone) signal milestone_reached(milestone: Milestone)
## Emitted after the player collects a new MP3
signal mp3_collected(mp3_track: MP3Track)
## Emitted as soon as the player dies. ## Emitted as soon as the player dies.
signal player_dead signal player_dead
@ -40,20 +43,13 @@ const BIG_TANK_LIMIT := 198000
@export var mp3_player_unlocked := false @export var mp3_player_unlocked := false
@export var toothbrush_unlocked := false @export var toothbrush_unlocked := false
@export var stickers_unlocked := false @export var stickers_unlocked := false
@export var mp3_collection: Array[MP3Track] = []
var debug_emit_alert_signal: int:
set(value):
alert_raised.emit(value)
var debug_unlock_milestone: Milestone:
set(value):
milestone_reached.emit(value)
## Amount of grunk the player is currently carrying. ## Amount of grunk the player is currently carrying.
var grunk_tank := 0.0 @export var grunk_tank := 0.0
## Total amount of grunk that has been deposited by the player. ## Total amount of grunk that has been deposited by the player.
var grunk_vault := 0.0 @export var grunk_vault := 0.0
## Level of grunk agressiveness, raised whenever the player messes up. ## Level of grunk agressiveness, raised whenever the player messes up.
var alert_level := 0 var alert_level := 0
@ -147,15 +143,23 @@ func next_milestone_amount() -> int:
func _on_milestone(milestone: Milestone) -> void: func _on_milestone(milestone: Milestone) -> void:
if milestone.mp3_player: if milestone.mp3_player:
mp3_player_unlocked = true mp3_player_unlocked = true
elif milestone.toothbrush: if milestone.toothbrush:
toothbrush_unlocked = true toothbrush_unlocked = true
elif milestone.stickers: if milestone.stickers:
stickers_unlocked = true stickers_unlocked = true
elif milestone.big_tank: if milestone.big_tank:
grunk_tank_limit = BIG_TANK_LIMIT grunk_tank_limit = BIG_TANK_LIMIT
if milestone.bonus_track:
collect_mp3(milestone.bonus_track)
# TODO the rest # TODO the rest
## Add an MP3 player track to the player's collection.
func collect_mp3(track: MP3Track) -> void:
mp3_collection.append(track)
mp3_collected.emit(track)
## Called by Player on death. ## Called by Player on death.
func on_player_death() -> void: func on_player_death() -> void:
player_dead.emit() player_dead.emit()

View File

@ -1,14 +1,21 @@
[gd_resource type="Resource" script_class="WorldManager" load_steps=13 format=3 uid="uid://tgac5tnfx56r"] [gd_resource type="Resource" script_class="WorldManager" load_steps=33 format=3 uid="uid://tgac5tnfx56r"]
[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/world/world_manager.gd" id="1_i77rl"]
[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_c37ff"]
[ext_resource type="Script" uid="uid://kwiy3dv1h7q7" path="res://src/equipment/mp3_player/mp3_track.gd" id="3_yiuq5"]
[ext_resource type="AudioStream" uid="uid://bp1dv4lv3344w" path="res://assets/music/chorus_01.wav" id="4_dwul7"]
[ext_resource type="AudioStream" uid="uid://ccqmeqw3moxfd" path="res://assets/music/descending_04.wav" id="5_dwul7"]
[ext_resource type="AudioStream" uid="uid://d4qqqrnplej6" path="res://assets/music/driving_01.wav" id="6_2q28t"]
[ext_resource type="AudioStream" uid="uid://dgvknkfvoqk8r" path="res://assets/music/simple_sample_01.wav" id="7_dojbf"]
[ext_resource type="AudioStream" uid="uid://bkvjtdlhjfr7n" path="res://assets/music/thaw_v2_slow.wav" id="8_81w62"]
[ext_resource type="AudioStream" uid="uid://b1rmpakal8l6j" path="res://assets/music/driving_02.wav" id="9_gv3bq"]
[ext_resource type="AudioStream" uid="uid://dgxko5ds8u2lk" path="res://assets/music/desert_01.wav" id="10_63s66"]
[sub_resource type="Resource" id="Resource_h4r54"] [sub_resource type="Resource" id="Resource_h4r54"]
script = ExtResource("2_c37ff") script = ExtResource("2_c37ff")
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!"
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -19,12 +26,18 @@ mystery = false
fiesta = false fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_veuns"]
script = ExtResource("3_yiuq5")
title = "descending"
track = ExtResource("5_dwul7")
metadata/_custom_type_script = "uid://kwiy3dv1h7q7"
[sub_resource type="Resource" id="Resource_b83gw"] [sub_resource type="Resource" id="Resource_b83gw"]
script = ExtResource("2_c37ff") script = ExtResource("2_c37ff")
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."
bonus_track = false bonus_track = SubResource("Resource_veuns")
mp3_player = true mp3_player = true
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -40,7 +53,6 @@ script = ExtResource("2_c37ff")
name = "TOOTHBRUSH" name = "TOOTHBRUSH"
message = "TOOTHBRUSH DECRYPTED. message = "TOOTHBRUSH DECRYPTED.
Enjoy teethbrushing in moderation!" Enjoy teethbrushing in moderation!"
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = true toothbrush = true
seminar = false seminar = false
@ -51,12 +63,17 @@ mystery = false
fiesta = false fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_h2b4l"]
script = ExtResource("3_yiuq5")
title = "slower"
track = ExtResource("8_81w62")
metadata/_custom_type_script = "uid://kwiy3dv1h7q7"
[sub_resource type="Resource" id="Resource_vebb4"] [sub_resource type="Resource" id="Resource_vebb4"]
script = ExtResource("2_c37ff") script = ExtResource("2_c37ff")
name = "BONUS TRACK" name = "BONUS TRACK"
message = "BONUS TRACK DELIVERED message = "BONUS TRACK DELIVERED"
[TODO]" bonus_track = SubResource("Resource_h2b4l")
bonus_track = true
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -72,7 +89,6 @@ script = ExtResource("2_c37ff")
name = "WELLNESS SEMINAR" name = "WELLNESS SEMINAR"
message = "SEMINAR DECRYPTED. message = "SEMINAR DECRYPTED.
The FUTURE of WELLNESS is TODAY!" The FUTURE of WELLNESS is TODAY!"
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = true seminar = true
@ -83,12 +99,32 @@ mystery = false
fiesta = false fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_enr7w"]
script = ExtResource("3_yiuq5")
title = "driving02"
track = ExtResource("9_gv3bq")
metadata/_custom_type_script = "uid://kwiy3dv1h7q7"
[sub_resource type="Resource" id="Resource_dwul7"]
script = ExtResource("2_c37ff")
name = "BONUS TRACK"
message = "BONUS TRACK DELIVERED"
bonus_track = SubResource("Resource_enr7w")
mp3_player = false
toothbrush = false
seminar = false
big_tank = false
stickers = false
quota = false
mystery = false
fiesta = false
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_c37ff")
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."
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -99,12 +135,32 @@ mystery = false
fiesta = false fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_qb1w8"]
script = ExtResource("3_yiuq5")
title = "simple"
track = ExtResource("7_dojbf")
metadata/_custom_type_script = "uid://kwiy3dv1h7q7"
[sub_resource type="Resource" id="Resource_ohbx8"]
script = ExtResource("2_c37ff")
name = "BONUS TRACK"
message = "BONUS TRACK DELIVERED"
bonus_track = SubResource("Resource_qb1w8")
mp3_player = false
toothbrush = false
seminar = false
big_tank = false
stickers = false
quota = false
mystery = false
fiesta = false
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_c37ff")
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\""
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -115,12 +171,32 @@ mystery = false
fiesta = false fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_drgdw"]
script = ExtResource("3_yiuq5")
title = "driving01"
track = ExtResource("6_2q28t")
metadata/_custom_type_script = "uid://kwiy3dv1h7q7"
[sub_resource type="Resource" id="Resource_74vm3"]
script = ExtResource("2_c37ff")
name = "BONUS TRACK"
message = "BONUS TRACK DELIVERED"
bonus_track = SubResource("Resource_drgdw")
mp3_player = false
toothbrush = false
seminar = false
big_tank = false
stickers = false
quota = false
mystery = false
fiesta = false
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_c37ff")
name = "QUOTA" name = "QUOTA"
message = "QUOTA SATISFIED. message = "QUOTA SATISFIED.
FINE WORK GRUNKER !" FINE WORK GRUNKER !"
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -131,11 +207,32 @@ mystery = false
fiesta = false fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_mwqeg"]
script = ExtResource("3_yiuq5")
title = "gonk"
track = ExtResource("4_dwul7")
metadata/_custom_type_script = "uid://kwiy3dv1h7q7"
[sub_resource type="Resource" id="Resource_6ok02"]
script = ExtResource("2_c37ff")
name = "BONUS TRACK"
message = "BONUS TRACK DELIVERED
THIS ONE'S A CLASSIC"
bonus_track = SubResource("Resource_mwqeg")
mp3_player = false
toothbrush = false
seminar = false
big_tank = false
stickers = false
quota = false
mystery = false
fiesta = false
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_c37ff")
name = "???" name = "???"
message = "????? ?" message = "????? ?"
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -146,11 +243,31 @@ mystery = true
fiesta = false fiesta = false
metadata/_custom_type_script = "uid://ufxoxupdvyd5" metadata/_custom_type_script = "uid://ufxoxupdvyd5"
[sub_resource type="Resource" id="Resource_l175b"]
script = ExtResource("3_yiuq5")
title = "desert"
track = ExtResource("10_63s66")
metadata/_custom_type_script = "uid://kwiy3dv1h7q7"
[sub_resource type="Resource" id="Resource_ysbqn"]
script = ExtResource("2_c37ff")
name = "BONUS TRACK"
message = "BONUS TRACK DELIVERED"
bonus_track = SubResource("Resource_l175b")
mp3_player = false
toothbrush = false
seminar = false
big_tank = false
stickers = false
quota = false
mystery = false
fiesta = false
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_c37ff")
name = "taco fiesta" name = "taco fiesta"
message = "ENJOY THE FIESTA GRUNKER !" message = "ENJOY THE FIESTA GRUNKER !"
bonus_track = false
mp3_player = false mp3_player = false
toothbrush = false toothbrush = false
seminar = false seminar = false
@ -171,18 +288,21 @@ vault_milestones = Dictionary[int, ExtResource("2_c37ff")]({
200000: SubResource("Resource_o6um0"), 200000: SubResource("Resource_o6um0"),
300000: SubResource("Resource_vebb4"), 300000: SubResource("Resource_vebb4"),
400000: SubResource("Resource_aolyc"), 400000: SubResource("Resource_aolyc"),
500000: SubResource("Resource_vebb4"), 500000: SubResource("Resource_dwul7"),
600000: SubResource("Resource_36cpv"), 600000: SubResource("Resource_36cpv"),
800000: SubResource("Resource_vebb4"), 800000: SubResource("Resource_ohbx8"),
1000000: SubResource("Resource_pfnwj"), 1000000: SubResource("Resource_pfnwj"),
1400000: SubResource("Resource_vebb4"), 1400000: SubResource("Resource_74vm3"),
2000000: SubResource("Resource_p7jc6"), 2000000: SubResource("Resource_p7jc6"),
2500000: SubResource("Resource_vebb4"), 2500000: SubResource("Resource_6ok02"),
3200000: SubResource("Resource_2eyq5"), 3200000: SubResource("Resource_2eyq5"),
4200000: SubResource("Resource_vebb4"), 4200000: SubResource("Resource_ysbqn"),
6400000: SubResource("Resource_2qxxw") 6400000: SubResource("Resource_2qxxw")
}) })
mp3_player_unlocked = true mp3_player_unlocked = false
toothbrush_unlocked = true toothbrush_unlocked = false
stickers_unlocked = false stickers_unlocked = false
mp3_collection = Array[ExtResource("3_yiuq5")]([])
grunk_tank = 0.0
grunk_vault = 0.0
metadata/_custom_type_script = "uid://c1i5gnht15x0e" metadata/_custom_type_script = "uid://c1i5gnht15x0e"