88 lines
2.4 KiB
GDScript
88 lines
2.4 KiB
GDScript
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:
|
|
# First check if goals are already achieved
|
|
if is_goals_achieved(actor):
|
|
blackboard.set_value("current_action", "idle")
|
|
return FAILURE
|
|
|
|
if actor.action_points < 2:
|
|
return FAILURE
|
|
|
|
var arrangement = find_best_arrangement(actor)
|
|
if arrangement.is_empty():
|
|
return FAILURE
|
|
|
|
blackboard.set_value("source_slot", arrangement.source_slot)
|
|
blackboard.set_value("target_slot", arrangement.target_slot)
|
|
|
|
# Do the arrangement
|
|
if actor.is_multiplayer_authority():
|
|
var item = actor.playerboard[arrangement.source_slot]
|
|
actor.playerboard[arrangement.target_slot] = item
|
|
actor.playerboard[arrangement.source_slot] = -1
|
|
actor.rpc("sync_playerboard", actor.playerboard)
|
|
actor.has_performed_action = true
|
|
actor.action_points -= 2
|
|
|
|
return SUCCESS
|