This commit is contained in:
2025-01-28 14:17:29 +08:00
parent a43811fe77
commit 9640283964
22 changed files with 512 additions and 10 deletions
@@ -0,0 +1,22 @@
class_name ArrangeAction extends ActionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
var source_slot = blackboard.get_value("source_slot", -1)
var target_slot = blackboard.get_value("target_slot", -1)
if source_slot == -1 or target_slot == -1:
return FAILURE
if actor.action_points < 2:
return FAILURE
var selected_item = actor.playerboard[source_slot]
actor.playerboard[target_slot] = selected_item
actor.playerboard[source_slot] = -1
if actor.is_multiplayer_authority():
actor.rpc("sync_playerboard", actor.playerboard)
actor.action_points -= 2
actor.has_performed_action = true
return SUCCESS
@@ -0,0 +1,18 @@
class_name ArrangeCondition extends ConditionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
# Check we have enough action points
if actor.action_points < 2:
return FAILURE
# Check for items that can be arranged
for i in range(actor.playerboard.size()):
if actor.playerboard[i] != -1:
var neighbors = actor.get_adjacent_playerboard_slots(i)
for adj_slot in neighbors:
if actor.playerboard[adj_slot] == -1 and actor.playerboard[i] in actor.goals:
blackboard.set_value("source_slot", i)
blackboard.set_value("target_slot", adj_slot)
return SUCCESS
return FAILURE
@@ -0,0 +1,16 @@
extends ConditionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
if actor.action_points < 2:
return FAILURE
# Look for items that match goals
for i in range(actor.playerboard.size()):
if actor.playerboard[i] in actor.goals:
var neighbors = actor.get_adjacent_playerboard_slots(i)
for adj_slot in neighbors:
if actor.playerboard[adj_slot] == -1:
blackboard.set_value("source_slot", i)
blackboard.set_value("target_slot", adj_slot)
return SUCCESS
return FAILURE
+25
View File
@@ -0,0 +1,25 @@
extends ConditionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
if actor.playerboard_is_full():
return FAILURE
# Check current position
var current_cell = Vector3i(actor.current_position.x, 1, actor.current_position.y)
var item = actor.enhanced_gridmap.get_cell_item(current_cell)
if item in actor.goals:
blackboard.set_value("grab_position", actor.current_position)
return SUCCESS
# Check adjacent cells
var neighbors = actor.enhanced_gridmap.get_neighbors(actor.current_position, 0)
for neighbor in neighbors:
if not neighbor.is_walkable:
continue
var cell = Vector3i(neighbor.position.x, 1, neighbor.position.y)
item = actor.enhanced_gridmap.get_cell_item(cell)
if item in actor.goals:
blackboard.set_value("grab_position", neighbor.position)
return SUCCESS
return FAILURE
+31
View File
@@ -0,0 +1,31 @@
extends ConditionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
# Find an item in playerboard that matches goals
var put_slot = -1
for i in range(actor.playerboard.size()):
if actor.playerboard[i] in actor.goals:
put_slot = i
break
if put_slot == -1:
return FAILURE
# Find empty adjacent cell
var current_cell = Vector3i(actor.current_position.x, 1, actor.current_position.y)
if actor.enhanced_gridmap.get_cell_item(current_cell) == -1:
blackboard.set_value("put_position", actor.current_position)
blackboard.set_value("put_slot", put_slot)
return SUCCESS
var neighbors = actor.enhanced_gridmap.get_neighbors(actor.current_position, 0)
for neighbor in neighbors:
if not neighbor.is_walkable:
continue
var cell = Vector3i(neighbor.position.x, 1, neighbor.position.y)
if actor.enhanced_gridmap.get_cell_item(cell) == -1:
blackboard.set_value("put_position", neighbor.position)
blackboard.set_value("put_slot", put_slot)
return SUCCESS
return FAILURE
@@ -0,0 +1,21 @@
class_name GrabCondition extends ConditionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
if actor.action_points < 1 or actor.playerboard_is_full():
return FAILURE
# Check current position first
var current_cell = Vector3i(actor.current_position.x, 1, actor.current_position.y)
if actor.enhanced_gridmap.get_cell_item(current_cell) in actor.goals:
blackboard.set_value("grab_position", actor.current_position)
return SUCCESS
# Check adjacent cells
var neighbors = actor.enhanced_gridmap.get_neighbors(actor.current_position, 1)
for neighbor in neighbors:
var cell = Vector3i(neighbor.position.x, 1, neighbor.position.y)
if actor.enhanced_gridmap.get_cell_item(cell) in actor.goals:
blackboard.set_value("grab_position", neighbor.position)
return SUCCESS
return FAILURE
+6
View File
@@ -0,0 +1,6 @@
extends ConditionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
if actor.action_points >= 1:
return SUCCESS
return FAILURE
@@ -0,0 +1,85 @@
extends ConditionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
if actor.action_points <= 0:
return FAILURE
var target_pos = find_best_move_position(actor)
if target_pos == Vector2i(-1, -1):
return FAILURE
blackboard.set_value("move_target", target_pos)
return SUCCESS
func find_best_move_position(actor: Node) -> Vector2i:
# First priority: Move towards items that match our goals
var closest_goal_item = find_closest_goal_item(actor)
if closest_goal_item != Vector2i(-1, -1):
return get_position_towards(actor, closest_goal_item)
# Second priority: Move towards empty cells if we have items
if actor.has_items_in_playerboard():
var empty_pos = find_closest_empty_cell(actor)
if empty_pos != Vector2i(-1, -1):
return get_position_towards(actor, empty_pos)
# Last resort: Random valid move
return actor.find_random_valid_position_in_range()
func find_closest_goal_item(actor: Node) -> Vector2i:
var min_distance = 999999
var closest_pos = Vector2i(-1, -1)
for x in range(actor.enhanced_gridmap.columns):
for z in range(actor.enhanced_gridmap.rows):
var cell = Vector3i(x, 1, z)
var item = actor.enhanced_gridmap.get_cell_item(cell)
if item in actor.goals:
var dist = actor.current_position.distance_squared_to(Vector2i(x, z))
if dist < min_distance:
min_distance = dist
closest_pos = Vector2i(x, z)
return closest_pos
func find_closest_empty_cell(actor: Node) -> Vector2i:
var min_distance = 999999
var closest_pos = Vector2i(-1, -1)
for x in range(actor.enhanced_gridmap.columns):
for z in range(actor.enhanced_gridmap.rows):
var cell = Vector3i(x, 1, z)
if actor.enhanced_gridmap.get_cell_item(cell) == -1:
var dist = actor.current_position.distance_squared_to(Vector2i(x, z))
if dist < min_distance:
min_distance = dist
closest_pos = Vector2i(x, z)
return closest_pos
func get_position_towards(actor: Node, target: Vector2i) -> Vector2i:
# Find a valid position within movement range that's closest to target
var best_pos = Vector2i(-1, -1)
var min_distance = 999999
for x in range(actor.current_position.x - actor.movement_range,
actor.current_position.x + actor.movement_range + 1):
for z in range(actor.current_position.y - actor.movement_range,
actor.current_position.y + actor.movement_range + 1):
var pos = Vector2i(x, z)
if not actor.is_within_movement_range(pos):
continue
if actor.is_position_occupied(pos):
continue
var cell_item = actor.enhanced_gridmap.get_cell_item(Vector3i(x, 0, z))
if cell_item == -1 or cell_item in actor.enhanced_gridmap.non_walkable_items:
continue
var dist = pos.distance_squared_to(target)
if dist < min_distance:
min_distance = dist
best_pos = pos
return best_pos