Files
tekton/scripts/static_tekton_controller.gd
T
adtpdn 5354d8b30f freemode fishing tekton autoplay + static tekton throw fix
- Added tekton_fishing_autoplay.gd: plays both GLB animations simultaneously, looped
- Attached autoplay script to 3 fishing tekton instances in freemode.tscn
- Fixed static tekton throw: faces throw direction + plays throw animation
- Fixed AnimationPlayer path in tekton.gd for static turrets
- Fixed animation names (tekton_throw_tile -> ted_bones_001|Tekton Throwing Tiles|Anima_Layer)
- Fixed static_tekton_controller.gd idle resume
- Rebuilt animation-pack.res with new animations (holding_1, put_1, stun_1, etc.)
- Fixed GutBottomPanel.tscn broken UID
2026-06-15 18:15:39 +08:00

127 lines
4.2 KiB
GDScript

extends Node
@export var throw_interval: float = 2.0
@export var throw_range: int = 3
var tekton: Node3D
var enhanced_gridmap: Node
var timer: Timer
func _ready():
tekton = get_parent()
if not tekton:
set_physics_process(false)
return
# Wait for gridmap
await get_tree().process_frame
var main = tekton.get_tree().get_root().get_node_or_null("Main")
if main:
enhanced_gridmap = main.get_node_or_null("EnhancedGridMap")
# Initial State
# No idle anim for static tekton mesh, just ensure stopped
var ap = tekton.get_node_or_null("Visuals/tekton/AnimationPlayer")
if ap: ap.stop()
# Setup Timer
timer = Timer.new()
timer.one_shot = true
timer.timeout.connect(_on_timer_timeout)
add_child(timer)
_start_timer()
func _start_timer():
timer.wait_time = throw_interval
timer.start()
func _on_timer_timeout():
if not multiplayer.has_multiplayer_peer(): return
if not is_multiplayer_authority(): return
if not tekton or not enhanced_gridmap: return
if tekton.get("is_carried") or tekton.get("is_thrown"):
_start_timer()
return
# print("[StaticTekton] Timer timeout. Attempting throw...")
_attempt_throw()
func _attempt_throw():
# Find target
var target = _find_empty_tile()
if target == Vector2i(-1, -1):
# print("[StaticTekton] No valid target found.")
_start_timer()
return
# print("[StaticTekton] Target found: %s" % target)
# Execute Throw
# 1. Face target
var target_world_pos = Vector3(target.x + 0.5, 0, target.y + 0.5)
if enhanced_gridmap and "cell_size" in enhanced_gridmap:
target_world_pos = Vector3(
target.x * enhanced_gridmap.cell_size.x + enhanced_gridmap.cell_size.x / 2,
enhanced_gridmap.cell_size.y,
target.y * enhanced_gridmap.cell_size.z + enhanced_gridmap.cell_size.z / 2
)
tekton.look_at(Vector3(target_world_pos.x, tekton.global_position.y, target_world_pos.z), Vector3.UP)
# 2. Play Animation
if tekton.has_method("play_animation_rpc") and tekton.has_method("can_rpc") and tekton.can_rpc():
tekton.rpc("play_animation_rpc", "ted_bones_001|Tekton Throwing Tiles|Anima_Layer")
# 3. Create Projectile Visual (Synced)
if tekton.has_method("spawn_projectile_rpc") and tekton.has_method("can_rpc") and tekton.can_rpc():
tekton.rpc("spawn_projectile_rpc", target_world_pos, 0.5)
# 4. Impact / Spawn
await get_tree().create_timer(0.5).timeout
var main = tekton.get_tree().get_root().get_node_or_null("Main")
if main and tekton.has_method("can_rpc") and tekton.can_rpc():
# Spawn Item (Random ID 7-10)
var item_id = randi_range(7, 10)
main.rpc("sync_grid_item", target.x, 1, target.y, item_id)
# 5. Resume Idle
await get_tree().create_timer(0.5).timeout # Small delay after throw
# No idle anim for static tekton mesh, just stop
if tekton.has_method("can_rpc") and tekton.can_rpc():
# Stop animation on all peers via a direct call (AnimationPlayer.stop is visual-only, safe)
var ap = tekton.get_node_or_null("Visuals/tekton/AnimationPlayer")
if ap: ap.stop()
_start_timer()
func _find_empty_tile() -> Vector2i:
if not enhanced_gridmap or not "rows" in enhanced_gridmap: return Vector2i(-1, -1)
var center = Vector2i(tekton.global_position.x, tekton.global_position.z) # Approx grid pos
# Better: use tekton.current_position if available
if "current_position" in tekton:
center = tekton.current_position
var candidates = []
for x in range(center.x - throw_range, center.x + throw_range + 1):
for y in range(center.y - throw_range, center.y + throw_range + 1):
if x < 0 or y < 0 or x >= enhanced_gridmap.columns or y >= enhanced_gridmap.rows: continue
# Check range logic (Euclidean or Manhattan?)
if Vector2(x, y).distance_to(Vector2(center.x, center.y)) > throw_range: continue
# EXPLICITLY EXCLUDE 3x3 BASE AREA (Tekton Stand)
# The stand occupies [center-1, center+1]. We must NOT spawn here.
if abs(x - center.x) <= 1 and abs(y - center.y) <= 1:
continue
# Check if empty (Layer 1 has no item)
if enhanced_gridmap.get_cell_item(Vector3i(x, 1, y)) == -1:
# Also check floor exist? (Layer 0)
if enhanced_gridmap.get_cell_item(Vector3i(x, 0, y)) != -1:
candidates.append(Vector2i(x, y))
if candidates.is_empty(): return Vector2i(-1, -1)
return candidates.pick_random()