feat: update
This commit is contained in:
@@ -99,6 +99,10 @@ const SMACK_CHARGE_WINDOW: float = 3.0
|
||||
|
||||
var player_mission_completions: Dictionary = {} # player_id → int
|
||||
var player_cleansers: Dictionary = {} # player_id → int (0 or 1)
|
||||
var cleanser_active: Dictionary = {} # player_id → true when immunity active
|
||||
var cleanser_cells_left: Dictionary = {} # player_id → int (cells remaining)
|
||||
const CLEANSER_MAX_CELLS: int = 5
|
||||
const CLEANSER_ACTIVATION_DELAY: float = 0.3
|
||||
|
||||
# =============================================================================
|
||||
# Trapped Players
|
||||
@@ -131,6 +135,7 @@ var phase_label: Label
|
||||
var cleanser_label: Label
|
||||
var cleanser_icon: TextureRect
|
||||
var cleanser_count: int = 0
|
||||
var slowmo_label: Label
|
||||
var _gauntlet_hud_scene: PackedScene = preload("res://scenes/gauntlet_hud.tscn")
|
||||
|
||||
# =============================================================================
|
||||
@@ -763,13 +768,13 @@ func clear_sticky_cell(pos: Vector2i) -> void:
|
||||
main_scene.rpc("sync_grid_item", pos.x, 2, pos.y, -1)
|
||||
|
||||
func _try_use_cleanser() -> void:
|
||||
"""Local player attempts to use Cleanser on adjacent sticky cells."""
|
||||
"""Local player attempts to activate Cleanser for 5-cell sticky immunity."""
|
||||
var local_pid = multiplayer.get_unique_id()
|
||||
var count = player_cleansers.get(local_pid, 0)
|
||||
if count <= 0:
|
||||
return
|
||||
|
||||
# Find local player
|
||||
# Block activation during stun
|
||||
var all_players = get_tree().get_nodes_in_group("Players")
|
||||
var local_player = null
|
||||
for p in all_players:
|
||||
@@ -777,41 +782,75 @@ func _try_use_cleanser() -> void:
|
||||
if pid == local_pid:
|
||||
local_player = p
|
||||
break
|
||||
if not local_player or not gridmap:
|
||||
if not local_player:
|
||||
return
|
||||
if local_player.get("is_frozen") or local_player.get("is_stop_frozen"):
|
||||
return
|
||||
# Already active
|
||||
if cleanser_active.has(local_pid):
|
||||
return
|
||||
|
||||
# Get player grid position
|
||||
var player_pos = local_player.global_position
|
||||
var grid_pos = Vector2i(int(player_pos.x), int(player_pos.z))
|
||||
# 0.3s activation delay
|
||||
await get_tree().create_timer(CLEANSER_ACTIVATION_DELAY).timeout
|
||||
|
||||
# Clear sticky cells in 3x3 area around player
|
||||
var cleared_any = false
|
||||
for dx in range(-1, 2):
|
||||
for dz in range(-1, 2):
|
||||
var check_pos = grid_pos + Vector2i(dx, dz)
|
||||
if sticky_cells.has(check_pos):
|
||||
if multiplayer.is_server():
|
||||
clear_sticky_cell(check_pos)
|
||||
else:
|
||||
rpc("rpc_use_cleanser", check_pos)
|
||||
cleared_any = true
|
||||
# Re-validate after delay
|
||||
if not is_instance_valid(local_player):
|
||||
return
|
||||
if local_player.get("is_frozen") or local_player.get("is_stop_frozen"):
|
||||
return
|
||||
|
||||
if cleared_any:
|
||||
# Consume cleanser
|
||||
player_cleansers[local_pid] = 0
|
||||
update_cleanser_ui(0)
|
||||
# Trigger slow-mo for dramatic effect
|
||||
if multiplayer.is_server():
|
||||
trigger_slowmo()
|
||||
else:
|
||||
rpc("rpc_trigger_slowmo")
|
||||
# Notify server if we're a client
|
||||
if not multiplayer.is_server() and _can_rpc():
|
||||
rpc("rpc_consume_cleanser", local_pid)
|
||||
elif multiplayer.is_server():
|
||||
# Sync to all clients
|
||||
# Activate cleanser immunity
|
||||
cleanser_active[local_pid] = true
|
||||
cleanser_cells_left[local_pid] = CLEANSER_MAX_CELLS
|
||||
|
||||
# Consume cleanser from inventory
|
||||
player_cleansers[local_pid] = 0
|
||||
update_cleanser_ui(0)
|
||||
|
||||
# Sync to server/clients
|
||||
if not multiplayer.is_server() and _can_rpc():
|
||||
rpc("rpc_activate_cleanser", local_pid)
|
||||
elif multiplayer.is_server():
|
||||
if _can_rpc():
|
||||
rpc("sync_cleanser_count", local_pid, 0)
|
||||
|
||||
# Trigger slow-mo for dramatic effect
|
||||
if multiplayer.is_server():
|
||||
trigger_slowmo()
|
||||
else:
|
||||
rpc("rpc_trigger_slowmo")
|
||||
|
||||
NotificationManager.send_message(local_player, "Cleanser Active! (5 cells)", NotificationManager.MessageType.POWERUP)
|
||||
|
||||
func deactivate_cleanser(player_id: int) -> void:
|
||||
"""Deactivate cleanser immunity for a player."""
|
||||
cleanser_active.erase(player_id)
|
||||
cleanser_cells_left.erase(player_id)
|
||||
|
||||
func is_cleanser_active(player_id: int) -> bool:
|
||||
"""Check if a player has active cleanser immunity."""
|
||||
return cleanser_active.has(player_id)
|
||||
|
||||
func use_cleanser_cell(player_id: int) -> bool:
|
||||
"""Use one cleanser cell. Returns true if still active, false if exhausted."""
|
||||
if not cleanser_active.has(player_id):
|
||||
return false
|
||||
cleanser_cells_left[player_id] -= 1
|
||||
if cleanser_cells_left[player_id] <= 0:
|
||||
deactivate_cleanser(player_id)
|
||||
return false
|
||||
return true
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func rpc_activate_cleanser(pid: int) -> void:
|
||||
"""RPC for clients to activate cleanser on server."""
|
||||
if multiplayer.is_server():
|
||||
if not cleanser_active.has(pid):
|
||||
cleanser_active[pid] = true
|
||||
cleanser_cells_left[pid] = CLEANSER_MAX_CELLS
|
||||
player_cleansers[pid] = 0
|
||||
if _can_rpc():
|
||||
rpc("sync_cleanser_count", local_pid, 0)
|
||||
rpc("sync_cleanser_count", pid, 0)
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func rpc_use_cleanser(pos: Vector2i) -> void:
|
||||
@@ -848,6 +887,9 @@ func trigger_slowmo(duration: float = 4.0) -> void:
|
||||
# Show visual overlay
|
||||
if main_scene and main_scene.has_node("Camera3D200"):
|
||||
_show_slowmo_overlay()
|
||||
# Show slow-mo HUD label
|
||||
if slowmo_label:
|
||||
slowmo_label.visible = true
|
||||
if _can_rpc():
|
||||
rpc("sync_slowmo_start", duration)
|
||||
|
||||
@@ -855,6 +897,9 @@ func _end_slowmo() -> void:
|
||||
slowmo_active = false
|
||||
Engine.time_scale = 1.0
|
||||
_hide_slowmo_overlay()
|
||||
# Hide slow-mo HUD label
|
||||
if slowmo_label:
|
||||
slowmo_label.visible = false
|
||||
if _can_rpc():
|
||||
rpc("sync_slowmo_end")
|
||||
|
||||
@@ -890,6 +935,8 @@ func sync_slowmo_start(duration: float) -> void:
|
||||
slowmo_timer = duration
|
||||
Engine.time_scale = SLOWMO_SCALE
|
||||
_show_slowmo_overlay()
|
||||
if slowmo_label:
|
||||
slowmo_label.visible = true
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func sync_slowmo_end() -> void:
|
||||
@@ -907,6 +954,7 @@ func _setup_hud() -> void:
|
||||
phase_label = hud_layer.get_node("TopContainer/PhaseLabel")
|
||||
cleanser_icon = hud_layer.get_node("BottomContainer/CleanserHBox/CleanserIcon")
|
||||
cleanser_label = hud_layer.get_node("BottomContainer/CleanserHBox/CleanserLabel")
|
||||
slowmo_label = hud_layer.get_node_or_null("TopContainer/SlowMoLabel")
|
||||
_generate_cleanser_icon()
|
||||
|
||||
func _generate_cleanser_icon() -> void:
|
||||
@@ -995,6 +1043,7 @@ func _on_goal_count_updated(peer_id: int, count: int) -> void:
|
||||
player_cleansers[peer_id] = 0
|
||||
if player_cleansers[peer_id] < 1:
|
||||
player_cleansers[peer_id] = 1
|
||||
emit_signal("cleanser_granted", peer_id)
|
||||
print("[Gauntlet] Player %d granted Cleanser (mission %d)" % [peer_id, completions])
|
||||
|
||||
# Respawn mission tiles in non-sticky locations
|
||||
|
||||
Reference in New Issue
Block a user