feat(candy-survival): toggle-and-walk knock mode, unified animations, score rewards, RPC fix
- Changed knock from instant-ambush to toggle-and-walk: press Q to toggle Knock Mode ON, walk into target to execute, consumed on use - Unified knock animation with other game modes (attack_mode SFX, bump, 3-tile knockback, stagger) - Added +100 score rewards for completing goals, KNOCK, and GHOST - Fixed RPC unknown peer ID crash for AI bots in ghost/candy stack sync - Bots auto-toggle is_charged_strike when they have knock charges - Fixed profile panel username update on connected peers - Added SafeNakamaMultiplayerBridge for match state crash prevention
This commit is contained in:
@@ -120,39 +120,28 @@ func handle_unhandled_input(event):
|
||||
var gm = player.get_node_or_null("/root/Main/CandySurvivalManager")
|
||||
if gm and gm.active:
|
||||
var att_id = player.get("peer_id") if "peer_id" in player else player.name.to_int()
|
||||
|
||||
# Toggle mode: if already in knock mode, turn it off
|
||||
if player.get("is_charged_strike"):
|
||||
player.is_charged_strike = false
|
||||
NotificationManager.send_message(player, "Knock Mode OFF", NotificationManager.MessageType.WARNING)
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
|
||||
# Check charges before toggling on
|
||||
if gm.player_knocks.get(att_id, 5) <= 0:
|
||||
NotificationManager.send_message(player, "No Knock charges left!", NotificationManager.MessageType.WARNING)
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
|
||||
# Find a target to knock (adjacent player: cardinal or diagonal distance <= 1)
|
||||
var p_pos = player.current_position
|
||||
var all_players = get_tree().get_nodes_in_group("Players")
|
||||
var target_found = null
|
||||
var min_dist = 999
|
||||
for other in all_players:
|
||||
if other == player or not is_instance_valid(other): continue
|
||||
var other_pos = other.current_position
|
||||
var dist = max(abs(p_pos.x - other_pos.x), abs(p_pos.y - other_pos.y))
|
||||
if dist <= 1 and dist < min_dist:
|
||||
target_found = other
|
||||
min_dist = dist
|
||||
if dist == 1:
|
||||
break
|
||||
|
||||
if target_found:
|
||||
var tgt_id = target_found.get("peer_id") if "peer_id" in target_found else target_found.name.to_int()
|
||||
if multiplayer.is_server():
|
||||
gm.try_knock(att_id, tgt_id)
|
||||
else:
|
||||
gm.rpc_id(1, "try_knock", att_id, tgt_id)
|
||||
else:
|
||||
# No target, but play the bump animation anyway in place
|
||||
player.rpc("sync_bump", p_pos)
|
||||
|
||||
|
||||
# Toggle knock mode ON (reuses charged strike visuals)
|
||||
player.is_charged_strike = true
|
||||
NotificationManager.send_message(player, "🥊 Knock Mode ON — Walk into a target!", NotificationManager.MessageType.POWERUP)
|
||||
player.update_active_player_indicator()
|
||||
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
|
||||
|
||||
if player.powerup_manager:
|
||||
player.powerup_manager.use_special_effect()
|
||||
if player.get("is_attack_mode") and player.has_method("enter_attack_mode"):
|
||||
|
||||
Reference in New Issue
Block a user