feat: add Tekton entity with movement, carry/throw mechanics, and a static controller for item throwing.

This commit is contained in:
Yogi Wiguna
2026-02-12 17:38:01 +08:00
parent 21a502a62f
commit 450ad2ce1f
4 changed files with 11 additions and 1 deletions
+2
View File
@@ -659,6 +659,8 @@ func _create_tekton(pos: Vector2i, tekton_id: int, is_static: bool = false):
# If Static, swap controller # If Static, swap controller
if is_static: if is_static:
tekton.is_static_turret = true
var old_controller = tekton.get_node_or_null("TektonController") var old_controller = tekton.get_node_or_null("TektonController")
if old_controller: if old_controller:
old_controller.queue_free() old_controller.queue_free()
+1
View File
@@ -2019,6 +2019,7 @@ func _find_nearby_tekton() -> Node3D: # Find closest Tekton
for t in tektons: for t in tektons:
if t.is_carried: continue if t.is_carried: continue
if t.get("is_recovering"): continue # Cannot grab recovering/shrunk Tekton if t.get("is_recovering"): continue # Cannot grab recovering/shrunk Tekton
if t.get("is_static_turret"): continue # Cannot grab/knock static turret
# Check adjacency (or same tile) # Check adjacency (or same tile)
# Assuming is_adjacent_or_same is a helper function that checks if two Vector2i are adjacent or the same. # Assuming is_adjacent_or_same is a helper function that checks if two Vector2i are adjacent or the same.
+1 -1
View File
@@ -2,7 +2,7 @@ extends Node
@export var throw_interval_min: float = 2.0 @export var throw_interval_min: float = 2.0
@export var throw_interval_max: float = 4.0 @export var throw_interval_max: float = 4.0
@export var throw_range: int = 6 @export var throw_range: int = 3
var tekton: Node3D var tekton: Node3D
var enhanced_gridmap: Node var enhanced_gridmap: Node
+7
View File
@@ -8,6 +8,7 @@ signal movement_finished
@export var current_position: Vector2i = Vector2i(0, 0) @export var current_position: Vector2i = Vector2i(0, 0)
@export var health: int = 3 @export var health: int = 3
@export var movement_speed: float = 2.0 # Seconds per step (Slower walk) @export var movement_speed: float = 2.0 # Seconds per step (Slower walk)
@export var is_static_turret: bool = false # If true, cannot be grabbed, thrown, or knocked
var enhanced_gridmap: Node var enhanced_gridmap: Node
var is_moving: bool = false var is_moving: bool = false
@@ -87,6 +88,8 @@ func sync_movement(target_pos: Vector2i):
func on_hit(attacker: Node = null, intensity: float = 1.0): func on_hit(attacker: Node = null, intensity: float = 1.0):
"""Called when hit by a player attack or knock. """Called when hit by a player attack or knock.
Intensity: 0.5 for throw, 1.0+ for knock.""" Intensity: 0.5 for throw, 1.0+ for knock."""
if is_static_turret: return
print("[Tekton] Hit by %s! Intensity: %.1f" % [attacker.name if attacker else "Unknown", intensity]) print("[Tekton] Hit by %s! Intensity: %.1f" % [attacker.name if attacker else "Unknown", intensity])
# Visual Reaction (Flash red) # Visual Reaction (Flash red)
@@ -99,6 +102,8 @@ func on_hit(attacker: Node = null, intensity: float = 1.0):
@rpc("any_peer", "call_local") @rpc("any_peer", "call_local")
func set_carried(state: bool, p_carrier: Node3D = null): func set_carried(state: bool, p_carrier: Node3D = null):
if is_static_turret: return
is_carried = state is_carried = state
carrier = p_carrier carrier = p_carrier
@@ -123,6 +128,8 @@ func set_carried(state: bool, p_carrier: Node3D = null):
@rpc("any_peer", "call_local") @rpc("any_peer", "call_local")
func set_thrown(state: bool): func set_thrown(state: bool):
if is_static_turret: return
is_thrown = state is_thrown = state
if is_thrown: if is_thrown: