rename gauntlet→candy_survival + rewrite Candy Survival per boss design
- Rename enum GAUNTLET→CANDY_SURVIVAL, all gauntlet_*→candy_survival_* - Rename files: gauntlet_manager→candy_survival_manager, candy_cannon→candy_survival_npc, gauntlet.tscn→candy_survival.tscn - Rewrite candy_survival_manager.gd: blueprints, candy stack, Mekton delivery, Sugar Rush, knock/ghost charges, sticky-as-wall - Update player_movement_manager.gd: smack→knock system, ghost integration - All Candy Survival issues (#54-57, #65-70) retitled per boss design - Shared managers (goals_cycle, goal, player_race, playerboard, turn) untouched
This commit is contained in:
@@ -112,19 +112,19 @@ func simple_move_to(grid_position: Vector2i) -> bool:
|
||||
print("[MovementManager] Hard block at %s. Ghost pass denied." % grid_position)
|
||||
|
||||
var gm = null
|
||||
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
|
||||
var main_candy_survival = player.get_tree().root.get_node_or_null("Main")
|
||||
if main_candy_survival and main_candy_survival.get("candy_survival_manager"):
|
||||
gm = main_candy_survival.candy_survival_manager
|
||||
|
||||
# Check Floor 0 (Basic Walkability/Void)
|
||||
if (cell_floor == -1 or cell_floor in enhanced_gridmap.non_walkable_items) and not is_wall_passable:
|
||||
print("[Move] Failed: Floor Item %d is non-walkable" % cell_floor)
|
||||
return false
|
||||
|
||||
# Gauntlet Mode explicit wall overrides (since we visually removed the wall blocks)
|
||||
# Candy Survival explicit wall overrides (since we visually removed the wall blocks)
|
||||
if gm and gm.is_active:
|
||||
if gm._is_npc_zone(grid_position):
|
||||
print("[Move] Failed: Blocked by Gauntlet NPC center at %s" % grid_position)
|
||||
print("[Move] Failed: Blocked by Candy Survival NPC center at %s" % grid_position)
|
||||
return false
|
||||
|
||||
# Check Floor 1 (Obstacles/Walls)
|
||||
@@ -156,13 +156,13 @@ func simple_move_to(grid_position: Vector2i) -> bool:
|
||||
return false # Don't move into the tile, just knock
|
||||
|
||||
# If moving into a sticky cell: block movement unless player is in ghost
|
||||
# mode (is_invisible), which lets them bypass sticky tiles in gauntlet.
|
||||
# mode (is_invisible), which lets them bypass sticky tiles in Candy Survival
|
||||
if gm and gm.is_active and gm.is_sticky_cell(grid_position):
|
||||
if player.get("is_invisible"):
|
||||
# Ghost mode: walk through sticky tile freely
|
||||
print("[Move] Ghost mode bypassed sticky cell at %s" % grid_position)
|
||||
else:
|
||||
print("[Move] Failed: Blocked by Gauntlet Sticky cell at %s" % grid_position)
|
||||
print("[Move] Failed: Blocked by Candy Survival Sticky cell at %s" % grid_position)
|
||||
return false
|
||||
|
||||
rotate_towards_target(grid_position)
|
||||
@@ -208,15 +208,16 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
||||
NotificationManager.send_message(player, "Target is Immune!", NotificationManager.MessageType.WARNING)
|
||||
return false
|
||||
|
||||
# === NEW LOGIC: Only allow push if in ATTACK MODE and NOT GHOST ===
|
||||
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:
|
||||
# Candy Survival: check if attacker has knock charges
|
||||
var has_knock = false
|
||||
var main_for_knock = player.get_tree().root.get_node_or_null("Main")
|
||||
var gm_for_knock = main_for_knock.get("candy_survival_manager") if main_for_knock else null
|
||||
if gm_for_knock and gm_for_knock.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)
|
||||
var charges = gm_for_knock.player_knocks.get(att_pid, 0) if gm_for_knock.player_knocks else 0
|
||||
has_knock = charges > 0
|
||||
|
||||
if (not player.get("is_charged_strike") and not has_smack) or player.get("is_invisible"):
|
||||
if (not player.get("is_charged_strike") and not has_knock) or player.get("is_invisible"):
|
||||
# Standard bumping effect (Visual only)
|
||||
print("[Move] Push blocked: Not charged or is Ghost (%s trying to push %s)" % [player.name, other_player.name])
|
||||
if _can_rpc():
|
||||
@@ -243,47 +244,20 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
||||
|
||||
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 main_push_check and main_push_check.get("candy_survival_manager"):
|
||||
gm = main_push_check.candy_survival_manager
|
||||
|
||||
# IF Gauntlet Mode is active, handle special Gauntlet Smacks
|
||||
if gm and gm.is_active:
|
||||
# Candy Survival: knock mechanic (candy-steal or backfire)
|
||||
if gm and gm.is_active and gm.has_method("try_knock"):
|
||||
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)
|
||||
if gm.try_knock(pid, other_pid):
|
||||
print("[CandySurvival] Player %d knocked %d, stole candies!" % [pid, other_pid])
|
||||
else:
|
||||
print("[CandySurvival] Player %d tried to knock %d (backfire or no charges)" % [pid, other_pid])
|
||||
if _can_rpc():
|
||||
player.rpc("sync_bump", target_pos, false)
|
||||
return false
|
||||
|
||||
# === SUPER PUSH (Attack Mode) ===
|
||||
print("Player %s SUPER PUSHING %s!" % [player.name, other_player.name])
|
||||
@@ -300,7 +274,7 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
||||
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)
|
||||
var gm_push = main_push.candy_survival_manager if main_push and main_push.has_node("CandySurvivalManager") else (main_push.get("candy_survival_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
|
||||
@@ -335,8 +309,8 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
||||
|
||||
# Check if landing spot is sticky
|
||||
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 main_sticky and main_sticky.get("candy_survival_manager"):
|
||||
var gm_sticky = main_sticky.candy_survival_manager
|
||||
if gm_sticky.is_active and gm_sticky.is_sticky_cell(pushed_to_pos):
|
||||
if other_player.get("is_invisible"):
|
||||
# Ghost mode: pushed player bypasses sticky
|
||||
|
||||
Reference in New Issue
Block a user