Update
This commit is contained in:
@@ -48,15 +48,29 @@ func grab_item(grid_position: Vector2i) -> bool:
|
||||
if not player.is_multiplayer_authority():
|
||||
return false
|
||||
|
||||
# === Branching Logic: Host vs Client ===
|
||||
# === Optimistic Local Update (immediate visual feedback) ===
|
||||
# Apply changes locally first, server will validate/sync
|
||||
enhanced_gridmap.set_cell_item(cell, -1) # Remove item visually immediately
|
||||
player.playerboard[target_slot] = item # Add to playerboard immediately
|
||||
|
||||
# Update UI immediately for responsiveness
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
if main and main.ui_manager:
|
||||
main.ui_manager.update_playerboard_ui()
|
||||
|
||||
# === Server Sync ===
|
||||
if multiplayer.is_server():
|
||||
# HOST/SERVER: Call the logic directly
|
||||
_execute_grab(grid_position, cell, item)
|
||||
# HOST/SERVER: Broadcast to all clients
|
||||
main.rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)
|
||||
player.rpc("sync_playerboard", player.playerboard)
|
||||
player.has_performed_action = true
|
||||
player.consume_action_points(1)
|
||||
player.rpc("force_action_state_none")
|
||||
else:
|
||||
# CLIENT: Send RPC request to server (peer 1)
|
||||
# CLIENT: Send RPC request to server for validation
|
||||
player.rpc_id(1, "request_server_grab", grid_position, cell.x, cell.y, cell.z, item)
|
||||
|
||||
return true # Request was sent or processed
|
||||
return true # Action applied locally
|
||||
|
||||
func _execute_grab(grid_pos: Vector2i, cell: Vector3i, item_id: int):
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
@@ -178,10 +192,10 @@ func auto_put_item() -> bool:
|
||||
if valid_put_positions.is_empty():
|
||||
return false
|
||||
|
||||
# Step 2: Find a tile that should NOT be on the board
|
||||
# Step 2: Find a tile that should NOT be on the board (prioritize non-goal items)
|
||||
var put_slot = -1
|
||||
|
||||
# Count how many times each goal item appears in central 3x3
|
||||
# Count how many times each goal item is needed in the goals
|
||||
var goal_counts = {}
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
@@ -189,31 +203,18 @@ func auto_put_item() -> bool:
|
||||
if g != -1:
|
||||
goal_counts[g] = goal_counts.get(g, 0) + 1
|
||||
|
||||
# Now scan playerboard
|
||||
# Priority 1: Find items that are NOT in goals at all (junk tiles)
|
||||
for i in range(player.playerboard.size()):
|
||||
var current_item = player.playerboard[i]
|
||||
if current_item == -1:
|
||||
continue
|
||||
|
||||
# Case 1: Item is not in goals at all → definitely junk
|
||||
# Item is not in goals at all → definitely junk, put this first
|
||||
if not current_item in player.goals:
|
||||
put_slot = i
|
||||
break
|
||||
|
||||
# Case 2: Item is in goals, but we already have enough in correct spots
|
||||
var current_count = 0
|
||||
for r in range(1, 4): # central rows 1-3 (5x5 board)
|
||||
for c in range(1, 4): # central cols 1-3
|
||||
var idx = r * 5 + c
|
||||
if player.playerboard[idx] == current_item:
|
||||
current_count += 1
|
||||
|
||||
# If we already have all needed copies in central area, this is extra
|
||||
if current_count >= goal_counts.get(current_item, 0):
|
||||
put_slot = i
|
||||
break
|
||||
|
||||
# If no junk found, fall back to any non-goal-matching tile outside center
|
||||
# Priority 2: Find items outside central 3x3 OR items in central 3x3 that don't match goal position
|
||||
if put_slot == -1:
|
||||
for i in range(player.playerboard.size()):
|
||||
var board_item = player.playerboard[i]
|
||||
@@ -221,31 +222,75 @@ func auto_put_item() -> bool:
|
||||
continue
|
||||
var row = i / 5
|
||||
var col = i % 5
|
||||
# If it's outside the central 3x3, it shouldn't be there
|
||||
|
||||
# If it's outside the central 3x3, it's potentially movable
|
||||
if row < 1 or row > 3 or col < 1 or col > 3:
|
||||
if not board_item in player.goals or player.playerboard[i] != player.goals[(row - 1) * 3 + (col - 1)]:
|
||||
put_slot = i
|
||||
break
|
||||
else:
|
||||
# It's inside central 3x3 - check if it matches the corresponding goal position
|
||||
var goal_row = row - 1
|
||||
var goal_col = col - 1
|
||||
var expected_goal = player.goals[goal_row * 3 + goal_col]
|
||||
# If the item doesn't match what should be in this goal position, it's misplaced
|
||||
if board_item != expected_goal and expected_goal != -1:
|
||||
put_slot = i
|
||||
break
|
||||
|
||||
# Priority 3: Find excess goal items (we have more than needed in central area)
|
||||
if put_slot == -1:
|
||||
for i in range(player.playerboard.size()):
|
||||
var current_item = player.playerboard[i]
|
||||
if current_item == -1:
|
||||
continue
|
||||
if not current_item in player.goals:
|
||||
continue
|
||||
|
||||
# Count how many of this item we have in the correct central positions
|
||||
var correctly_placed_count = 0
|
||||
for goal_row in range(3):
|
||||
for goal_col in range(3):
|
||||
if player.goals[goal_row * 3 + goal_col] == current_item:
|
||||
var board_idx = (goal_row + 1) * 5 + (goal_col + 1)
|
||||
if player.playerboard[board_idx] == current_item:
|
||||
correctly_placed_count += 1
|
||||
|
||||
# Count total of this item on the board
|
||||
var total_count = 0
|
||||
for board_item in player.playerboard:
|
||||
if board_item == current_item:
|
||||
total_count += 1
|
||||
|
||||
# If we have all needed copies already correctly placed, extras can go
|
||||
if correctly_placed_count >= goal_counts.get(current_item, 0) and total_count > correctly_placed_count:
|
||||
put_slot = i
|
||||
break
|
||||
|
||||
if put_slot == -1:
|
||||
return false # Nothing suitable to put
|
||||
|
||||
# Step 3: Perform the put
|
||||
# Step 3: Perform the put with optimistic local update
|
||||
var target_pos = valid_put_positions[0]
|
||||
var item = player.playerboard[put_slot]
|
||||
var cell = Vector3i(target_pos.x, 1, target_pos.y)
|
||||
|
||||
if player.is_multiplayer_authority():
|
||||
# === Optimistic Local Update (immediate visual feedback) ===
|
||||
enhanced_gridmap.set_cell_item(cell, item) # Add item to grid visually immediately
|
||||
player.playerboard[put_slot] = -1 # Remove from playerboard immediately
|
||||
|
||||
# Update UI immediately for responsiveness
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
if main and main.ui_manager:
|
||||
main.ui_manager.update_playerboard_ui()
|
||||
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
||||
|
||||
# === Server Sync ===
|
||||
player.rpc("sync_grid_item", cell.x, cell.y, cell.z, item)
|
||||
player.playerboard[put_slot] = -1
|
||||
player.rpc("sync_playerboard", player.playerboard)
|
||||
player.has_performed_action = true
|
||||
player.consume_action_points(1)
|
||||
|
||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||
if main and main.ui_manager:
|
||||
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
||||
|
||||
return true
|
||||
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user