feat: Introduce PlayerMovementManager to centralize grid-based player and bot movement, including multiplayer synchronization and push interactions.
This commit is contained in:
@@ -282,7 +282,35 @@ func _try_attack_chase() -> bool:
|
||||
# No victim found? Just behave normally (grab tiles etc)
|
||||
return false
|
||||
|
||||
# Pathfind to victim
|
||||
# 1. Adjacency Check: If already touching or on same tile, attack directly!
|
||||
var dist_manhattan = abs(victim.current_position.x - actor.current_position.x) + abs(victim.current_position.y - actor.current_position.y)
|
||||
if dist_manhattan <= 1:
|
||||
print("[BotController] %s is close to %s (Dist: %d). Attacking!" % [actor.name, victim.name, dist_manhattan])
|
||||
|
||||
var push_dir = victim.current_position - actor.current_position
|
||||
if push_dir == Vector2i.ZERO:
|
||||
# If overlapping, use actor's last move direction or fallback
|
||||
push_dir = actor.movement_manager.last_move_direction if actor.movement_manager else Vector2i(1, 0)
|
||||
|
||||
# Trigger push logic directly
|
||||
var push_success = actor.movement_manager.try_push(victim.current_position, push_dir)
|
||||
|
||||
if not push_success:
|
||||
# If attack failed (e.g. Safe Zone in Stop n Go), don't just loop!
|
||||
if LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO):
|
||||
if victim.current_position.x in [6, 7, 8, 14, 15, 16]: # Safe Zone Columns
|
||||
print("[BotController] %s target is in Safe Zone. Moving to find better angle." % actor.name)
|
||||
await _try_unstuck_move()
|
||||
|
||||
_is_processing_action = true
|
||||
_current_action = "attacking"
|
||||
await _wait_with_variance(action_delay)
|
||||
if not is_instance_valid(self) or not is_instance_valid(actor): return true
|
||||
_is_processing_action = false
|
||||
_current_action = "idle"
|
||||
return true
|
||||
|
||||
# 2. Pathfind to victim if not adjacent
|
||||
var path = enhanced_gridmap.find_path(
|
||||
Vector2(actor.current_position),
|
||||
Vector2(victim.current_position),
|
||||
@@ -305,15 +333,28 @@ func _try_attack_chase() -> bool:
|
||||
# print("[BotController] %s attack blocked by boundary (Not late game yet)." % actor.name)
|
||||
return false
|
||||
|
||||
# Move to next step (If occupied by victim, movement_manager will trigger PUSH)
|
||||
# Move to next step
|
||||
# note: simple_move_to will call try_push if next_step is occupied
|
||||
if actor.movement_manager.simple_move_to(next_step):
|
||||
_is_processing_action = true
|
||||
_current_action = "attacking"
|
||||
await _wait_with_variance(action_delay) # Shorter delay for attacks? perhaos
|
||||
await _wait_with_variance(action_delay)
|
||||
if not is_instance_valid(self) or not is_instance_valid(actor): return true
|
||||
_is_processing_action = false
|
||||
_current_action = "idle"
|
||||
return true
|
||||
else:
|
||||
# If move failed, it might be because simple_move_to called try_push and returned false
|
||||
# We check if the target is occupied. If it is, and we are in attack mode,
|
||||
# we assume an attack attempt was made.
|
||||
if actor.is_position_occupied(next_step):
|
||||
_is_processing_action = true
|
||||
_current_action = "attacking"
|
||||
await _wait_with_variance(action_delay)
|
||||
if not is_instance_valid(self) or not is_instance_valid(actor): return true
|
||||
_is_processing_action = false
|
||||
_current_action = "idle"
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
@@ -450,7 +491,15 @@ func _try_move() -> bool:
|
||||
var unstuck = await _try_unstuck_move()
|
||||
return unstuck
|
||||
|
||||
# Execute SINGLE STEP movement using player manager
|
||||
# 1. Check if next step is blocked by another player/bot
|
||||
# If we are NOT in attack mode, we should avoid bumping into others if possible
|
||||
if not actor.get("is_attack_mode") and actor.is_position_occupied(next_step):
|
||||
# Try to find a detour? For now, just try an unstuck move to get out of the way
|
||||
print("[BotController] %s path blocked by %s. Detouring." % [actor.name, next_step])
|
||||
var unstuck = await _try_unstuck_move()
|
||||
return unstuck
|
||||
|
||||
# 2. Execute movement
|
||||
if actor.movement_manager.simple_move_to(next_step):
|
||||
_is_processing_action = true
|
||||
_current_action = "moving"
|
||||
|
||||
Reference in New Issue
Block a user