implement auto tile pickup and visual candy stacking on player head
This commit is contained in:
@@ -601,6 +601,45 @@ func _get_all_mesh_instances(node: Node) -> Array:
|
|||||||
result.append_array(_get_all_mesh_instances(child))
|
result.append_array(_get_all_mesh_instances(child))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# RPCs
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
|
func sync_candy_stack(count: int, color_id: int) -> void:
|
||||||
|
var visuals = get_node_or_null("Visuals")
|
||||||
|
if not visuals: return
|
||||||
|
|
||||||
|
var old_stack = visuals.get_node_or_null("CandyStack")
|
||||||
|
if old_stack:
|
||||||
|
old_stack.queue_free()
|
||||||
|
|
||||||
|
if count <= 0: return
|
||||||
|
|
||||||
|
var stack_node = Node3D.new()
|
||||||
|
stack_node.name = "CandyStack"
|
||||||
|
visuals.add_child(stack_node)
|
||||||
|
|
||||||
|
stack_node.position = Vector3(0, 2.0, 0)
|
||||||
|
|
||||||
|
# Determine base tile and override material based on the mode config or default tile meshes
|
||||||
|
var mesh_path = "res://assets/models/tiles/tile_heart.tres"
|
||||||
|
match color_id:
|
||||||
|
0: mesh_path = "res://assets/models/tiles/tile_heart.tres"
|
||||||
|
1: mesh_path = "res://assets/models/tiles/tile_diamond.tres"
|
||||||
|
2: mesh_path = "res://assets/models/tiles/tile_star.tres"
|
||||||
|
3: mesh_path = "res://assets/models/tiles/tile_coin.tres"
|
||||||
|
|
||||||
|
var tile_mesh = load(mesh_path)
|
||||||
|
if not tile_mesh: return
|
||||||
|
|
||||||
|
for i in range(count):
|
||||||
|
var mi = MeshInstance3D.new()
|
||||||
|
mi.mesh = tile_mesh
|
||||||
|
mi.position = Vector3(0, i * 0.4, 0)
|
||||||
|
mi.scale = Vector3(0.5, 0.5, 0.5)
|
||||||
|
stack_node.add_child(mi)
|
||||||
|
|
||||||
@rpc("any_peer", "call_local", "reliable")
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
func sync_character(character_name: String) -> void:
|
func sync_character(character_name: String) -> void:
|
||||||
"""Sync character selection across all clients."""
|
"""Sync character selection across all clients."""
|
||||||
|
|||||||
@@ -253,8 +253,18 @@ func _give_candy(pid: int, color: int) -> void:
|
|||||||
func _update_candy_badge(pid: int) -> void:
|
func _update_candy_badge(pid: int) -> void:
|
||||||
var count = player_candies.get(pid, 0)
|
var count = player_candies.get(pid, 0)
|
||||||
var mult = 1.0 + count * MULTI_STEP
|
var mult = 1.0 + count * MULTI_STEP
|
||||||
|
var color = player_candy_color.get(pid, -1)
|
||||||
rpc("sync_candy_badge", pid, count, mult)
|
rpc("sync_candy_badge", pid, count, mult)
|
||||||
|
|
||||||
|
# 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", count, color)
|
||||||
|
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)
|
||||||
return 1.0 + count * MULTI_STEP
|
return 1.0 + count * MULTI_STEP
|
||||||
@@ -420,8 +430,8 @@ func setup_mission_tiles() -> void:
|
|||||||
func get_spawn_points(count: int) -> Array:
|
func get_spawn_points(count: int) -> Array:
|
||||||
var points = []
|
var points = []
|
||||||
var corners = [
|
var corners = [
|
||||||
Vector2i(2, 2), Vector2i(ARENA_COLS - 3, 2),
|
Vector2i(2, 2), Vector2i(ARENA_COLS - 2, 2),
|
||||||
Vector2i(2, ARENA_ROWS - 3), Vector2i(ARENA_COLS - 3, ARENA_ROWS - 3)
|
Vector2i(2, ARENA_ROWS - 2), Vector2i(ARENA_COLS - 2, ARENA_ROWS - 2)
|
||||||
]
|
]
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
points.append(corners[i % corners.size()])
|
points.append(corners[i % corners.size()])
|
||||||
|
|||||||
@@ -373,9 +373,18 @@ func set_speed_multiplier(multiplier: float):
|
|||||||
# likely uses a fixed speed or duration on all clients.
|
# likely uses a fixed speed or duration on all clients.
|
||||||
# Let's check how 'start_movement_along_path' is implemented in player.gd.
|
# Let's check how 'start_movement_along_path' is implemented in player.gd.
|
||||||
|
|
||||||
|
# Handle goal pickups (shared logic)
|
||||||
|
# ... (This happens after the move is completed, or during the move)
|
||||||
|
pass
|
||||||
|
|
||||||
func _on_movement_finished():
|
func _on_movement_finished():
|
||||||
|
# Auto-pickup logic for Candy Survival
|
||||||
|
if LobbyManager.game_mode == "Candy Survival":
|
||||||
|
if player.has_method("grab_item"):
|
||||||
|
# Check if there is an item at current_position and if the board has space
|
||||||
|
if player.playerboard_manager and player.playerboard_manager.has_empty_slot():
|
||||||
|
player.grab_item(player.current_position)
|
||||||
|
|
||||||
if not movement_queue.is_empty():
|
if not movement_queue.is_empty():
|
||||||
var next_target = movement_queue.pop_front()
|
var next_target = movement_queue.pop_front()
|
||||||
# Use a small delay or call_deferred to avoid recursion issues,
|
# Use a small delay or call_deferred to avoid recursion issues,
|
||||||
@@ -386,6 +395,7 @@ func _on_movement_finished():
|
|||||||
current_move_direction = Vector2i.ZERO
|
current_move_direction = Vector2i.ZERO
|
||||||
emit_signal("movement_finished")
|
emit_signal("movement_finished")
|
||||||
else:
|
else:
|
||||||
|
is_moving = false
|
||||||
current_move_direction = Vector2i.ZERO
|
current_move_direction = Vector2i.ZERO
|
||||||
emit_signal("movement_finished")
|
emit_signal("movement_finished")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user