feat: the rebuild gamemode of "Gauntlet"

This commit is contained in:
2026-06-10 02:12:25 +08:00
parent 2d857a490b
commit 5653473c12
28 changed files with 1313 additions and 254 deletions
+80 -18
View File
@@ -132,9 +132,9 @@ func simple_move_to(grid_position: Vector2i) -> bool:
return false
var gm = null
var main = player.get_tree().root.get_node_or_null("Main")
if main and main.get("gauntlet_manager"):
gm = main.gauntlet_manager
var main_gauntlet = player.get_tree().root.get_node_or_null("Main")
if main_gauntlet and main_gauntlet.get("gauntlet_manager"):
gm = main_gauntlet.gauntlet_manager
# Check if currently trapped
if gm and gm.is_active:
@@ -205,7 +205,14 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
return false
# === NEW LOGIC: Only allow push if in ATTACK MODE and NOT GHOST ===
if not player.get("is_attack_mode") or player.get("is_invisible"):
var has_smack = false
var main_for_smack = player.get_tree().root.get_node_or_null("Main")
var gm_for_smack = main_for_smack.get("gauntlet_manager") if main_for_smack else null
if gm_for_smack and gm_for_smack.is_active:
var att_pid = player.get("peer_id") if "peer_id" in player else player.name.to_int()
has_smack = gm_for_smack.has_smack_charged(att_pid)
if (not player.get("is_attack_mode") and not has_smack) or player.get("is_invisible"):
# Standard bumping effect (Visual only)
print("[Move] Push blocked: Not in attack mode or is Ghost (%s trying to push %s)" % [player.name, other_player.name])
if _can_rpc():
@@ -229,6 +236,51 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
NotificationManager.send_message(player, "Target is in Safe Zone!", NotificationManager.MessageType.WARNING)
return false
var gm = null
var main_push_check = player.get_tree().root.get_node_or_null("Main")
if main_push_check and main_push_check.get("gauntlet_manager"):
gm = main_push_check.gauntlet_manager
# IF Gauntlet Mode is active, handle special Gauntlet Smacks
if gm and gm.is_active:
var pid = player.get("peer_id") if "peer_id" in player else player.name.to_int()
var other_pid = other_player.get("peer_id") if "peer_id" in other_player else other_player.name.to_int()
# Check if attacker has smack
if not gm.has_smack_charged(pid):
# bump visuals
if _can_rpc():
player.rpc("sync_bump", target_pos, true)
elif player.has_method("sync_bump"):
player.sync_bump(target_pos, true)
return false
# Smack Clash: Both charged
if gm.has_smack_charged(other_pid):
print("[Move] SMACK CLASH! Both %s and %s consumed." % [player.name, other_player.name])
if multiplayer.is_server():
gm.consume_smack(pid)
gm.consume_smack(other_pid)
elif _can_rpc():
gm.rpc("consume_smack", pid) # Assuming consume_smack is @rpc
gm.rpc("consume_smack", other_pid)
if _can_rpc():
player.rpc("apply_stagger", 1.0)
other_player.rpc("apply_stagger", 1.0)
else:
player.apply_stagger(1.0)
other_player.apply_stagger(1.0)
return false
# Else standard push
if multiplayer.is_server():
gm.consume_smack(pid)
elif _can_rpc():
gm.rpc("consume_smack", pid)
# === SUPER PUSH (Attack Mode) ===
print("Player %s SUPER PUSHING %s!" % [player.name, other_player.name])
@@ -240,17 +292,27 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
player.sync_bump(target_pos, false)
SfxManager.play("attack_mode")
# 1. 3-Floor Knockback towards Starting Line (X=0)
var push_direction = Vector2i(-1, 0) # Backwards
# 1. 3-Floor Knockback
var push_direction = Vector2i(-1, 0) # Default back (Stop N Go)
var main_push = player.get_tree().root.get_node_or_null("Main")
var gm_push = main_push.gauntlet_manager if main_push and main_push.has_node("GauntletManager") else (main_push.get("gauntlet_manager") if main_push else null)
if gm_push and gm_push.is_active:
push_direction = direction # Use the direction of the attack
var pushed_to_pos = target_pos
var push_path = []
# Try to push up to 3 tiles back, building the path as we go
var hit_sticky = false
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))
if gm_push and gm_push.is_active and gm_push.is_sticky_cell(pushed_to_pos):
hit_sticky = true
break # stop pushing immediately upon touching sticky zone!
else:
break # Blocked by wall or edge
@@ -268,20 +330,20 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
other_player.target_position = pushed_to_pos # Logical update
# Check if landing spot is sticky
var main = player.get_tree().root.get_node_or_null("Main")
if main and main.get("gauntlet_manager"):
var gm = main.gauntlet_manager
if gm.is_active and gm.is_sticky_cell(pushed_to_pos):
var main_sticky = player.get_tree().root.get_node_or_null("Main")
if main_sticky and main_sticky.get("gauntlet_manager"):
var gm_sticky = main_sticky.gauntlet_manager
if gm_sticky.is_active and gm_sticky.is_sticky_cell(pushed_to_pos):
print("[Move] Player pushed into sticky cell at %s" % pushed_to_pos)
if multiplayer.is_server() or other_player.is_multiplayer_authority():
gm._trap_player(other_player)
gm_sticky._trap_player(other_player)
# 2. Apply freeze/stun effect (blue tint)
# 2. Apply freeze/stun effect
var stun_duration = 1.0 if (gm_push and gm_push.is_active) else 1.5
if _can_rpc():
other_player.rpc("apply_stagger", 1.5)
other_player.rpc("apply_stagger", stun_duration)
else:
# Handle local execution (e.g. offline or host-only logic)
other_player.apply_stagger(1.5)
other_player.apply_stagger(stun_duration)
# 4. Consume Boost (Full) - One hit per charge
if player.powerup_manager:
@@ -292,9 +354,9 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
if player.is_multiplayer_authority():
var is_sng = LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO)
if not is_sng:
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
var gcm = main.get_node_or_null("GoalsCycleManager")
var main_score = player.get_tree().get_root().get_node_or_null("Main")
if main_score:
var gcm = main_score.get_node_or_null("GoalsCycleManager")
if gcm:
if multiplayer.is_server():
# Server/Bot: Directly add score to specific player ID