feat: Implement core player character logic, including state management, network synchronization, character selection, and manager initialization.
This commit is contained in:
@@ -34,6 +34,9 @@ func grab_item(grid_position: Vector2i) -> bool:
|
||||
if not enhanced_gridmap or not has_ap:
|
||||
return false
|
||||
|
||||
if player.get("is_frozen"):
|
||||
return false
|
||||
|
||||
var cell = Vector3i(grid_position.x, 1, grid_position.y)
|
||||
var item = enhanced_gridmap.get_cell_item(cell)
|
||||
|
||||
@@ -319,7 +322,7 @@ func auto_put_item() -> bool:
|
||||
# Check AP only if in turn-based mode
|
||||
var has_ap = player.action_points > 0 if TurnManager.turn_based_mode else true
|
||||
|
||||
if not enhanced_gridmap or not has_ap or player.is_bot or player.is_in_group("Bots"):
|
||||
if not enhanced_gridmap or not has_ap or player.is_bot or player.is_in_group("Bots") or player.get("is_frozen"):
|
||||
return false
|
||||
|
||||
# Step 1: Find empty adjacent (or current) grid cells
|
||||
|
||||
+106
-7
@@ -120,15 +120,114 @@ func _process(delta):
|
||||
global_position = carrier.global_position + Vector3(0, 1.5, 0)
|
||||
rotation = carrier.rotation
|
||||
|
||||
func _flash_damage():
|
||||
var mesh_cache: Array[MeshInstance3D] = []
|
||||
var original_scales: Array[Vector3] = []
|
||||
|
||||
func _ready():
|
||||
# Cache meshes and their initial scales
|
||||
# We wait a frame to ensure all children are ready and transforms applied
|
||||
await get_tree().process_frame
|
||||
var meshes = find_children("*", "MeshInstance3D", true)
|
||||
for mesh in meshes:
|
||||
var original_modulate = mesh.transparency
|
||||
# Quick flash hack or shader param?
|
||||
# If standard material, maybe just modulate visibility or scale
|
||||
var t = create_tween()
|
||||
t.tween_property(mesh, "scale", Vector3(1.2, 1.2, 1.2), 0.1)
|
||||
t.tween_property(mesh, "scale", Vector3(1.0, 1.0, 1.0), 0.1)
|
||||
mesh_cache.append(mesh)
|
||||
original_scales.append(mesh.scale)
|
||||
|
||||
func _flash_damage():
|
||||
# If cache empty (e.g. called before ready), try to populate or just skip custom scaling
|
||||
if mesh_cache.is_empty():
|
||||
return
|
||||
|
||||
for i in range(mesh_cache.size()):
|
||||
var mesh = mesh_cache[i]
|
||||
if is_instance_valid(mesh):
|
||||
var base_scale = original_scales[i]
|
||||
var t = create_tween()
|
||||
t.tween_property(mesh, "scale", base_scale * 1.2, 0.1)
|
||||
t.tween_property(mesh, "scale", base_scale, 0.1)
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func on_thrown_landing(attacker: Node = null):
|
||||
"""Called when Tekton lands after being thrown."""
|
||||
print("[Tekton] Landed! Shrinking and waiting...")
|
||||
|
||||
# Disable movement/interaction logic temporarily
|
||||
var controller = get_node_or_null("TektonController")
|
||||
if controller and controller.get("timer"):
|
||||
controller.timer.stop()
|
||||
|
||||
# Visual Shrink
|
||||
# Use cached meshes if available, else find them (but can't restore accurately if not cached)
|
||||
if mesh_cache.is_empty():
|
||||
# Fallback if _ready hasn't run or failed
|
||||
# We'll just define the user's specific vector as fallback target for the sphere
|
||||
# But better to rely on cache.
|
||||
pass
|
||||
|
||||
for i in range(mesh_cache.size()):
|
||||
var mesh = mesh_cache[i]
|
||||
if is_instance_valid(mesh):
|
||||
var base_scale = original_scales[i]
|
||||
var t = create_tween()
|
||||
t.tween_property(mesh, "scale", base_scale * 0.5, 0.2).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
|
||||
|
||||
# Wait 1 seconds
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
|
||||
# Grow back
|
||||
for i in range(mesh_cache.size()):
|
||||
var mesh = mesh_cache[i]
|
||||
if is_instance_valid(mesh):
|
||||
var base_scale = original_scales[i]
|
||||
var t = create_tween()
|
||||
t.tween_property(mesh, "scale", base_scale, 0.2).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
|
||||
|
||||
# Resume AI
|
||||
if controller and controller.has_method("_start_timer"):
|
||||
if is_multiplayer_authority() and not is_carried:
|
||||
controller._start_timer()
|
||||
|
||||
# Spawn tiles (as requested "tekton will spawn a tiles around that floor also")
|
||||
if is_multiplayer_authority():
|
||||
spawn_tiles_around(8) # Standard amount
|
||||
|
||||
# Floor Freeze (Visual/Instant - Run on all clients locally)
|
||||
_temporarily_change_floor(current_position, 1, 6, 3.0)
|
||||
|
||||
func _temporarily_change_floor(center: Vector2i, radius: int, new_id: int, duration: float):
|
||||
if not enhanced_gridmap: return
|
||||
|
||||
# Run locally on all clients to ensure instant feedback without network delay
|
||||
var changed_cells = {} # pos: original_id
|
||||
|
||||
for x in range(-radius, radius + 1):
|
||||
for y in range(-radius, radius + 1):
|
||||
var pos = center + Vector2i(x, y)
|
||||
if enhanced_gridmap.is_position_valid(pos):
|
||||
var cell_3d = Vector3i(pos.x, 0, pos.y)
|
||||
var original = enhanced_gridmap.get_cell_item(cell_3d)
|
||||
|
||||
# Only change if not already the new ID (avoid redundant updates or overriding existing freeze)
|
||||
if original != new_id:
|
||||
changed_cells[pos] = original
|
||||
# Set locally immediately
|
||||
enhanced_gridmap.set_cell_item(cell_3d, new_id)
|
||||
|
||||
await get_tree().create_timer(duration).timeout
|
||||
|
||||
# Restore locally
|
||||
for pos in changed_cells:
|
||||
var original = changed_cells[pos]
|
||||
var current_cell = Vector3i(pos.x, 0, pos.y)
|
||||
var current = enhanced_gridmap.get_cell_item(current_cell)
|
||||
|
||||
# Only restore if it hasn't been changed to something else in meantime
|
||||
if current == new_id:
|
||||
enhanced_gridmap.set_cell_item(current_cell, original)
|
||||
|
||||
# Stun nearby players handled by Thrower (Player.gd) or here?
|
||||
# Player.gd handles the stun call because it knows the impact zone context better?
|
||||
# Actually, Player.gd calls this function. Player.gd *also* iterates players to stun them.
|
||||
# That is fine.
|
||||
|
||||
func spawn_tiles_around(count: int = 4):
|
||||
"""Spawns a mix of normal and special tiles in a radius."""
|
||||
|
||||
Reference in New Issue
Block a user