feat: Add PlayerMovementManager to centralize player movement logic and implement a 'SUPER PUSH' attack mechanic.
This commit is contained in:
@@ -78,25 +78,8 @@ func simple_move_to(grid_position: Vector2i) -> bool:
|
||||
return false
|
||||
|
||||
# PHYSICS CHECK: Ensure no static obstacles (like Stands) are blocking the path
|
||||
# GridMap logic handles cells, but Objects/Bodies might be placed on top (like StaticTektonStand)
|
||||
var space_state = player.get_world_3d().direct_space_state
|
||||
# RAYCAST HEIGHT: 0.3 (Center of the 0.6m tall stand)
|
||||
# Check from CENTER using +0.5
|
||||
var from = Vector3(player.current_position.x + 0.5, 0.3, player.current_position.y + 0.5)
|
||||
var to = Vector3(grid_position.x + 0.5, 0.3, grid_position.y + 0.5)
|
||||
|
||||
# Check center of target tile
|
||||
var query = PhysicsRayQueryParameters3D.create(from, to)
|
||||
query.collide_with_areas = false
|
||||
query.collide_with_bodies = true
|
||||
# query.collision_mask = 1 # Default mask usually covers static bodies
|
||||
|
||||
var result = space_state.intersect_ray(query)
|
||||
if result:
|
||||
# If we hit something static that isn't ourselves
|
||||
if result.collider != player:
|
||||
print("Movement Blocked by Physics Body: ", result.collider.name)
|
||||
return false
|
||||
if _is_position_blocked_by_physics(grid_position):
|
||||
return false
|
||||
|
||||
if player.is_position_occupied(grid_position):
|
||||
var push_dir = grid_position - player.current_position
|
||||
@@ -158,9 +141,11 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
||||
# 3. Knockback / Stagger
|
||||
# Push them away
|
||||
var pushed_to_pos = target_pos + direction
|
||||
if enhanced_gridmap.is_position_valid(pushed_to_pos) and \
|
||||
if not _is_position_in_static_stand_area(pushed_to_pos) and \
|
||||
enhanced_gridmap.is_position_valid(pushed_to_pos) and \
|
||||
enhanced_gridmap.get_cell_item(Vector3i(pushed_to_pos.x, 0, pushed_to_pos.y)) != -1 and \
|
||||
not player.is_position_occupied(pushed_to_pos):
|
||||
not player.is_position_occupied(pushed_to_pos) and \
|
||||
not _is_position_blocked_by_physics(pushed_to_pos):
|
||||
# Valid push
|
||||
var push_path = [Vector2(pushed_to_pos.x, pushed_to_pos.y)]
|
||||
other_player.rpc("start_movement_along_path", push_path, false)
|
||||
@@ -404,3 +389,47 @@ func highlight_adjacent_cells():
|
||||
cells_to_highlight.append(cell_pos)
|
||||
|
||||
player.highlight_cells_if_authorized(cells_to_highlight)
|
||||
|
||||
func _is_position_in_static_stand_area(pos: Vector2i) -> bool:
|
||||
# Check against all known Static Tekton Stands (3x3 areas)
|
||||
var stands = player.get_tree().get_nodes_in_group("StaticTektonStands")
|
||||
print("[Debug] Checking Push Prevention for %s. Found %d stands." % [pos, stands.size()])
|
||||
|
||||
for stand in stands:
|
||||
if not enhanced_gridmap: continue
|
||||
|
||||
# Convert world to grid. Use global_position just to be safe.
|
||||
var local_pos = enhanced_gridmap.to_local(stand.global_position)
|
||||
var stand_grid_pos = enhanced_gridmap.local_to_map(local_pos)
|
||||
|
||||
# Stand is centered, so key check is 3x3 around it
|
||||
var center = Vector2i(stand_grid_pos.x, stand_grid_pos.z)
|
||||
|
||||
# Check if pos is right on top of stand (distance 0) or adjacent (distance 1)
|
||||
# Chebyshev distance <= 1 means 3x3 square
|
||||
if abs(pos.x - center.x) <= 1 and abs(pos.y - center.y) <= 1:
|
||||
print(" - BLOCKED by Stand at %s (Center: %s)" % [stand.name, center])
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func _is_position_blocked_by_physics(target_pos: Vector2i) -> bool:
|
||||
if not player.is_inside_tree(): return false
|
||||
|
||||
var space_state = player.get_world_3d().direct_space_state
|
||||
var center_x = target_pos.x + 0.5
|
||||
var center_z = target_pos.y + 0.5
|
||||
var from = Vector3(center_x, 1.0, center_z)
|
||||
var to = Vector3(center_x, 0.1, center_z)
|
||||
|
||||
var query = PhysicsRayQueryParameters3D.create(from, to)
|
||||
query.collide_with_areas = false
|
||||
query.collide_with_bodies = true
|
||||
|
||||
var result = space_state.intersect_ray(query)
|
||||
if result:
|
||||
if result.collider != player:
|
||||
# print("Movement Blocked by Physics Body: ", result.collider.name)
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
@@ -10,6 +10,8 @@ extends StaticBody3D
|
||||
_update_mesh_from_index()
|
||||
|
||||
func _ready():
|
||||
add_to_group("StaticTektonStands")
|
||||
print("Static Stand Ready: ", name)
|
||||
if multiplayer.is_server():
|
||||
# Only randomize if not already set (Main.gd sets it now)
|
||||
if shape_index == -1:
|
||||
|
||||
Reference in New Issue
Block a user