grunk/src/world/spook_manager/spook_manager.gd

91 lines
2.5 KiB
GDScript

class_name SpookManager extends Resource
## A strategy for handling horror elements through the level.
const SPAWN_GROUP := "BeastSpawnPoint"
const BEAST_GROUP := "GrunkBeast"
@export var grunkbeast_scene: PackedScene
var debug_set_alert_level: int:
set = on_alert_raised
func _spawn_beast_at_point(spawn_point: Node3D) -> void:
print_debug("Spawning active beast at ", spawn_point.global_position)
var beast: GrunkBeast = grunkbeast_scene.instantiate()
spawn_point.add_child(beast)
## Spawn a beast somewhere the player isn't looking.
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 := 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
@warning_ignore("unsafe_cast")
spawn_point = nodes.pick_random() as Node3D
_spawn_beast_at_point(spawn_point)
## Spawn beasts at _every_ spawn point the player can't see.
func spawn_many_beasts() -> void:
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:
match new_level:
0:
# LEVEL 0: UNAWARE
pass
1:
# LEVEL 1: PASSIVE
# Beast avoids the player.
# Set up meet-spook.
# Get closest MeetSpook point to player.
if Player.instance:
var closest := (
SceneTools.closest_in_group(Player.instance, MeetSpook.GROUP) as MeetSpook
)
if closest:
closest.prepare()
2:
# LEVEL 2: AGGRESSIVE
# Beast pursues player on sight.
spawn_beast()
3:
# LEVEL 3: PREDATORY
# Beast pursues player relentlessly.
# The logic for this behavior change is handled directly in the GrunkBeast AI.
pass
4:
# LEVEL 4: SWARMING
# Many beasts spawn, overwhelming the player.
spawn_many_beasts()
5:
# LEVEL 5: FUN
# Just kill that fool!
pass # TODO
func on_alert_cleared() -> void:
# Destroy all grunk beasts
for b: Node in World.instance.get_tree().get_nodes_in_group(BEAST_GROUP):
b.queue_free()
# And spawn one back in, if needed
if World.instance.manager.alert_level >= 2:
spawn_beast()
## Set the state of spooky effects after a level is initialized & any save state is loaded.
func after_level_init() -> void:
on_alert_cleared()