feat: Implement core player character logic including movement, state management, and network synchronization, and add a new special tiles manager.

This commit is contained in:
Yogi Wiguna
2026-03-25 16:47:48 +08:00
parent 0a8e2b9702
commit 21dcaf72f8
2 changed files with 21 additions and 21 deletions
+20 -20
View File
@@ -53,6 +53,11 @@ var is_invisible: bool = false:
if is_invisible == value: return if is_invisible == value: return
is_invisible = value is_invisible = value
_refresh_player_visuals() _refresh_player_visuals()
var is_slowed: bool = false:
set(value):
if is_slowed == value: return
is_slowed = value
_refresh_player_visuals()
var original_movement_range: int = 1 var original_movement_range: int = 1
# Tekton Interaction # Tekton Interaction
@@ -692,6 +697,8 @@ func _refresh_player_visuals():
color_to_apply = Color.BLUE # Frozen (Staggered) color_to_apply = Color.BLUE # Frozen (Staggered)
elif is_stop_frozen: elif is_stop_frozen:
color_to_apply = Color.CYAN # Stop n Go Freeze color_to_apply = Color.CYAN # Stop n Go Freeze
elif is_slowed:
color_to_apply = Color(0.6, 0.8, 1.0) # Slowed / Icy Blue
elif is_attack_mode: elif is_attack_mode:
color_to_apply = Color(1.0, 0.5, 0.5) # Attack Mode (Red Tint) color_to_apply = Color(1.0, 0.5, 0.5) # Attack Mode (Red Tint)
elif is_carrying_tekton or is_knock_mode: elif is_carrying_tekton or is_knock_mode:
@@ -742,6 +749,7 @@ func _apply_tint_recursive(node: Node, color: Color, alpha: float = 1.0):
_apply_tint_recursive(child, color, alpha) _apply_tint_recursive(child, color, alpha)
var immunity_timer: float = 0.0 var immunity_timer: float = 0.0
var slow_timer: float = 0.0
var tekton_carry_timer: float = 0.0 var tekton_carry_timer: float = 0.0
const MAX_TEKTON_CARRY_TIME: float = 3.0 const MAX_TEKTON_CARRY_TIME: float = 3.0
@@ -805,9 +813,9 @@ func sync_stop_freeze(enabled: bool):
@rpc("any_peer", "call_local") @rpc("any_peer", "call_local")
func apply_slow_effect(duration: float = 3.0): func apply_slow_effect(duration: float = 3.0):
# "area with blue like wall... Player who cross on that area will got slowed and freeze effect" # Update the timer (extend if already slowed)
# Visual: Blue Tint slow_timer = max(slow_timer, duration)
_apply_tint_recursive(self , Color(0.6, 0.8, 1.0)) # Icy Blue self.is_slowed = true
# Logic: Slow Movement speed # Logic: Slow Movement speed
if movement_manager: if movement_manager:
@@ -816,23 +824,6 @@ func apply_slow_effect(duration: float = 3.0):
print("Player %s is slowed for %.1f seconds" % [name, duration]) print("Player %s is slowed for %.1f seconds" % [name, duration])
# Restore after duration
# Note: If they stand in the zone, this will be re-applied constantly, resetting the visual
# A better way is managing a "slow_timer" but for now let's just reset if timer expires.
# The persistent zone logic reapplies every frame, so we want this timer to be short
# OR we rely on the zone logic.
# The RPC call says "apply_slow_effect(0.5)", so it expires quickly.
await get_tree().create_timer(duration).timeout
if movement_manager:
movement_manager.set_speed_multiplier(1.0)
if immunity_timer > 0:
_apply_tint_recursive(self , Color(0.5, 1.0, 0.5))
else:
_apply_tint_recursive(self , Color.WHITE)
func playerboard_is_empty() -> bool: func playerboard_is_empty() -> bool:
for item in playerboard: for item in playerboard:
if item != -1: if item != -1:
@@ -1098,6 +1089,15 @@ func _process(delta):
immunity_timer = 0 immunity_timer = 0
_apply_tint_recursive(self , Color.WHITE) # Remove immunity tint _apply_tint_recursive(self , Color.WHITE) # Remove immunity tint
# Slow Timer Logic
if slow_timer > 0:
slow_timer -= delta
if slow_timer <= 0:
slow_timer = 0.0
self.is_slowed = false
if movement_manager:
movement_manager.set_speed_multiplier(1.0)
func _process_remote_interpolation(_delta): func _process_remote_interpolation(_delta):
if snapshot_buffer.size() < 2: if snapshot_buffer.size() < 2:
# Fallback to simple lerp if not enough snapshots # Fallback to simple lerp if not enough snapshots
+1 -1
View File
@@ -379,7 +379,7 @@ func _execute_area_freeze(target_pos: Vector2i = Vector2i(-9999, -9999)):
# If inside square radius # If inside square radius
if dx <= radius and dy <= radius: if dx <= radius and dy <= radius:
if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED: if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED:
p.rpc("apply_slow_effect", FREEZE_SLOW_DURATION) p.rpc("apply_slow_effect", 0.5)
NotificationManager.send_message(p, "Caught in Freeze Zone!", NotificationManager.MessageType.WARNING) NotificationManager.send_message(p, "Caught in Freeze Zone!", NotificationManager.MessageType.WARNING)
if p != player: # Don't score for freezing self (unless desired?) - Assuming enemies if p != player: # Don't score for freezing self (unless desired?) - Assuming enemies
hit_count += 1 hit_count += 1