Files
Cinderwild/scripts/creatures/tutorial_wolf.gd

80 lines
1.8 KiB
GDScript

extends "res://scripts/creatures/creature.gd"
## The tutorial's wolf (docs/TUTORIAL_DESIGN.md §2, step "Wolves"): it comes
## out of the dark, circles at the edge of the light for a while, and slinks
## off. It never attacks. When it's gone, `gone` fires and the step ticks.
signal gone
const RING := 11.0
const CIRCLE_SECONDS := 18.0
const LEAVE_AFTER := 40.0 ## this far from you it's gone
var target: Node3D
var _a := 0.0
var _goal_d := 0.0
var _done := false
func begin(t: Node3D) -> void:
target = t
var away: Vector3 = global_position - t.global_position
_a = atan2(away.z, away.x)
state = "stalk"
_state_t = CIRCLE_SECONDS
func display_name() -> String:
return "Wolf"
func interact_prompt(_p: Node) -> String:
return "Wolf (watching you from the dark)"
func _pick_target() -> Node3D:
return target
func _think(dt: float) -> void:
if target == null or not is_instance_valid(target):
_leave()
return
_state_t -= dt
var tp: Vector3 = target.global_position
match state:
"stalk":
_a += dt * 0.35
_go_to(tp + Vector3(cos(_a), 0, sin(_a)) * RING)
if _state_t <= 0.0:
state = "flee"
_state_t = 15.0
"flee":
var away := global_position - tp
away.y = 0.0
steer(atan2(-away.x, -away.z))
_goal_d = 99.0
if global_position.distance_to(tp) > LEAVE_AFTER or _state_t <= 0.0:
_leave()
_:
state = "stalk"
func _go_to(p: Vector3) -> void:
var to := p - global_position
to.y = 0.0
if to.length() > 0.3:
steer(atan2(-to.x, -to.z))
_goal_d = to.length()
func _desired_speed() -> float:
match state:
"stalk": return 0.0 if _goal_d < 1.0 else (3.0 if _goal_d < 6.0 else 6.5)
"flee": return 7.5
return 0.0
func _leave() -> void:
if _done:
return
_done = true
gone.emit()
queue_free()
## (A swipe makes it run.)
func _react(_from: Vector3) -> void:
state = "flee"
_state_t = 10.0