80 lines
1.8 KiB
GDScript
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
|