feat: introduce core player logic with manager integration and power-up inventory UI.
This commit is contained in:
@@ -24,6 +24,7 @@ func initialize(p_player: Node3D, p_gridmap: Node):
|
||||
signal movement_finished
|
||||
var movement_queue: Array[Vector2i] = [] # Queue of target grid positions
|
||||
var current_move_direction: Vector2i = Vector2i.ZERO
|
||||
var last_move_direction: Vector2i = Vector2i(0, 1) # Default forward (towards +Z)
|
||||
|
||||
func _process(delta):
|
||||
if player:
|
||||
@@ -137,6 +138,8 @@ func simple_move_to(grid_position: Vector2i) -> bool:
|
||||
path.pop_front()
|
||||
|
||||
current_move_direction = grid_position - player.current_position
|
||||
if current_move_direction != Vector2i.ZERO:
|
||||
last_move_direction = current_move_direction
|
||||
|
||||
if player.is_multiplayer_authority():
|
||||
# Authority starts their own tween locally
|
||||
@@ -174,54 +177,39 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
||||
NotificationManager.send_message(player, "Cannot Attack in Safe Zone!", NotificationManager.MessageType.WARNING)
|
||||
return false
|
||||
|
||||
# 1. Drop Victim's Tiles
|
||||
if other_player.has_method("drop_all_tiles"):
|
||||
if _can_rpc():
|
||||
other_player.rpc("drop_all_tiles") # Sync drop
|
||||
# 1. 3-Floor Knockback towards Starting Line (X=0)
|
||||
var push_direction = Vector2i(-1, 0) # Backwards
|
||||
var pushed_to_pos = target_pos
|
||||
var push_path = []
|
||||
|
||||
# 2. Spawn PowerUps around Victim
|
||||
# We delegate this to the attacker's SpecialTilesManager to handle the spawning authority
|
||||
if player.special_tiles_manager and player.special_tiles_manager.has_method("spawn_powerups_around"):
|
||||
player.special_tiles_manager.spawn_powerups_around(other_player.current_position)
|
||||
|
||||
# 3. Knockback / Stagger
|
||||
# Push them away
|
||||
var pushed_to_pos = target_pos + direction
|
||||
|
||||
# IMPROVED: Check if destination is valid and walkable to prevent being stuck on 'blocks'
|
||||
var is_dest_valid = _can_push_to(pushed_to_pos)
|
||||
|
||||
# DEFLECTION LOGIC: If direct path is blocked, try diagonal deflection
|
||||
if not is_dest_valid:
|
||||
var alts = []
|
||||
if direction.x != 0 and direction.y == 0: # Horizontal push -> try diagonal North/South
|
||||
alts = [pushed_to_pos + Vector2i(0, 1), pushed_to_pos + Vector2i(0, -1)]
|
||||
elif direction.y != 0 and direction.x == 0: # Vertical push -> try diagonal East/West
|
||||
alts = [pushed_to_pos + Vector2i(1, 0), pushed_to_pos + Vector2i(-1, 0)]
|
||||
elif direction.x != 0 and direction.y != 0: # Diagonal push -> try horizontal/vertical components
|
||||
alts = [pushed_to_pos - Vector2i(direction.x, 0), pushed_to_pos - Vector2i(0, direction.y)]
|
||||
# Try to push up to 3 tiles back, building the path as we go
|
||||
for i in range(3):
|
||||
var next_back = pushed_to_pos + push_direction
|
||||
if _can_push_to(next_back):
|
||||
pushed_to_pos = next_back
|
||||
push_path.append(Vector2(pushed_to_pos.x, pushed_to_pos.y))
|
||||
else:
|
||||
break # Blocked by wall or edge
|
||||
|
||||
for alt in alts:
|
||||
if _can_push_to(alt):
|
||||
pushed_to_pos = alt
|
||||
is_dest_valid = true
|
||||
break
|
||||
|
||||
if is_dest_valid:
|
||||
# Valid push
|
||||
var push_path = [Vector2(pushed_to_pos.x, pushed_to_pos.y)]
|
||||
if push_path.size() > 0:
|
||||
# Valid push movement
|
||||
if _can_rpc():
|
||||
other_player.rpc("start_movement_along_path", push_path, false)
|
||||
# Pass 'true' for 'force' parameter to interrupt active movements
|
||||
other_player.rpc("start_movement_along_path", push_path, false, true)
|
||||
|
||||
# Authority Check: If we are already the authority for the victim (e.g. Host hitting a Bot),
|
||||
# the 'call_remote' RPC above won't execute locally. We MUST call it manually.
|
||||
if other_player.is_multiplayer_authority():
|
||||
other_player.start_movement_along_path(push_path, false, true)
|
||||
|
||||
other_player.target_position = pushed_to_pos # Logical update
|
||||
|
||||
# Apply stun/freeze effect as requested (same as wall stagger)
|
||||
if _can_rpc():
|
||||
other_player.rpc("apply_stagger", 1.5)
|
||||
|
||||
# 2. Apply freeze/stun effect (blue tint)
|
||||
if _can_rpc():
|
||||
other_player.rpc("apply_stagger", 1.5)
|
||||
else:
|
||||
# Wall/Blocked -> Stagger in place (Only if no alternatives found)
|
||||
if _can_rpc():
|
||||
other_player.rpc("apply_stagger", 1.5)
|
||||
# Handle local execution (e.g. offline or host-only logic)
|
||||
other_player.apply_stagger(1.5)
|
||||
|
||||
# 4. Consume Boost (Full) - One hit per charge
|
||||
if player.powerup_manager:
|
||||
@@ -246,12 +234,8 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
||||
else:
|
||||
NotificationManager.send_message(player, "Successful Attack!", NotificationManager.MessageType.GOAL)
|
||||
|
||||
# 5. Attack Mode Persistence
|
||||
# logic moved to consume_boost: checks if <= 0 then disables.
|
||||
# So we do NOT force disable here.
|
||||
# player.is_attack_mode = false
|
||||
|
||||
return true
|
||||
# 5. Block the attacker from moving into the victim's space to prevent overlapping
|
||||
return false
|
||||
|
||||
func set_speed_multiplier(multiplier: float):
|
||||
speed_multiplier = multiplier
|
||||
|
||||
Reference in New Issue
Block a user