diff --git a/characters/pests/Slug.gd b/characters/pests/Slug.gd index 65c39cb..50194a0 100644 --- a/characters/pests/Slug.gd +++ b/characters/pests/Slug.gd @@ -1,6 +1,7 @@ extends KinematicBody2D const SPEED := 50 +const HEAL_RATE_PER_OLIVE := 1.0 var _velocity := Vector2.ZERO @@ -8,7 +9,7 @@ onready var _agent: NavigationAgent2D = $NavigationAgent2D var target: Node2D = null -var eaten_olives: int = 0 +var eaten_olives: float = 0 var hp: float = 0 @@ -25,9 +26,12 @@ func _find_target() -> void: var best_tree = null var best_tree_juiciness = -1 for tree in trees: - var tree_distsq = self.global_position.distance_squared_to(tree.global_position) - var tree_food = tree.calculate_food(sqrt(tree_distsq) / SPEED) - var tree_juiciness = tree_food / tree_distsq + 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 if tree_juiciness > best_tree_juiciness: best_tree = tree @@ -39,8 +43,27 @@ func _find_target() -> void: _agent.set_target_location(target.global_position) func _at_target() -> void: - print("at target") + if target.is_in_group("olive_trees"): + _eating() pass + +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: @@ -68,6 +91,10 @@ func _physics_process(delta: float) -> void: #print(_velocity) var _vel := move_and_slide(_velocity) +func _process(delta: float) -> void: + hp = min(eaten_olives, hp + eaten_olives * HEAL_RATE_PER_OLIVE * delta) + _on_hp_updated() + func _on_hp_updated() -> void: if hp == eaten_olives: self.modulate.a = 1.0 @@ -81,7 +108,7 @@ func _on_eaten_olives_updated() -> void: self.modulate.b = non_red func interact(_player: Node2D) -> bool: - self.hp -= 1 + self.hp -= 1.0 if self.hp < 0: # the slug is dead! $SlimyWalkSfx.stop() @@ -92,3 +119,10 @@ func interact(_player: Node2D) -> bool: self._on_hp_updated() return true + + +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() diff --git a/characters/pests/Slug.tscn b/characters/pests/Slug.tscn index ef4ab97..45f8c86 100644 --- a/characters/pests/Slug.tscn +++ b/characters/pests/Slug.tscn @@ -26,7 +26,7 @@ animations = [ { radius = 6.0 height = 40.0 -[node name="Slug" type="KinematicBody2D"] +[node name="Slug" type="KinematicBody2D" groups=["interactable"]] collision_layer = 2 collision_mask = 0 script = ExtResource( 7 ) @@ -49,3 +49,5 @@ path_max_distance = 64.0 [node name="SlimyWalkSfx" type="AudioStreamPlayer2D" parent="."] stream = ExtResource( 8 ) + +[connection signal="target_reached" from="NavigationAgent2D" to="." method="_on_NavigationAgent2D_target_reached"] diff --git a/levels/Level0A.tscn b/levels/Level0A.tscn index 17103ff..8597d44 100644 --- a/levels/Level0A.tscn +++ b/levels/Level0A.tscn @@ -81,10 +81,10 @@ position = Vector2( 247, 412 ) position = Vector2( 486, 154 ) [node name="Node2D" parent="World/YSort" instance=ExtResource( 3 )] -position = Vector2( 701, 189 ) +position = Vector2( 1134, 649 ) [node name="Node2D2" parent="World/YSort" instance=ExtResource( 3 )] -position = Vector2( 135, 190 ) +position = Vector2( 574, 653 ) [node name="Node2D3" parent="World/YSort" instance=ExtResource( 4 )] position = Vector2( 542, 475 ) diff --git a/scenery/facilities/OliveTree.gd b/scenery/facilities/OliveTree.gd index 3800816..d325903 100644 --- a/scenery/facilities/OliveTree.gd +++ b/scenery/facilities/OliveTree.gd @@ -34,3 +34,28 @@ func calculate_food(in_time: float) -> float: food += child.calculate_food_on_bud(in_time) return food + +func eat_food() -> float: + if not has_been_munched: + # TODO sfx + # TODO show munched sprite... colour will do for now + $Sprite.modulate = Color(0.6, 0.4, 0.4) + has_been_munched = true + for child in self.get_children(): + # curse all buds + # TODO they will recover when next harvested, so this isn't as bad + # as it sounds.. + if child.has_method("drop_olive"): + child.grow_rate *= 0.5 + return 2.0 + + var limit = 1.0 + var eaten = 0 + for child in self.get_children(): + if child.has_method("drop_olive"): + eaten += child.eat_food_from_bud(limit - eaten) + + if limit - eaten < 0.01: + break + + return eaten diff --git a/scenery/facilities/OliveTreeBud.gd b/scenery/facilities/OliveTreeBud.gd index 5bafa16..c2ba776 100644 --- a/scenery/facilities/OliveTreeBud.gd +++ b/scenery/facilities/OliveTreeBud.gd @@ -61,3 +61,12 @@ func drop_olive(): func calculate_food_on_bud(in_time: float) -> float: return clamp(progress + in_time * grow_rate, 0.0, 1.0) + +func eat_food_from_bud(limit: float) -> float: + if limit >= progress: + var eaten = max(0.0, progress) + self.reset() + return eaten + else: + set_progress(progress - limit) + return limit