update feature & bugfix
This commit is contained in:
+107
-9
@@ -173,9 +173,6 @@ func _ready():
|
||||
# =========================================================================
|
||||
# BOT-SPECIFIC SETUP - BotController handles bot AI, we just disable input
|
||||
# =========================================================================
|
||||
# =========================================================================
|
||||
# BOT-SPECIFIC SETUP - BotController handles bot AI
|
||||
# =========================================================================
|
||||
if is_bot == true or is_in_group("Bots"):
|
||||
# Disable input processing for bots
|
||||
set_process_input(false)
|
||||
@@ -183,10 +180,11 @@ func _ready():
|
||||
|
||||
# Set initial position for bots
|
||||
if enhanced_gridmap:
|
||||
current_position = _find_random_spawn_position()
|
||||
update_player_position(current_position)
|
||||
spawn_point_selected = true
|
||||
if is_multiplayer_authority():
|
||||
current_position = _find_random_spawn_position()
|
||||
update_player_position(current_position)
|
||||
spawn_point_selected = true
|
||||
rpc("set_spawn_position", current_position)
|
||||
rpc("notify_spawn_selected", current_position)
|
||||
|
||||
# Assign bot character (deterministic based on ID to match lobby preview)
|
||||
@@ -603,6 +601,96 @@ func _apply_tint_recursive(node: Node, color: Color):
|
||||
for child in node.get_children():
|
||||
_apply_tint_recursive(child, color)
|
||||
|
||||
var immunity_timer: float = 0.0
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func apply_stagger(duration: float = 1.5):
|
||||
if immunity_timer > 0:
|
||||
return # Immune!
|
||||
|
||||
if is_frozen:
|
||||
return # Already staggered
|
||||
|
||||
is_frozen = true
|
||||
_apply_tint_recursive(self, Color.BLUE) # Visual feedback
|
||||
|
||||
# Set immunity (3 seconds as requested)
|
||||
immunity_timer = 3.0
|
||||
|
||||
print("Player %s staggered for %.1f seconds" % [name, duration])
|
||||
|
||||
if is_multiplayer_authority():
|
||||
rpc("display_message", "C R U S H E D !", 4) # MessageType.WARNING
|
||||
drop_random_item()
|
||||
|
||||
# Grant "Smashed" Bonus (1 bar, max 2)
|
||||
if powerup_manager:
|
||||
powerup_manager.acquire_smash_bonus()
|
||||
|
||||
await get_tree().create_timer(duration).timeout
|
||||
|
||||
is_frozen = false
|
||||
# If still immune, show immunity tint (Green?), otherwise White
|
||||
if immunity_timer > 0:
|
||||
_apply_tint_recursive(self, Color(0.5, 1.0, 0.5)) # Light Green for immunity
|
||||
else:
|
||||
_apply_tint_recursive(self, Color.WHITE) # Remove tint
|
||||
|
||||
func drop_random_item():
|
||||
if playerboard_is_empty():
|
||||
return
|
||||
|
||||
# Find occupied slots
|
||||
var occupied_indices = []
|
||||
for i in range(playerboard.size()):
|
||||
if playerboard[i] != -1:
|
||||
occupied_indices.append(i)
|
||||
|
||||
if occupied_indices.size() == 0:
|
||||
return
|
||||
|
||||
# Pick random slot
|
||||
var slot_index = occupied_indices.pick_random()
|
||||
var item_id = playerboard[slot_index]
|
||||
|
||||
# Try to find empty spot on grid near player
|
||||
var drop_pos = _find_valid_drop_position()
|
||||
|
||||
if drop_pos != Vector2i(-1, -1):
|
||||
# Drop it
|
||||
playerboard[slot_index] = -1
|
||||
rpc("sync_playerboard", playerboard)
|
||||
|
||||
# Sync grid item
|
||||
var cell = Vector3i(drop_pos.x, 0, drop_pos.y)
|
||||
rpc("sync_grid_item", cell.x, cell.y, cell.z, item_id)
|
||||
|
||||
rpc("display_message", "Dropped item!", 4)
|
||||
print("Player %s dropped item %d at %s" % [name, item_id, drop_pos])
|
||||
|
||||
func playerboard_is_empty() -> bool:
|
||||
for item in playerboard:
|
||||
if item != -1:
|
||||
return false
|
||||
return true
|
||||
|
||||
func _find_valid_drop_position() -> Vector2i:
|
||||
# Try random adjacent cells
|
||||
var neighbors = enhanced_gridmap.get_neighbors(current_position, 0)
|
||||
neighbors.shuffle()
|
||||
|
||||
for neighbor in neighbors:
|
||||
var pos = neighbor.position
|
||||
if enhanced_gridmap.get_cell_item(Vector3i(pos.x, 0, pos.y)) == -1: # Empty floor? No, 0 is floor. -1 is void?
|
||||
# Wait, items are on layer 1 usually?
|
||||
# Check logic: grab_item uses y=1?
|
||||
var item_cell = Vector3i(pos.x, 1, pos.y)
|
||||
if enhanced_gridmap.get_cell_item(item_cell) == -1:
|
||||
if not is_position_occupied(pos):
|
||||
return pos
|
||||
|
||||
return Vector2i(-1, -1)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
if is_multiplayer_authority():
|
||||
@@ -629,6 +717,13 @@ func _process(delta):
|
||||
if movement_manager:
|
||||
movement_manager._process(delta)
|
||||
|
||||
# Immunity Timer Logic
|
||||
if immunity_timer > 0:
|
||||
immunity_timer -= delta
|
||||
if immunity_timer <= 0:
|
||||
immunity_timer = 0
|
||||
_apply_tint_recursive(self, Color.WHITE) # Remove immunity tint
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func ping_existence():
|
||||
# This just lets other clients know this player exists
|
||||
@@ -876,7 +971,8 @@ func start_movement_along_path(path: Array, clear_visual: bool = true):
|
||||
|
||||
# Clear visuals for everyone including bots
|
||||
if clear_visual:
|
||||
enhanced_gridmap.clear_path_visualization()
|
||||
if enhanced_gridmap:
|
||||
enhanced_gridmap.clear_path_visualization()
|
||||
|
||||
# Check for buffered input
|
||||
if movement_manager and movement_manager.has_method("_on_movement_finished"):
|
||||
@@ -1429,8 +1525,10 @@ func sync_position(pos: Vector2i):
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
) + cell_offset
|
||||
|
||||
global_position = new_pos
|
||||
target_visual_position = new_pos # Reset smoothing target to prevent fighting
|
||||
# Only snap visual if not moving (moving players will tween to destination)
|
||||
if not is_player_moving:
|
||||
global_position = new_pos
|
||||
target_visual_position = new_pos # Reset smoothing target to prevent fighting
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func set_spawn_position(pos: Vector2i):
|
||||
|
||||
Reference in New Issue
Block a user