grunk/src/world/spook_manager/spook_manager.gd

91 lines
2.5 KiB
GDScript3
Raw Normal View History

2025-04-10 18:29:00 -06:00
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
2025-04-10 18:29:00 -06:00
var debug_set_alert_level: int:
set = on_alert_raised
2025-04-10 18:29:00 -06:00
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
2025-04-18 09:53:21 -06:00
@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:
2025-04-10 18:29:00 -06:00
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:
2025-04-22 12:08:09 -06:00
var closest := (
SceneTools.closest_in_group(Player.instance, MeetSpook.GROUP) as MeetSpook
)
if closest:
closest.prepare()
2025-04-10 18:29:00 -06:00
2:
# LEVEL 2: AGGRESSIVE
# Beast pursues player on sight.
spawn_beast()
2025-04-10 18:29:00 -06:00
3:
# LEVEL 3: PREDATORY
# Beast pursues player relentlessly.
# The logic for this behavior change is handled directly in the GrunkBeast AI.
pass
2025-04-10 18:29:00 -06:00
4:
# LEVEL 4: SWARMING
# Many beasts spawn, overwhelming the player.
spawn_many_beasts()
2025-04-10 18:29:00 -06:00
5:
# LEVEL 5: FUN
# Just kill that fool!
pass # TODO
func on_alert_cleared() -> void:
# Destroy all but one grunk beasts
var beasts := World.instance.get_tree().get_nodes_in_group(BEAST_GROUP)
if not beasts:
return
@warning_ignore("unsafe_cast")
var survivor := beasts.pick_random() as GrunkBeast
for beast: Node in beasts:
if beast != survivor:
beast.queue_free()
survivor.clear_aggro()