update
This commit is contained in:
+7
-4
@@ -158,11 +158,14 @@ func update_button_states():
|
|||||||
randomize_button.visible = true
|
randomize_button.visible = true
|
||||||
arrange_button.visible = true
|
arrange_button.visible = true
|
||||||
|
|
||||||
move_button.disabled = local_player_character.is_player_moving or local_player_character.has_performed_action
|
# Only keep randomize button's disable condition
|
||||||
grab_button.disabled = not local_player_character.has_item_at_current_position()
|
|
||||||
put_button.disabled = not (local_player_character.has_items_in_playerboard() and not local_player_character.has_item_at_current_position())
|
|
||||||
randomize_button.disabled = local_player_character.has_performed_action
|
randomize_button.disabled = local_player_character.has_performed_action
|
||||||
arrange_button.disabled = not local_player_character.has_items_in_playerboard()
|
|
||||||
|
# Remove disabled conditions for other buttons:
|
||||||
|
move_button.disabled = false
|
||||||
|
grab_button.disabled = false
|
||||||
|
put_button.disabled = false
|
||||||
|
arrange_button.disabled = false
|
||||||
|
|
||||||
func _on_playerboard_slot_clicked(event, slot_index):
|
func _on_playerboard_slot_clicked(event, slot_index):
|
||||||
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
||||||
|
|||||||
@@ -1,24 +1,85 @@
|
|||||||
extends ActionLeaf
|
extends ActionLeaf
|
||||||
|
|
||||||
|
func find_best_arrangement(actor) -> Dictionary:
|
||||||
|
# Convert goals to 2D array for easier comparison
|
||||||
|
var goals_2d = []
|
||||||
|
for i in range(3):
|
||||||
|
var row = []
|
||||||
|
for j in range(3):
|
||||||
|
row.append(actor.goals[i * 3 + j])
|
||||||
|
goals_2d.append(row)
|
||||||
|
|
||||||
|
# Convert playerboard to 2D
|
||||||
|
var board_2d = []
|
||||||
|
for i in range(5):
|
||||||
|
var row = []
|
||||||
|
for j in range(5):
|
||||||
|
row.append(actor.playerboard[i * 5 + j])
|
||||||
|
board_2d.append(row)
|
||||||
|
|
||||||
|
# Find misplaced items
|
||||||
|
for i in range(1, 4): # Check central 3x3 area
|
||||||
|
for j in range(1, 4):
|
||||||
|
var board_idx = i * 5 + j
|
||||||
|
var goal_idx = (i - 1) * 3 + (j - 1)
|
||||||
|
|
||||||
|
var current_item = actor.playerboard[board_idx]
|
||||||
|
var goal_item = actor.goals[goal_idx]
|
||||||
|
|
||||||
|
if current_item != goal_item and current_item != -1:
|
||||||
|
# Find better position for this item
|
||||||
|
for gi in range(3):
|
||||||
|
for gj in range(3):
|
||||||
|
if actor.goals[gi * 3 + gj] == current_item:
|
||||||
|
var target_slot = (gi + 1) * 5 + (gj + 1)
|
||||||
|
if actor.playerboard[target_slot] == -1:
|
||||||
|
return {
|
||||||
|
"source_slot": board_idx,
|
||||||
|
"target_slot": target_slot
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
func is_goals_achieved(actor) -> bool:
|
||||||
|
# Check only central 3x3 area of playerboard against goals
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
var board_idx = (i + 1) * 5 + (j + 1)
|
||||||
|
var goal_idx = i * 3 + j
|
||||||
|
|
||||||
|
if actor.goals[goal_idx] != -1 and actor.goals[goal_idx] != actor.playerboard[board_idx]:
|
||||||
|
return false
|
||||||
|
elif actor.goals[goal_idx] == -1 and actor.playerboard[board_idx] != -1:
|
||||||
|
return false
|
||||||
|
|
||||||
|
# Also check outside the goal area
|
||||||
|
if i == 0 or i == 4 or j == 0 or j == 4:
|
||||||
|
if actor.playerboard[i * 5 + j] != -1:
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
func tick(actor: Node, blackboard: Blackboard) -> int:
|
func tick(actor: Node, blackboard: Blackboard) -> int:
|
||||||
var source_slot = blackboard.get_value("source_slot")
|
# First check if goals are already achieved
|
||||||
var target_slot = blackboard.get_value("target_slot")
|
if is_goals_achieved(actor):
|
||||||
|
blackboard.set_value("current_action", "idle")
|
||||||
if source_slot == -1 or target_slot == -1:
|
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
# Verify conditions are still valid
|
if actor.action_points < 2:
|
||||||
if actor.action_points < 2 or actor.playerboard[source_slot] == -1:
|
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
if actor.playerboard[target_slot] != -1:
|
var arrangement = find_best_arrangement(actor)
|
||||||
|
if arrangement.is_empty():
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
|
blackboard.set_value("source_slot", arrangement.source_slot)
|
||||||
|
blackboard.set_value("target_slot", arrangement.target_slot)
|
||||||
|
|
||||||
# Do the arrangement
|
# Do the arrangement
|
||||||
if actor.is_multiplayer_authority():
|
if actor.is_multiplayer_authority():
|
||||||
var item = actor.playerboard[source_slot]
|
var item = actor.playerboard[arrangement.source_slot]
|
||||||
actor.playerboard[target_slot] = item
|
actor.playerboard[arrangement.target_slot] = item
|
||||||
actor.playerboard[source_slot] = -1
|
actor.playerboard[arrangement.source_slot] = -1
|
||||||
actor.rpc("sync_playerboard", actor.playerboard)
|
actor.rpc("sync_playerboard", actor.playerboard)
|
||||||
actor.has_performed_action = true
|
actor.has_performed_action = true
|
||||||
actor.action_points -= 2
|
actor.action_points -= 2
|
||||||
|
|||||||
@@ -1,28 +1,105 @@
|
|||||||
extends ActionLeaf
|
extends ActionLeaf
|
||||||
|
|
||||||
|
func is_goals_achieved(actor) -> bool:
|
||||||
|
# Convert goals to 2D for easier pattern matching
|
||||||
|
var goals_2d = []
|
||||||
|
for i in range(3):
|
||||||
|
var row = []
|
||||||
|
for j in range(3):
|
||||||
|
row.append(actor.goals[i * 3 + j])
|
||||||
|
goals_2d.append(row)
|
||||||
|
|
||||||
|
# Convert playerboard to 2D
|
||||||
|
var board_2d = []
|
||||||
|
for i in range(5):
|
||||||
|
var row = []
|
||||||
|
for j in range(5):
|
||||||
|
row.append(actor.playerboard[i * 5 + j])
|
||||||
|
board_2d.append(row)
|
||||||
|
|
||||||
|
# Check every possible 3x3 region in the 5x5 board
|
||||||
|
for start_row in range(3): # 5-3+1 possible start rows
|
||||||
|
for start_col in range(3): # 5-3+1 possible start columns
|
||||||
|
var matches = true
|
||||||
|
|
||||||
|
# Check if this 3x3 region matches the goals
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
var board_item = board_2d[start_row + i][start_col + j]
|
||||||
|
var goal_item = goals_2d[i][j]
|
||||||
|
|
||||||
|
if goal_item != -1 and goal_item != board_item:
|
||||||
|
matches = false
|
||||||
|
break
|
||||||
|
elif goal_item == -1 and board_item != -1:
|
||||||
|
matches = false
|
||||||
|
break
|
||||||
|
|
||||||
|
if not matches:
|
||||||
|
break
|
||||||
|
|
||||||
|
if matches:
|
||||||
|
return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
|
func find_target_slot(actor, item: int) -> int:
|
||||||
|
# Get the goals in 2D format (3x3)
|
||||||
|
var goals_2d = []
|
||||||
|
for i in range(3):
|
||||||
|
var row = []
|
||||||
|
for j in range(3):
|
||||||
|
row.append(actor.goals[i * 3 + j])
|
||||||
|
goals_2d.append(row)
|
||||||
|
|
||||||
|
# Convert playerboard to 2D (5x5)
|
||||||
|
var board_2d = []
|
||||||
|
for i in range(5):
|
||||||
|
var row = []
|
||||||
|
for j in range(5):
|
||||||
|
row.append(actor.playerboard[i * 5 + j])
|
||||||
|
board_2d.append(row)
|
||||||
|
|
||||||
|
# Find matching position in goals
|
||||||
|
var target_positions = []
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
if goals_2d[i][j] == item:
|
||||||
|
# Convert to playerboard position (centered in 5x5 grid)
|
||||||
|
target_positions.append(Vector2i(j + 1, i + 1))
|
||||||
|
|
||||||
|
# Find best empty slot that matches a goal position
|
||||||
|
for pos in target_positions:
|
||||||
|
var slot_index = (pos.y + 1) * 5 + (pos.x + 1)
|
||||||
|
if actor.playerboard[slot_index] == -1:
|
||||||
|
return slot_index
|
||||||
|
|
||||||
|
# If no matching position found, find any empty slot
|
||||||
|
return actor.playerboard.find(-1)
|
||||||
|
|
||||||
func tick(actor: Node, blackboard: Blackboard) -> int:
|
func tick(actor: Node, blackboard: Blackboard) -> int:
|
||||||
# Early validation for bots only
|
# Early validation
|
||||||
if not actor.is_bot or actor.action_points <= 0:
|
if not actor.is_bot or actor.action_points <= 0:
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
var grab_position = blackboard.get_value("grab_position")
|
var grab_position = blackboard.get_value("grab_position")
|
||||||
if not grab_position:
|
if not grab_position:
|
||||||
grab_position = actor.current_position # Default to current position if no target
|
return FAILURE
|
||||||
|
|
||||||
# Check if there's an item at the position first
|
# Check if there's an item
|
||||||
var cell = Vector3i(grab_position.x, 1, grab_position.y)
|
var cell = Vector3i(grab_position.x, 1, grab_position.y)
|
||||||
var item = actor.enhanced_gridmap.get_cell_item(cell)
|
var item = actor.enhanced_gridmap.get_cell_item(cell)
|
||||||
if item == -1:
|
if item == -1:
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
# Find empty slot in playerboard
|
# Find strategic slot
|
||||||
var empty_slot_idx = actor.playerboard.find(-1)
|
var target_slot = find_target_slot(actor, item)
|
||||||
if empty_slot_idx == -1:
|
if target_slot == -1:
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
# For bots, we bypass the usual visual feedback system
|
# Execute grab
|
||||||
if actor.is_multiplayer_authority():
|
if actor.is_multiplayer_authority():
|
||||||
actor.playerboard[empty_slot_idx] = item
|
actor.playerboard[target_slot] = item
|
||||||
actor.rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)
|
actor.rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)
|
||||||
actor.rpc("sync_playerboard", actor.playerboard)
|
actor.rpc("sync_playerboard", actor.playerboard)
|
||||||
actor.has_performed_action = true
|
actor.has_performed_action = true
|
||||||
|
|||||||
@@ -1,6 +1,21 @@
|
|||||||
extends ActionLeaf
|
extends ActionLeaf
|
||||||
|
|
||||||
|
func is_goals_achieved(actor) -> bool:
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
var board_idx = (i + 1) * 5 + (j + 1)
|
||||||
|
var goal_idx = i * 3 + j
|
||||||
|
if actor.goals[goal_idx] != -1 and actor.goals[goal_idx] != actor.playerboard[board_idx]:
|
||||||
|
return false
|
||||||
|
elif actor.goals[goal_idx] == -1 and actor.playerboard[board_idx] != -1:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
func tick(actor: Node, blackboard: Blackboard) -> int:
|
func tick(actor: Node, blackboard: Blackboard) -> int:
|
||||||
|
# Don't move if goals are achieved
|
||||||
|
if is_goals_achieved(actor):
|
||||||
|
return FAILURE
|
||||||
|
|
||||||
# Get target from blackboard
|
# Get target from blackboard
|
||||||
var target_pos = blackboard.get_value("move_target")
|
var target_pos = blackboard.get_value("move_target")
|
||||||
if not target_pos:
|
if not target_pos:
|
||||||
|
|||||||
@@ -1,5 +1,24 @@
|
|||||||
extends ActionLeaf
|
extends ActionLeaf
|
||||||
|
|
||||||
|
func is_goals_achieved(actor) -> bool:
|
||||||
|
# Check only central 3x3 area of playerboard against goals
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
var board_idx = (i + 1) * 5 + (j + 1)
|
||||||
|
var goal_idx = i * 3 + j
|
||||||
|
|
||||||
|
if actor.goals[goal_idx] != -1 and actor.goals[goal_idx] != actor.playerboard[board_idx]:
|
||||||
|
return false
|
||||||
|
elif actor.goals[goal_idx] == -1 and actor.playerboard[board_idx] != -1:
|
||||||
|
return false
|
||||||
|
|
||||||
|
# Also check outside the goal area
|
||||||
|
if i == 0 or i == 4 or j == 0 or j == 4:
|
||||||
|
if actor.playerboard[i * 5 + j] != -1:
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
func tick(actor: Node, blackboard: Blackboard) -> int:
|
func tick(actor: Node, blackboard: Blackboard) -> int:
|
||||||
var put_position = blackboard.get_value("put_position")
|
var put_position = blackboard.get_value("put_position")
|
||||||
var put_slot = blackboard.get_value("put_slot")
|
var put_slot = blackboard.get_value("put_slot")
|
||||||
@@ -16,7 +35,7 @@ func tick(actor: Node, blackboard: Blackboard) -> int:
|
|||||||
if actor.enhanced_gridmap.get_cell_item(cell) != -1:
|
if actor.enhanced_gridmap.get_cell_item(cell) != -1:
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
# Put the item
|
# Execute put
|
||||||
var item = actor.playerboard[put_slot]
|
var item = actor.playerboard[put_slot]
|
||||||
if actor.is_multiplayer_authority():
|
if actor.is_multiplayer_authority():
|
||||||
actor.rpc("sync_grid_item", cell.x, cell.y, cell.z, item)
|
actor.rpc("sync_grid_item", cell.x, cell.y, cell.z, item)
|
||||||
|
|||||||
@@ -1,6 +1,49 @@
|
|||||||
extends ConditionLeaf
|
extends ConditionLeaf
|
||||||
|
|
||||||
|
func is_goals_achieved(actor) -> bool:
|
||||||
|
# Convert goals to 2D for easier pattern matching
|
||||||
|
var goals_2d = []
|
||||||
|
for i in range(3):
|
||||||
|
var row = []
|
||||||
|
for j in range(3):
|
||||||
|
row.append(actor.goals[i * 3 + j])
|
||||||
|
goals_2d.append(row)
|
||||||
|
|
||||||
|
# Convert playerboard to 2D
|
||||||
|
var board_2d = []
|
||||||
|
for i in range(5):
|
||||||
|
var row = []
|
||||||
|
for j in range(5):
|
||||||
|
row.append(actor.playerboard[i * 5 + j])
|
||||||
|
board_2d.append(row)
|
||||||
|
|
||||||
|
# Check every possible 3x3 region in the 5x5 board
|
||||||
|
for start_row in range(3):
|
||||||
|
for start_col in range(3):
|
||||||
|
var matches = true
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
var board_item = board_2d[start_row + i][start_col + j]
|
||||||
|
var goal_item = goals_2d[i][j]
|
||||||
|
|
||||||
|
if goal_item != -1 and goal_item != board_item:
|
||||||
|
matches = false
|
||||||
|
break
|
||||||
|
elif goal_item == -1 and board_item != -1:
|
||||||
|
matches = false
|
||||||
|
break
|
||||||
|
if not matches:
|
||||||
|
break
|
||||||
|
if matches:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
func tick(actor: Node, blackboard: Blackboard) -> int:
|
func tick(actor: Node, blackboard: Blackboard) -> int:
|
||||||
|
# First check if goals are achieved
|
||||||
|
if is_goals_achieved(actor):
|
||||||
|
blackboard.set_value("current_action", "idle")
|
||||||
|
return FAILURE
|
||||||
|
|
||||||
if actor.playerboard_is_full():
|
if actor.playerboard_is_full():
|
||||||
return FAILURE
|
return FAILURE
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
extends ConditionLeaf
|
extends ConditionLeaf
|
||||||
|
|
||||||
|
func is_goals_achieved(actor) -> bool:
|
||||||
|
# ... same is_goals_achieved function as in can_grab.gd ...
|
||||||
|
return false
|
||||||
|
|
||||||
func tick(actor: Node, blackboard: Blackboard) -> int:
|
func tick(actor: Node, blackboard: Blackboard) -> int:
|
||||||
|
# First check if goals are achieved
|
||||||
|
if is_goals_achieved(actor):
|
||||||
|
blackboard.set_value("current_action", "idle")
|
||||||
|
return FAILURE
|
||||||
|
|
||||||
# Find an item in playerboard that matches goals
|
# Find an item in playerboard that matches goals
|
||||||
var put_slot = -1
|
var put_slot = -1
|
||||||
for i in range(actor.playerboard.size()):
|
for i in range(actor.playerboard.size()):
|
||||||
|
|||||||
Reference in New Issue
Block a user