ld52_olive_harvest/characters/pests/Slug.gd

129 lines
3.1 KiB
GDScript
Raw Normal View History

extends KinematicBody2D
const SPEED := 50
2023-01-09 03:29:53 +00:00
const HEAL_RATE_PER_OLIVE := 1.0
var _velocity := Vector2.ZERO
onready var _agent: NavigationAgent2D = $NavigationAgent2D
var target: Node2D = null
2023-01-09 03:29:53 +00:00
var eaten_olives: float = 0
2023-01-09 02:55:34 +00:00
var hp: float = 0
# Called when the node enters the scene tree for the first time.
func _ready():
call_deferred("_find_target")
func _find_target() -> void:
2023-01-09 02:55:34 +00:00
if eaten_olives >= 5:
# go in for the kill
target = find_parent("YSort").get_node("Player")
else:
var trees := get_tree().get_nodes_in_group("olive_trees")
var best_tree = null
var best_tree_juiciness = -1
for tree in trees:
2023-01-09 03:29:53 +00:00
var tree_distsq := self.global_position.distance_squared_to(tree.global_position)
var tree_dist := sqrt(tree_distsq)
var tree_food = tree.calculate_food(tree_dist / SPEED)
if tree_food < 0.1:
continue
var tree_juiciness = tree_food / tree_dist
2023-01-09 02:55:34 +00:00
if tree_juiciness > best_tree_juiciness:
best_tree = tree
best_tree_juiciness = tree_juiciness
target = best_tree
if target != null:
_agent.set_target_location(target.global_position)
func _at_target() -> void:
2023-01-09 03:29:53 +00:00
if target.is_in_group("olive_trees"):
_eating()
pass
2023-01-09 03:29:53 +00:00
func _eating() -> void:
var tree = target
while true:
var just_eaten = tree.eat_food()
print("ate ", just_eaten)
eaten_olives += just_eaten
hp += just_eaten
_on_eaten_olives_updated()
# TODO sfx
# TODO vfx
yield(get_tree().create_timer(2.0, false), "timeout")
if just_eaten <= 0.1:
_find_target()
return
func _physics_process(delta: float) -> void:
if target == null:
if $AnimatedSprite.animation != "still":
$AnimatedSprite.play("still")
return
var target_velocity = Vector2.ZERO
if not _agent.is_navigation_finished():
var direction_towards_travel := global_position.direction_to(_agent.get_next_location())
target_velocity = direction_towards_travel * SPEED
_velocity += (target_velocity - _velocity) * delta * 2.0
if _velocity.length_squared() > 16:
if $AnimatedSprite.animation != "crawl":
$AnimatedSprite.play("crawl")
2023-01-09 02:55:34 +00:00
if not $SlimyWalkSfx.playing:
$SlimyWalkSfx.play()
else:
if $AnimatedSprite.animation != "still":
$AnimatedSprite.play("still")
2023-01-09 02:55:34 +00:00
$SlimyWalkSfx.playing = false
#print(_velocity)
var _vel := move_and_slide(_velocity)
2023-01-09 02:55:34 +00:00
2023-01-09 03:29:53 +00:00
func _process(delta: float) -> void:
hp = min(eaten_olives, hp + eaten_olives * HEAL_RATE_PER_OLIVE * delta)
_on_hp_updated()
2023-01-09 02:55:34 +00:00
func _on_hp_updated() -> void:
if hp == eaten_olives:
self.modulate.a = 1.0
else:
self.modulate.a = clamp(sqrt(hp / eaten_olives), 0.0, 1.0)
func _on_eaten_olives_updated() -> void:
self.scale = Vector2(1, 1) * (1.0 + eaten_olives * 0.1)
var non_red := 1.0 - (0.1 * eaten_olives)
self.modulate.g = non_red
self.modulate.b = non_red
func interact(_player: Node2D) -> bool:
2023-01-09 03:29:53 +00:00
self.hp -= 1.0
2023-01-09 02:55:34 +00:00
if self.hp < 0:
# the slug is dead!
$SlimyWalkSfx.stop()
target = null
# TODO sfx
self.queue_free()
else:
self._on_hp_updated()
return true
2023-01-09 03:29:53 +00:00
func _on_NavigationAgent2D_target_reached() -> void:
var dsq := self.global_position.distance_squared_to(target.global_position)
print("reached distsq = ", dsq)
if dsq < 256:
self._at_target()