extends Node # TektonController - AI for Tekton NPC # Handles random movement logic. @export var move_interval_min: float = 0.1 @export var move_interval_max: float = 0.1 var tekton: Node3D var enhanced_gridmap: Node var timer: Timer var rng = RandomNumberGenerator.new() func _ready(): if not is_multiplayer_authority(): set_process(false) return # Only server/authority runs AI tekton = get_parent() # Wait for tekton to be ready and have gridmap await get_tree().create_timer(1.0).timeout enhanced_gridmap = tekton.enhanced_gridmap rng.randomize() # Setup Timer timer = Timer.new() add_child(timer) timer.one_shot = true timer.timeout.connect(_on_timer_timeout) _start_timer() func _start_timer(): var time = rng.randf_range(move_interval_min, move_interval_max) timer.start(time) func _on_timer_timeout(): if not is_instance_valid(tekton) or not is_instance_valid(enhanced_gridmap): return _attempt_move() _start_timer() func _attempt_move(): if tekton.is_moving: return var neighbors = enhanced_gridmap.get_neighbors(tekton.current_position, 0) var valid_moves = [] for n in neighbors: if n.is_walkable: if _is_occupied(n.position): continue valid_moves.append(n.position) if valid_moves.size() > 0: var target = valid_moves[rng.randi() % valid_moves.size()] tekton.move_to(target) func _is_occupied(pos: Vector2i) -> bool: var players = get_tree().get_nodes_in_group("Players") for p in players: if p.current_position == pos: return true # Also check other Tektons? var tektons = get_tree().get_nodes_in_group("Tektons") for t in tektons: if t != tekton and t.current_position == pos: return true return false