Release 2.4.4: Candy Survival Knock and backfire fixes
Release / Build & Release (push) Successful in 7m54s
Release / Build & Release (push) Successful in 7m54s
This commit is contained in:
@@ -1,4 +1,9 @@
|
|||||||
## [NEXT]
|
## [NEXT]
|
||||||
|
|
||||||
|
## [2.4.4] — 2026-07-09
|
||||||
|
- Fixed Candy Survival Knock mechanic: pressing Q now properly knocks adjacent players diagonally and cardinally.
|
||||||
|
- Implemented Candy Survival Knock backfire mechanic: knocking a player with 0 candies transfers your candy stack to them and staggers you.
|
||||||
|
- Fixed Candy Survival candy stack 3D mesh visual desync and client-side stack synchronization.
|
||||||
- Fixed playerboard desync where host-side board changes weren't reflected on remote clients in multiplayer sessions.
|
- Fixed playerboard desync where host-side board changes weren't reflected on remote clients in multiplayer sessions.
|
||||||
- Fixed punch/smack SFX playing repeatedly when quickly attacking another player.
|
- Fixed punch/smack SFX playing repeatedly when quickly attacking another player.
|
||||||
- Fixed currency split between Gacha and Shop — wallet balance now updates immediately after purchase without needing to reopen the panel.
|
- Fixed currency split between Gacha and Shop — wallet balance now updates immediately after purchase without needing to reopen the panel.
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ This document serves as an exhaustive, technical record of all modifications, re
|
|||||||
- Fires `try_knock(attacker, target)` when adjacent to an opponent.
|
- Fires `try_knock(attacker, target)` when adjacent to an opponent.
|
||||||
- Consumes 1 of 5 starting charges (`player_knocks`).
|
- Consumes 1 of 5 starting charges (`player_knocks`).
|
||||||
- *Steal*: If target has candies, attacker adopts target's full stack and color; target is zeroed.
|
- *Steal*: If target has candies, attacker adopts target's full stack and color; target is zeroed.
|
||||||
- *Backfire*: If target has 0 candies, attacker loses a charge and both suffer the knock animation state (handled by caller).
|
- *Backfire*: If target has 0 candies, attacker loses a charge and gets staggered, while any candy stack held by the attacker is transferred to the target.
|
||||||
- **Ghost (Phase-Through)**:
|
- **Ghost (Phase-Through)**:
|
||||||
- Input bound natively to `action_grab_tekton` inside `player_input_manager.gd` (bypasses default grab behavior in this mode).
|
- Input bound natively to `action_grab_tekton` inside `player_input_manager.gd` (bypasses default grab behavior in this mode).
|
||||||
- Consumes 1 of 5 starting charges (`player_ghosts`).
|
- Consumes 1 of 5 starting charges (`player_ghosts`).
|
||||||
|
|||||||
@@ -1,7 +1,27 @@
|
|||||||
{
|
{
|
||||||
"latest_version": "2.4.3",
|
"latest_version": "2.4.4",
|
||||||
"minimum_app_version": "2.1.0",
|
"minimum_app_version": "2.1.0",
|
||||||
"releases": [
|
"releases": [
|
||||||
|
{
|
||||||
|
"version": "2.4.4",
|
||||||
|
"date": "2026-07-09",
|
||||||
|
"pck_url": "https://git.klud.top/danchie/tekton/raw/branch/patches/patch.pck",
|
||||||
|
"pck_size": 0,
|
||||||
|
"changelog": [
|
||||||
|
"Fixed Candy Survival Knock mechanic: pressing Q now properly knocks adjacent players diagonally and cardinally.",
|
||||||
|
"Implemented Candy Survival Knock backfire mechanic: knocking a player with 0 candies transfers your candy stack to them and staggers you.",
|
||||||
|
"Fixed Candy Survival candy stack 3D mesh visual desync and client-side stack synchronization.",
|
||||||
|
"Fixed playerboard desync where host-side board changes weren't reflected on remote clients in multiplayer sessions.",
|
||||||
|
"Fixed punch/smack SFX playing repeatedly when quickly attacking another player.",
|
||||||
|
"Fixed currency split between Gacha and Shop \u2014 wallet balance now updates immediately after purchase without needing to reopen the panel.",
|
||||||
|
"Fixed fatal crash in Multiplayer Gauntlet caused by missing `has_method` check on smack cooldown timers on remote peers.",
|
||||||
|
"Upgraded engine from Godot 4.6 to 4.7 stable for better performance and stability.",
|
||||||
|
"Migrated patch delivery from GitHub Pages to Gitea native raw endpoint \u2014 no more external dependencies for game updates.",
|
||||||
|
"CI: optimized build cache for Godot binary, eliminating repeated 140MB downloads on every workflow run.",
|
||||||
|
"CI: shallow repository checkout (--depth 1) for faster clone times.",
|
||||||
|
"CI: removed unnecessary export template download from patch deployment workflow (--export-pack doesn't need them)."
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
"date": "2026-07-04",
|
"date": "2026-07-04",
|
||||||
|
|||||||
+4
-4
@@ -14,7 +14,7 @@ custom_features=""
|
|||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter=""
|
include_filter=""
|
||||||
exclude_filter=""
|
exclude_filter=""
|
||||||
export_path="build/windows/tekton_armageddon_v2.4.3.exe"
|
export_path="build/windows/tekton_armageddon_v2.4.4.exe"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
patch_delta_encoding=false
|
patch_delta_encoding=false
|
||||||
patch_delta_compression_level_zstd=19
|
patch_delta_compression_level_zstd=19
|
||||||
@@ -85,7 +85,7 @@ custom_features=""
|
|||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter=""
|
include_filter=""
|
||||||
exclude_filter=""
|
exclude_filter=""
|
||||||
export_path="build/tekton-dash-armageddon-v.2.4.3.apk"
|
export_path="build/tekton-dash-armageddon-v.2.4.4.apk"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
patch_delta_encoding=false
|
patch_delta_encoding=false
|
||||||
patch_delta_compression_level_zstd=19
|
patch_delta_compression_level_zstd=19
|
||||||
@@ -314,7 +314,7 @@ custom_features=""
|
|||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter=""
|
include_filter=""
|
||||||
exclude_filter=""
|
exclude_filter=""
|
||||||
export_path="build/tekton_armageddon_v2.4.3.zip"
|
export_path="build/tekton_armageddon_v2.4.4.zip"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
patch_delta_encoding=false
|
patch_delta_encoding=false
|
||||||
patch_delta_compression_level_zstd=19
|
patch_delta_compression_level_zstd=19
|
||||||
@@ -589,7 +589,7 @@ custom_features=""
|
|||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter=""
|
include_filter=""
|
||||||
exclude_filter=""
|
exclude_filter=""
|
||||||
export_path="build/linux/tekton_armageddon_v2.4.3.x86_64"
|
export_path="build/linux/tekton_armageddon_v2.4.4.x86_64"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
patch_delta_encoding=false
|
patch_delta_encoding=false
|
||||||
patch_delta_compression_level_zstd=19
|
patch_delta_compression_level_zstd=19
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Tekton Dash Armageddon"
|
config/name="Tekton Dash Armageddon"
|
||||||
config/version="2.4.3"
|
config/version="2.4.4"
|
||||||
run/main_scene="res://scenes/ui/boot_screen.tscn"
|
run/main_scene="res://scenes/ui/boot_screen.tscn"
|
||||||
config/features=PackedStringArray("4.6", "Forward Plus")
|
config/features=PackedStringArray("4.6", "Forward Plus")
|
||||||
boot_splash/bg_color=Color(0.16470589, 0.6745098, 0.9372549, 1)
|
boot_splash/bg_color=Color(0.16470589, 0.6745098, 0.9372549, 1)
|
||||||
|
|||||||
@@ -1536,6 +1536,13 @@ func sync_game_start(player_list: Array, is_turn_based: bool):
|
|||||||
stop_n_go_manager.name = "StopNGoManager"
|
stop_n_go_manager.name = "StopNGoManager"
|
||||||
add_child(stop_n_go_manager)
|
add_child(stop_n_go_manager)
|
||||||
stop_n_go_manager.activate_client_side()
|
stop_n_go_manager.activate_client_side()
|
||||||
|
elif LobbyManager.game_mode == "Candy Survival":
|
||||||
|
if not candy_survival_manager:
|
||||||
|
candy_survival_manager = load("res://scripts/managers/candy_survival_manager.gd").new()
|
||||||
|
candy_survival_manager.name = "CandySurvivalManager"
|
||||||
|
add_child(candy_survival_manager)
|
||||||
|
candy_survival_manager.initialize(self, $EnhancedGridMap)
|
||||||
|
candy_survival_manager.activate_client_side()
|
||||||
|
|
||||||
# Initialize leaderboard for all peers (after a delay to ensure players loaded)
|
# Initialize leaderboard for all peers (after a delay to ensure players loaded)
|
||||||
call_deferred("_deferred_init_leaderboard")
|
call_deferred("_deferred_init_leaderboard")
|
||||||
@@ -2791,3 +2798,12 @@ func display_message(message: String, type: int = 0):
|
|||||||
if player.has_method("display_message"):
|
if player.has_method("display_message"):
|
||||||
player.display_message(message, type)
|
player.display_message(message, type)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
func get_player_ids() -> Array:
|
||||||
|
var pids: Array = []
|
||||||
|
for p in get_tree().get_nodes_in_group("Players"):
|
||||||
|
if not is_instance_valid(p): continue
|
||||||
|
var pid = p.get("peer_id") if "peer_id" in p else p.name.to_int()
|
||||||
|
if pid != 0 and not pids.has(pid):
|
||||||
|
pids.append(pid)
|
||||||
|
return pids
|
||||||
|
|||||||
@@ -611,6 +611,7 @@ var _candy_scene: PackedScene = preload("res://scenes/candy.tscn")
|
|||||||
func sync_candy_stack(colors: Array) -> void:
|
func sync_candy_stack(colors: Array) -> void:
|
||||||
var old_stack = get_node_or_null("CandyStack")
|
var old_stack = get_node_or_null("CandyStack")
|
||||||
if old_stack:
|
if old_stack:
|
||||||
|
old_stack.name = "CandyStack_Old_" + str(randi())
|
||||||
old_stack.queue_free()
|
old_stack.queue_free()
|
||||||
|
|
||||||
if colors.is_empty() or not _candy_scene: return
|
if colors.is_empty() or not _candy_scene: return
|
||||||
|
|||||||
@@ -148,8 +148,6 @@ func _define_sticky_walls() -> void:
|
|||||||
sticky_cells[Vector2i(NPC_CENTER.x + dx, NPC_CENTER.y + dy)] = true
|
sticky_cells[Vector2i(NPC_CENTER.x + dx, NPC_CENTER.y + dy)] = true
|
||||||
|
|
||||||
func start_game_mode() -> void:
|
func start_game_mode() -> void:
|
||||||
if multiplayer.is_server():
|
|
||||||
activate_client_side()
|
|
||||||
active = true
|
active = true
|
||||||
current_face = CandyColor.HEART
|
current_face = CandyColor.HEART
|
||||||
face_timer = 0.0
|
face_timer = 0.0
|
||||||
@@ -183,6 +181,9 @@ func start_game_mode() -> void:
|
|||||||
rpc("sync_knock_charge_count", pid, START_KNOCK)
|
rpc("sync_knock_charge_count", pid, START_KNOCK)
|
||||||
rpc("sync_ghost_charge_count", pid, START_GHOST)
|
rpc("sync_ghost_charge_count", pid, START_GHOST)
|
||||||
|
|
||||||
|
if multiplayer.is_server():
|
||||||
|
activate_client_side()
|
||||||
|
|
||||||
print("[CandySurvival] Started with %d players" % pids.size())
|
print("[CandySurvival] Started with %d players" % pids.size())
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
func _enter_tree() -> void:
|
||||||
@@ -330,15 +331,6 @@ func _update_candy_badge(pid: int) -> void:
|
|||||||
var face_match = (color != -1)
|
var face_match = (color != -1)
|
||||||
var score = player_score.get(pid, 0)
|
var score = player_score.get(pid, 0)
|
||||||
rpc("sync_candy_badge", pid, count, mult, face_match, score, colors)
|
rpc("sync_candy_badge", pid, count, mult, face_match, score, colors)
|
||||||
|
|
||||||
# Update the 3D meshes on the player's head across all clients
|
|
||||||
var all_players = get_tree().get_nodes_in_group("Players")
|
|
||||||
for player in all_players:
|
|
||||||
var curr_pid = player.get("peer_id") if "peer_id" in player else player.name.to_int()
|
|
||||||
if curr_pid == pid:
|
|
||||||
if player.has_method("sync_candy_stack"):
|
|
||||||
player.rpc("sync_candy_stack", colors)
|
|
||||||
break
|
|
||||||
|
|
||||||
func get_multiplier(pid: int) -> float:
|
func get_multiplier(pid: int) -> float:
|
||||||
var count = player_candies.get(pid, 0)
|
var count = player_candies.get(pid, 0)
|
||||||
@@ -395,31 +387,49 @@ func try_knock(attacker: int, target: int) -> bool:
|
|||||||
return false
|
return false
|
||||||
if player_ghost_active.get(target, false):
|
if player_ghost_active.get(target, false):
|
||||||
return false
|
return false
|
||||||
if player_knocks.get(attacker, 0) <= 0:
|
if not player_knocks.has(attacker):
|
||||||
|
player_knocks[attacker] = START_KNOCK
|
||||||
|
if player_knocks[attacker] <= 0:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
var target_colors = player_candy_colors.get(target, [])
|
var target_colors = player_candy_colors.get(target, [])
|
||||||
var target_candies = target_colors.size()
|
var target_candies = target_colors.size()
|
||||||
|
|
||||||
var attacker_node = main_scene.get_node_or_null(str(attacker))
|
var attacker_node = _find_player_node(attacker)
|
||||||
var target_node = main_scene.get_node_or_null(str(target))
|
var target_node = _find_player_node(target)
|
||||||
|
|
||||||
if attacker_node and target_node:
|
if attacker_node and target_node:
|
||||||
attacker_node.rpc("sync_bump", target_node.current_position)
|
attacker_node.rpc("sync_bump", target_node.current_position)
|
||||||
|
|
||||||
if target_candies == 0:
|
if target_candies == 0:
|
||||||
# Backfire: both lose a charge
|
# Backfire: attacker loses a charge & gets staggered
|
||||||
player_knocks[attacker] = player_knocks.get(attacker, 0) - 1
|
player_knocks[attacker] = player_knocks.get(attacker, START_KNOCK) - 1
|
||||||
rpc("sync_knock_charge_count", attacker, player_knocks[attacker])
|
rpc("sync_knock_charge_count", attacker, player_knocks[attacker])
|
||||||
|
|
||||||
# Attacker is also knocked down briefly (backfire)
|
# Attacker is knocked down briefly (backfire)
|
||||||
if attacker_node:
|
if attacker_node:
|
||||||
attacker_node.rpc("apply_stagger", 2.0)
|
attacker_node.rpc("apply_stagger", 2.0)
|
||||||
|
|
||||||
|
# Backfire penalty: Attacker's candy stack transfers to Target!
|
||||||
|
var attacker_colors = player_candy_colors.get(attacker, [])
|
||||||
|
var attacker_candies = attacker_colors.size()
|
||||||
|
if attacker_candies > 0:
|
||||||
|
if not player_candy_colors.has(target):
|
||||||
|
player_candy_colors[target] = []
|
||||||
|
player_candy_colors[target].append_array(attacker_colors)
|
||||||
|
player_candy_colors[attacker] = []
|
||||||
|
|
||||||
|
player_candies[target] = player_candy_colors[target].size()
|
||||||
|
player_candies[attacker] = 0
|
||||||
|
|
||||||
|
_add_score(target, attacker_candies * 100)
|
||||||
|
_update_candy_badge(attacker)
|
||||||
|
_update_candy_badge(target)
|
||||||
|
|
||||||
rpc("sync_knock_result", attacker, target, 0)
|
rpc("sync_knock_result", attacker, target, 0)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# Steal all candies
|
# Steal all candies (Successful knock)
|
||||||
if not player_candy_colors.has(attacker):
|
if not player_candy_colors.has(attacker):
|
||||||
player_candy_colors[attacker] = []
|
player_candy_colors[attacker] = []
|
||||||
player_candy_colors[attacker].append_array(target_colors)
|
player_candy_colors[attacker].append_array(target_colors)
|
||||||
@@ -428,7 +438,7 @@ func try_knock(attacker: int, target: int) -> bool:
|
|||||||
player_candies[attacker] = player_candy_colors[attacker].size()
|
player_candies[attacker] = player_candy_colors[attacker].size()
|
||||||
player_candies[target] = 0
|
player_candies[target] = 0
|
||||||
|
|
||||||
player_knocks[attacker] = player_knocks.get(attacker, 0) - 1
|
player_knocks[attacker] = player_knocks.get(attacker, START_KNOCK) - 1
|
||||||
rpc("sync_knock_charge_count", attacker, player_knocks[attacker])
|
rpc("sync_knock_charge_count", attacker, player_knocks[attacker])
|
||||||
player_last_knocked_by[target] = attacker
|
player_last_knocked_by[target] = attacker
|
||||||
|
|
||||||
@@ -567,7 +577,24 @@ func _add_score(pid: int, points: int) -> void:
|
|||||||
func _get_player_ids() -> Array:
|
func _get_player_ids() -> Array:
|
||||||
if main_scene and main_scene.has_method("get_player_ids"):
|
if main_scene and main_scene.has_method("get_player_ids"):
|
||||||
return main_scene.get_player_ids()
|
return main_scene.get_player_ids()
|
||||||
return []
|
var pids: Array = []
|
||||||
|
for p in get_tree().get_nodes_in_group("Players"):
|
||||||
|
if not is_instance_valid(p): continue
|
||||||
|
var pid = p.get("peer_id") if "peer_id" in p else p.name.to_int()
|
||||||
|
if pid != 0 and not pids.has(pid):
|
||||||
|
pids.append(pid)
|
||||||
|
return pids
|
||||||
|
|
||||||
|
func _find_player_node(pid: int) -> Node:
|
||||||
|
if main_scene:
|
||||||
|
var n = main_scene.get_node_or_null(str(pid))
|
||||||
|
if n: return n
|
||||||
|
for p in get_tree().get_nodes_in_group("Players"):
|
||||||
|
if not is_instance_valid(p): continue
|
||||||
|
var p_id = p.get("peer_id") if "peer_id" in p else p.name.to_int()
|
||||||
|
if p_id == pid:
|
||||||
|
return p
|
||||||
|
return null
|
||||||
|
|
||||||
func candy_survival_round_duration() -> int:
|
func candy_survival_round_duration() -> int:
|
||||||
return 180
|
return 180
|
||||||
@@ -577,10 +604,18 @@ func get_score(pid: int) -> int:
|
|||||||
|
|
||||||
# ── RPCs (stubs — HUD client handles visuals) ──
|
# ── RPCs (stubs — HUD client handles visuals) ──
|
||||||
|
|
||||||
@rpc("authority", "call_remote", "unreliable")
|
@rpc("authority", "call_local", "reliable")
|
||||||
func sync_candy_badge(pid: int, count: int, mult: float, face_match: bool, score: int, colors: Array) -> void:
|
func sync_candy_badge(pid: int, count: int, mult: float, face_match: bool, score: int, colors: Array) -> void:
|
||||||
if not active:
|
if not active:
|
||||||
activate_client_side()
|
activate_client_side()
|
||||||
|
player_candies[pid] = count
|
||||||
|
player_candy_colors[pid] = colors
|
||||||
|
player_score[pid] = score
|
||||||
|
|
||||||
|
var p_node = _find_player_node(pid)
|
||||||
|
if p_node and p_node.has_method("sync_candy_stack"):
|
||||||
|
p_node.sync_candy_stack(colors)
|
||||||
|
|
||||||
if pid == multiplayer.get_unique_id():
|
if pid == multiplayer.get_unique_id():
|
||||||
_last_badge_count = count
|
_last_badge_count = count
|
||||||
_last_badge_mult = mult
|
_last_badge_mult = mult
|
||||||
@@ -644,7 +679,7 @@ func _restore_delivery_indicator() -> void:
|
|||||||
else:
|
else:
|
||||||
hud_delivery_indicator.text = ""
|
hud_delivery_indicator.text = ""
|
||||||
|
|
||||||
@rpc("authority", "call_remote", "unreliable")
|
@rpc("authority", "call_local", "reliable")
|
||||||
func sync_knock_result(attacker: int, target: int, candies: int) -> void:
|
func sync_knock_result(attacker: int, target: int, candies: int) -> void:
|
||||||
if not active:
|
if not active:
|
||||||
activate_client_side()
|
activate_client_side()
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ func handle_unhandled_input(event):
|
|||||||
# 2. Action Buttons (Remappable via InputMap / KEY_Q override for Candy Survival)
|
# 2. Action Buttons (Remappable via InputMap / KEY_Q override for Candy Survival)
|
||||||
var is_knock = false
|
var is_knock = false
|
||||||
if LobbyManager.game_mode == "Candy Survival":
|
if LobbyManager.game_mode == "Candy Survival":
|
||||||
is_knock = (event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_Q) or event.is_action_pressed("action_knock_tekton")
|
is_knock = (event is InputEventKey and event.pressed and not event.echo and (event.keycode == KEY_Q or event.physical_keycode == KEY_Q)) or event.is_action_pressed("action_knock_tekton")
|
||||||
else:
|
else:
|
||||||
is_knock = event.is_action_pressed("action_knock_tekton")
|
is_knock = event.is_action_pressed("action_knock_tekton")
|
||||||
|
|
||||||
@@ -120,21 +120,25 @@ func handle_unhandled_input(event):
|
|||||||
var gm = player.get_node_or_null("/root/Main/CandySurvivalManager")
|
var gm = player.get_node_or_null("/root/Main/CandySurvivalManager")
|
||||||
if gm and gm.active:
|
if gm and gm.active:
|
||||||
var att_id = player.get("peer_id") if "peer_id" in player else player.name.to_int()
|
var att_id = player.get("peer_id") if "peer_id" in player else player.name.to_int()
|
||||||
if gm.player_knocks.get(att_id, 0) <= 0:
|
if gm.player_knocks.get(att_id, 5) <= 0:
|
||||||
NotificationManager.send_message(player, "No Knock charges left!", NotificationManager.MessageType.WARNING)
|
NotificationManager.send_message(player, "No Knock charges left!", NotificationManager.MessageType.WARNING)
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Find a target to knock (first adjacent player)
|
# Find a target to knock (adjacent player: cardinal or diagonal distance <= 1)
|
||||||
var p_pos = player.current_position
|
var p_pos = player.current_position
|
||||||
var all_players = get_tree().get_nodes_in_group("Players")
|
var all_players = get_tree().get_nodes_in_group("Players")
|
||||||
var target_found = null
|
var target_found = null
|
||||||
|
var min_dist = 999
|
||||||
for other in all_players:
|
for other in all_players:
|
||||||
if other == player: continue
|
if other == player or not is_instance_valid(other): continue
|
||||||
var other_pos = other.current_position
|
var other_pos = other.current_position
|
||||||
if abs(p_pos.x - other_pos.x) + abs(p_pos.y - other_pos.y) == 1:
|
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
|
target_found = other
|
||||||
break
|
min_dist = dist
|
||||||
|
if dist == 1:
|
||||||
|
break
|
||||||
|
|
||||||
if target_found:
|
if target_found:
|
||||||
var tgt_id = target_found.get("peer_id") if "peer_id" in target_found else target_found.name.to_int()
|
var tgt_id = target_found.get("peer_id") if "peer_id" in target_found else target_found.name.to_int()
|
||||||
|
|||||||
Reference in New Issue
Block a user