Refactor item grabbing logic and remove TileGrabber
Moved item grabbing and auto-arrange logic from the separate TileGrabber node into the player.gd script, consolidating server/client authority checks and RPC handling for multiplayer. Removed obsolete tile_grabber.gd and its UID file. Updated main.tscn to clean up unused UI nodes and adjust visibility settings for player boards.
This commit is contained in:
+157
-19
@@ -947,6 +947,9 @@ func bot_try_grab_item() -> bool:
|
||||
|
||||
return false
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# OLD GRAB Func
|
||||
# -----------------------------------------------------------------
|
||||
#func grab_item(grid_position: Vector2i = current_position) -> bool:
|
||||
#if is_bot:
|
||||
#return bot_try_grab_item()
|
||||
@@ -995,15 +998,60 @@ func bot_try_grab_item() -> bool:
|
||||
#return true
|
||||
#
|
||||
#return false
|
||||
|
||||
func grab_item(grid_position: Vector2i = current_position) -> bool:
|
||||
# -----------------------------------------------------------------
|
||||
#func grab_item(grid_position: Vector2i = current_position) -> bool:
|
||||
#if not enhanced_gridmap or action_points <= 0:
|
||||
#return false
|
||||
#
|
||||
#var cell = Vector3i(grid_position.x, 1, grid_position.y)
|
||||
#var item = enhanced_gridmap.get_cell_item(cell)
|
||||
#
|
||||
## Validate adjacency (unless it's current position)
|
||||
#if grid_position != current_position:
|
||||
#var neighbors = enhanced_gridmap.get_neighbors(current_position, 0)
|
||||
#var is_adjacent = false
|
||||
#for neighbor in neighbors:
|
||||
#if neighbor.position == grid_position:
|
||||
#is_adjacent = true
|
||||
#break
|
||||
#if not is_adjacent:
|
||||
#return false
|
||||
#
|
||||
#if item == -1:
|
||||
#return false
|
||||
#
|
||||
## === AUTO-ARRANGE LOGIC ===
|
||||
#var target_slot = find_best_goal_slot_for_item(item)
|
||||
#if target_slot == -1:
|
||||
#return false # no space
|
||||
#
|
||||
## Perform the grab and auto-place
|
||||
#if is_multiplayer_authority():
|
||||
## Update gridmap: remove item
|
||||
#rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)
|
||||
## Update playerboard
|
||||
#playerboard[target_slot] = item
|
||||
#rpc("sync_playerboard", playerboard)
|
||||
## Consume action
|
||||
#has_performed_action = true
|
||||
#consume_action_points(1)
|
||||
#
|
||||
## Optional: visual feedback
|
||||
#var main = get_tree().get_root().get_node_or_null("Main")
|
||||
#if main:
|
||||
#main.update_playerboard_ui()
|
||||
#main.set_action_state(main.ActionState.NONE)
|
||||
#
|
||||
#return true
|
||||
# -----------------------------------------------------------------
|
||||
func grab_item(grid_position: Vector2i = current_position) -> bool:
|
||||
if not enhanced_gridmap or action_points <= 0:
|
||||
return false
|
||||
|
||||
var cell = Vector3i(grid_position.x, 1, grid_position.y)
|
||||
var item = enhanced_gridmap.get_cell_item(cell)
|
||||
|
||||
# Validate adjacency (unless it's current position)
|
||||
# Validate adjacency (unless it's current position)
|
||||
if grid_position != current_position:
|
||||
var neighbors = enhanced_gridmap.get_neighbors(current_position, 0)
|
||||
var is_adjacent = false
|
||||
@@ -1017,32 +1065,108 @@ func grab_item(grid_position: Vector2i = current_position) -> bool:
|
||||
if item == -1:
|
||||
return false
|
||||
|
||||
# === AUTO-ARRANGE LOGIC ===
|
||||
# === AUTO-ARRANGE LOGIC (Client-side pre-check) ===
|
||||
var target_slot = find_best_goal_slot_for_item(item)
|
||||
if target_slot == -1:
|
||||
print("Player: No valid slot found for item.")
|
||||
return false # no space
|
||||
|
||||
# Perform the grab and auto-place
|
||||
if is_multiplayer_authority():
|
||||
# Update gridmap: remove item
|
||||
rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)
|
||||
# Update playerboard
|
||||
playerboard[target_slot] = item
|
||||
rpc("sync_playerboard", playerboard)
|
||||
# Consume action
|
||||
has_performed_action = true
|
||||
consume_action_points(1)
|
||||
if not is_multiplayer_authority():
|
||||
return false
|
||||
|
||||
# Optional: visual feedback
|
||||
var main = get_tree().get_root().get_node_or_null("Main")
|
||||
if main:
|
||||
main.update_playerboard_ui()
|
||||
main.set_action_state(main.ActionState.NONE)
|
||||
# === Branching Logic: Host vs Client ===
|
||||
if multiplayer.is_server():
|
||||
# HOST/SERVER: Call the logic directly
|
||||
_execute_grab(grid_position, cell, item)
|
||||
else:
|
||||
# CLIENT: Send RPC request to server (peer 1)
|
||||
rpc_id(1, "request_server_grab", grid_position, cell.x, cell.y, cell.z, item)
|
||||
|
||||
return true # Request was sent or processed
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Execute Grab
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
func _execute_grab(grid_pos: Vector2i, cell: Vector3i, item_id: int):
|
||||
var main = get_tree().get_root().get_node_or_null("Main")
|
||||
if not main:
|
||||
push_error("Server: Main node not found.")
|
||||
return false
|
||||
|
||||
var server_gridmap = main.get_node("EnhancedGridMap")
|
||||
if not server_gridmap:
|
||||
push_error("Server: EnhancedGridMap not found.")
|
||||
return false
|
||||
|
||||
# 1. Server-side Validation
|
||||
var server_item = server_gridmap.get_cell_item(cell)
|
||||
|
||||
# Check if item is still there
|
||||
if server_item != item_id:
|
||||
print("Server: Item mismatch or already taken. Server has ", server_item)
|
||||
return false
|
||||
|
||||
# Check action points
|
||||
if action_points <= 0:
|
||||
print("Server: Player has no action points.")
|
||||
return false
|
||||
|
||||
# Check adjacency
|
||||
if grid_pos != current_position:
|
||||
var neighbors = server_gridmap.get_neighbors(current_position, 0)
|
||||
if not neighbors.any(func(n): return n.position == grid_pos):
|
||||
print("Server: Player is not adjacent to item.")
|
||||
return false
|
||||
|
||||
# 2. Server-side Auto-Arrange
|
||||
var target_slot = find_best_goal_slot_for_item(item_id)
|
||||
if target_slot == -1:
|
||||
print("Server: Player has no valid slot for item.")
|
||||
return false
|
||||
|
||||
# 3. Server Executes the Action
|
||||
|
||||
# 3a. Update gridmap (using Main's RPC, which has authority)
|
||||
main.rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)
|
||||
|
||||
# 3b. Update playerboard state (on this server-side instance)
|
||||
playerboard[target_slot] = item_id
|
||||
|
||||
# 3c. Broadcast the new playerboard state to all clients
|
||||
rpc("sync_playerboard", playerboard)
|
||||
|
||||
# 3d. Consume action points
|
||||
has_performed_action = true
|
||||
consume_action_points(1)
|
||||
|
||||
# 3e. Reset the UI for the player who acted
|
||||
# This will RPC to the client, or run locally for the host
|
||||
rpc("force_action_state_none")
|
||||
|
||||
return true
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# This function runs on the server when requested by a client
|
||||
# -----------------------------------------------------------------
|
||||
@rpc("any_peer", "reliable")
|
||||
func request_server_grab(grid_pos: Vector2i, x: int, y: int, z: int, item_id: int):
|
||||
# 1. Only the server (peer 1) should process this
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
# 2. Security check: Did this request come from the actual owner of this node?
|
||||
if multiplayer.get_remote_sender_id() != get_multiplayer_authority():
|
||||
push_error("Security: Non-authority tried to grab item!")
|
||||
return
|
||||
|
||||
# 3. Call the execution logic
|
||||
_execute_grab(grid_pos, Vector3i(x, y, z), item_id)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Auto-put: no manual selection needed
|
||||
# Automatically puts a goal-matching tile into an adjacent (or current) empty grid cell
|
||||
# -----------------------------------------------------------------
|
||||
func auto_put_item() -> bool:
|
||||
if not enhanced_gridmap or action_points <= 0 or is_bot or is_in_group("Bots"):
|
||||
return false
|
||||
@@ -1134,6 +1258,20 @@ func auto_put_item() -> bool:
|
||||
|
||||
return true
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Force ActionState : None
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
@rpc("authority", "reliable")
|
||||
func force_action_state_none():
|
||||
# This is called by the server on the client to reset the UI
|
||||
var main = get_tree().get_root().get_node_or_null("Main")
|
||||
if main:
|
||||
main.set_action_state(main.ActionState.NONE)
|
||||
clear_highlights()
|
||||
clear_playerboard_highlights()
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
@rpc("any_peer", "reliable")
|
||||
func request_server_put(grid_position: Vector2i, slot_index: int, x: int, y: int, z: int, item: int):
|
||||
|
||||
Reference in New Issue
Block a user