2025-04-21 16:48:08 -06:00
|
|
|
class_name WorldManager extends Resource
|
|
|
|
## Autoloaded singleton encapsulating game world state.
|
2025-03-07 19:26:12 -07:00
|
|
|
|
2025-04-10 18:29:00 -06:00
|
|
|
# TODO a lot of this should really be a property of the world.
|
|
|
|
|
2025-03-13 13:34:35 -06:00
|
|
|
## Emitted just after `delta` is added to the player's grunk tank.
|
2025-03-07 19:26:12 -07:00
|
|
|
signal grunk_collected(delta: float)
|
|
|
|
|
2025-03-19 17:27:50 -06:00
|
|
|
## Emitted just after the grunk tank is emptied, where `amount` is how much had been collected.
|
|
|
|
signal grunk_emptied(amount: float)
|
|
|
|
|
2025-03-13 13:34:35 -06:00
|
|
|
## Emitted just before the alert level is raised to `new_value`.
|
|
|
|
signal alert_raised(new_value: int)
|
|
|
|
|
2025-04-20 02:15:46 -06:00
|
|
|
## Emitted just before the alert level is reset to the clear level.
|
2025-03-13 13:34:35 -06:00
|
|
|
signal alert_cleared
|
|
|
|
|
2025-03-21 19:13:17 -06:00
|
|
|
## Emitted after the player's grunk vault reaches a new milestone.
|
|
|
|
signal milestone_reached(milestone: Milestone)
|
2025-03-21 12:07:05 -06:00
|
|
|
|
2025-06-27 12:18:47 -06:00
|
|
|
## Emitted after the player collects a new MP3
|
|
|
|
signal mp3_collected(mp3_track: MP3Track)
|
|
|
|
|
2025-04-19 16:18:12 -06:00
|
|
|
## Emitted as soon as the player dies.
|
|
|
|
signal player_dead
|
|
|
|
|
2025-03-13 13:34:35 -06:00
|
|
|
const MAX_ALERT := 6
|
2025-04-20 02:15:46 -06:00
|
|
|
const CLEAR_LEVEL := 2
|
2025-03-13 13:34:35 -06:00
|
|
|
|
2025-04-19 17:13:36 -06:00
|
|
|
const BASE_TANK_LIMIT := 96000
|
|
|
|
const BIG_TANK_LIMIT := 198000
|
|
|
|
|
2025-03-20 22:45:19 -06:00
|
|
|
## Maximum amount of grunk the player can carry in their tank.
|
2025-04-19 17:13:36 -06:00
|
|
|
@export var grunk_tank_limit := BASE_TANK_LIMIT
|
2025-03-20 22:45:19 -06:00
|
|
|
|
2025-03-21 19:13:17 -06:00
|
|
|
# TODO figure this out
|
|
|
|
@export var grunk_quota := 2000000
|
|
|
|
|
|
|
|
## Grunk collection milestones
|
|
|
|
@export var vault_milestones: Dictionary[int, Milestone]
|
|
|
|
|
2025-04-19 17:13:36 -06:00
|
|
|
@export_group("Progress")
|
|
|
|
@export var mp3_player_unlocked := false
|
|
|
|
@export var toothbrush_unlocked := false
|
|
|
|
@export var stickers_unlocked := false
|
2025-06-27 12:18:47 -06:00
|
|
|
@export var mp3_collection: Array[MP3Track] = []
|
2025-04-19 17:13:36 -06:00
|
|
|
|
2025-03-19 17:27:50 -06:00
|
|
|
## Amount of grunk the player is currently carrying.
|
2025-06-27 12:18:47 -06:00
|
|
|
@export var grunk_tank := 0.0
|
2025-03-07 19:26:12 -07:00
|
|
|
|
2025-03-19 17:27:50 -06:00
|
|
|
## Total amount of grunk that has been deposited by the player.
|
2025-06-27 12:18:47 -06:00
|
|
|
@export var grunk_vault := 0.0
|
2025-03-19 17:27:50 -06:00
|
|
|
|
|
|
|
## Level of grunk agressiveness, raised whenever the player messes up.
|
2025-03-07 19:26:12 -07:00
|
|
|
var alert_level := 0
|
|
|
|
|
|
|
|
|
2025-04-21 16:48:08 -06:00
|
|
|
func _init() -> void:
|
|
|
|
milestone_reached.connect(_on_milestone)
|
|
|
|
|
|
|
|
|
2025-03-13 13:34:35 -06:00
|
|
|
## Add to the player's grunk tank.
|
2025-03-07 19:26:12 -07:00
|
|
|
func collect_grunk(delta: float) -> void:
|
|
|
|
grunk_tank += delta
|
|
|
|
grunk_collected.emit(delta)
|
2025-03-13 13:34:35 -06:00
|
|
|
|
|
|
|
|
2025-03-19 17:27:50 -06:00
|
|
|
## Empty the player's grunk tank, e.g. when depositing grunk.
|
|
|
|
func empty_tank() -> void:
|
|
|
|
var amount := grunk_tank
|
|
|
|
grunk_tank = 0.0
|
|
|
|
grunk_emptied.emit(amount)
|
|
|
|
|
|
|
|
|
|
|
|
## Deposit the player's grunk in the vault, emptying the player's tank.
|
|
|
|
func deposit_tank() -> void:
|
2025-03-21 19:13:17 -06:00
|
|
|
var prev_milestone := latest_milestone()
|
2025-03-19 17:27:50 -06:00
|
|
|
grunk_vault += grunk_tank
|
|
|
|
empty_tank()
|
2025-03-21 19:13:17 -06:00
|
|
|
var new_milestone := latest_milestone()
|
|
|
|
if new_milestone != prev_milestone:
|
|
|
|
milestone_reached.emit(new_milestone)
|
2025-04-20 02:15:46 -06:00
|
|
|
if alert_level >= CLEAR_LEVEL:
|
|
|
|
clear_alert()
|
2025-03-19 17:27:50 -06:00
|
|
|
|
2025-04-22 13:59:24 -06:00
|
|
|
World.instance.save_progress()
|
|
|
|
|
2025-03-19 17:27:50 -06:00
|
|
|
|
2025-03-20 22:45:19 -06:00
|
|
|
func is_tank_full() -> bool:
|
|
|
|
return grunk_tank >= grunk_tank_limit
|
|
|
|
|
|
|
|
|
|
|
|
func get_tank_fill_pct() -> float:
|
|
|
|
return grunk_tank / grunk_tank_limit
|
|
|
|
|
|
|
|
|
2025-03-13 13:34:35 -06:00
|
|
|
## Raise the alert level, if possible.
|
|
|
|
func raise_alert(delta: int) -> void:
|
|
|
|
var new_value := clampi(alert_level + delta, 0, MAX_ALERT)
|
|
|
|
if new_value != alert_level:
|
|
|
|
alert_raised.emit(new_value)
|
|
|
|
alert_level = new_value
|
|
|
|
|
|
|
|
|
2025-04-20 02:15:46 -06:00
|
|
|
## Reset the alert level to the clear level.
|
2025-03-13 13:34:35 -06:00
|
|
|
func clear_alert() -> void:
|
|
|
|
alert_cleared.emit()
|
2025-04-20 02:15:46 -06:00
|
|
|
alert_level = CLEAR_LEVEL
|
2025-03-21 19:13:17 -06:00
|
|
|
|
|
|
|
|
|
|
|
## Returns the latest vault milestone reached by the player.
|
|
|
|
##
|
|
|
|
## Returns null if the player has not reached a milestone (shouldn't be possible).
|
|
|
|
func latest_milestone() -> Milestone:
|
|
|
|
var prev: Milestone = null
|
|
|
|
for milestone_amt: int in vault_milestones:
|
|
|
|
if grunk_vault < milestone_amt:
|
|
|
|
return prev
|
|
|
|
prev = vault_milestones[milestone_amt]
|
|
|
|
return prev
|
|
|
|
|
|
|
|
|
|
|
|
## Returns the next vault milestone for the player to reach.
|
|
|
|
##
|
|
|
|
## Returns null if all milestones have been reached.
|
|
|
|
func next_milestone() -> Milestone:
|
|
|
|
var amt := next_milestone_amount()
|
|
|
|
if amt >= 0:
|
|
|
|
return vault_milestones[amt]
|
|
|
|
return null
|
|
|
|
|
|
|
|
|
|
|
|
## Returns the grunk amount needed for the player to reach the next milestone.
|
|
|
|
##
|
|
|
|
## Returns <0 if all milestones have been reached.
|
|
|
|
func next_milestone_amount() -> int:
|
|
|
|
for milestone_amt: int in vault_milestones:
|
|
|
|
if grunk_vault < milestone_amt:
|
|
|
|
return milestone_amt
|
|
|
|
return -1
|
2025-04-19 16:18:12 -06:00
|
|
|
|
|
|
|
|
2025-04-19 17:13:36 -06:00
|
|
|
func _on_milestone(milestone: Milestone) -> void:
|
|
|
|
if milestone.mp3_player:
|
|
|
|
mp3_player_unlocked = true
|
2025-06-27 12:18:47 -06:00
|
|
|
if milestone.toothbrush:
|
2025-04-19 17:13:36 -06:00
|
|
|
toothbrush_unlocked = true
|
2025-06-27 12:18:47 -06:00
|
|
|
if milestone.stickers:
|
2025-04-19 17:13:36 -06:00
|
|
|
stickers_unlocked = true
|
2025-06-27 12:18:47 -06:00
|
|
|
if milestone.big_tank:
|
2025-04-19 17:13:36 -06:00
|
|
|
grunk_tank_limit = BIG_TANK_LIMIT
|
2025-06-27 12:18:47 -06:00
|
|
|
if milestone.bonus_track:
|
|
|
|
collect_mp3(milestone.bonus_track)
|
2025-04-19 17:13:36 -06:00
|
|
|
# TODO the rest
|
|
|
|
|
|
|
|
|
2025-06-27 12:18:47 -06:00
|
|
|
## Add an MP3 player track to the player's collection.
|
|
|
|
func collect_mp3(track: MP3Track) -> void:
|
|
|
|
mp3_collection.append(track)
|
|
|
|
mp3_collected.emit(track)
|
|
|
|
|
|
|
|
|
2025-04-19 16:18:12 -06:00
|
|
|
## Called by Player on death.
|
|
|
|
func on_player_death() -> void:
|
|
|
|
player_dead.emit()
|
|
|
|
# TODO reload from save?
|
2025-04-19 20:04:54 -06:00
|
|
|
|
|
|
|
# REMOVEME
|
|
|
|
# workaround until saving & loading is implemented
|
|
|
|
grunk_tank_limit = BASE_TANK_LIMIT
|
|
|
|
grunk_tank = 0.0
|
|
|
|
grunk_vault = 0.0
|