48 lines
1.3 KiB
GDScript
48 lines
1.3 KiB
GDScript
extends Node3D
|
|
## Where a band of the drowned crew rose (treasure.gd): what their guard
|
|
## brains (guard.gd) ask of their "barrow". They're up and angry from the
|
|
## start, chase whoever's nearest within LEASH of the dig, and go back to
|
|
## stand round it when nobody is. By day, once nobody's been near for a
|
|
## while, they sink back into the ground.
|
|
|
|
const LEASH := 20.0
|
|
const SINK_AFTER := 30.0 ## seconds with nobody near, by day
|
|
|
|
var world: Node3D
|
|
var spot := Vector3.ZERO
|
|
var alarmed := true
|
|
var crew: Array = []
|
|
var _alone := 0.0
|
|
|
|
func center() -> Vector3:
|
|
return spot
|
|
|
|
func wakes_for(p: Node3D) -> bool:
|
|
return alarmed and not p.survival.dead
|
|
|
|
func alarm() -> void:
|
|
alarmed = true
|
|
|
|
## (Out in the open: they walk on the ground.)
|
|
func floor_y_at(_p: Vector3) -> float:
|
|
return -INF
|
|
|
|
func is_night() -> bool:
|
|
var h: float = world.day_night.hours()
|
|
return h >= 19.5 or h < 5.5
|
|
|
|
func alive() -> Array:
|
|
return crew.filter(func(g): return is_instance_valid(g) and not g.is_dead())
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
var anyone := false
|
|
for p in world.players():
|
|
if not p.survival.dead and p.global_position.distance_to(spot) < LEASH:
|
|
anyone = true
|
|
_alone = 0.0 if anyone or is_night() else _alone + delta
|
|
if alive().is_empty() or _alone > SINK_AFTER:
|
|
for g in crew:
|
|
if is_instance_valid(g) and not g.is_dead():
|
|
g.queue_free()
|
|
queue_free()
|