update bot logic
This commit is contained in:
@@ -23,3 +23,16 @@ window/size/viewport_height=720
|
|||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/enhanced_gridmap/plugin.cfg")
|
enabled=PackedStringArray("res://addons/enhanced_gridmap/plugin.cfg")
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
grab_item={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
put_item={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
+123
-21
@@ -214,37 +214,139 @@ func _on_message_input_text_submitted(new_text):
|
|||||||
$MessageInput.text = ""
|
$MessageInput.text = ""
|
||||||
$MessageInput.release_focus()
|
$MessageInput.release_focus()
|
||||||
|
|
||||||
|
# ---------
|
||||||
|
# Bot Logic
|
||||||
|
# ---------
|
||||||
|
func evaluate_bot_move(bot: Node) -> Dictionary:
|
||||||
|
var best_move = {
|
||||||
|
"action": "none",
|
||||||
|
"position": bot.current_position,
|
||||||
|
"value": -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# If no action performed yet, prioritize grab/put
|
||||||
|
if not bot.has_performed_action:
|
||||||
|
# Check current position for grabbing
|
||||||
|
var current_cell = Vector3i(bot.current_position.x, 1, bot.current_position.y)
|
||||||
|
var current_item = bot.enhanced_gridmap.get_cell_item(current_cell)
|
||||||
|
|
||||||
|
# Evaluate grabbing current item if it matches goals
|
||||||
|
if current_item != -1 and current_item in bot.goals and bot.playerboard.find(-1) != -1:
|
||||||
|
return {
|
||||||
|
"action": "grab",
|
||||||
|
"position": bot.current_position,
|
||||||
|
"value": 10
|
||||||
|
}
|
||||||
|
|
||||||
|
# Evaluate putting item from playerboard
|
||||||
|
for goal in bot.goals:
|
||||||
|
var item_index = bot.playerboard.find(goal)
|
||||||
|
if item_index != -1 and current_item == -1:
|
||||||
|
return {
|
||||||
|
"action": "put",
|
||||||
|
"position": bot.current_position,
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
# Bot has performed action, look for movement
|
||||||
|
var neighbors = bot.enhanced_gridmap.get_neighbors(bot.current_position, 1)
|
||||||
|
for neighbor in neighbors:
|
||||||
|
if not neighbor.is_walkable:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not bot.is_within_movement_range(neighbor.position):
|
||||||
|
continue
|
||||||
|
|
||||||
|
var cell = Vector3i(neighbor.position.x, 1, neighbor.position.y)
|
||||||
|
var item = bot.enhanced_gridmap.get_cell_item(cell)
|
||||||
|
|
||||||
|
# Evaluate position for next turn
|
||||||
|
if item in bot.goals or item == -1:
|
||||||
|
var value = 8
|
||||||
|
if value > best_move.value:
|
||||||
|
best_move = {
|
||||||
|
"action": "move",
|
||||||
|
"position": neighbor.position,
|
||||||
|
"value": value
|
||||||
|
}
|
||||||
|
|
||||||
|
return best_move
|
||||||
|
|
||||||
|
#func move_bot(bot_id):
|
||||||
|
#if multiplayer.is_server():
|
||||||
|
#if moving_bots.get(bot_id, false):
|
||||||
|
#return # Skip if bot is already moving
|
||||||
|
#
|
||||||
|
#var bot = get_node(str(bot_id))
|
||||||
|
#if bot and (turn_based_mode or not bot.is_player_moving):
|
||||||
|
#moving_bots[bot_id] = true # Mark bot as moving
|
||||||
|
#var target_position = bot.find_random_valid_position_in_range() # Use the new function
|
||||||
|
#if target_position != bot.current_position:
|
||||||
|
#var path = bot.enhanced_gridmap.find_path(Vector2(bot.current_position), Vector2(target_position))
|
||||||
|
#
|
||||||
|
#if path.size() > 1:
|
||||||
|
#path.pop_front()
|
||||||
|
## Trim path to respect movement range
|
||||||
|
#var trimmed_path = path.slice(0, bot.movement_range)
|
||||||
|
#bot.move_bot_along_path(trimmed_path, bot_id)
|
||||||
|
#else:
|
||||||
|
#print("No valid path found for bot")
|
||||||
|
#moving_bots[bot_id] = false
|
||||||
|
#if turn_based_mode:
|
||||||
|
#end_current_turn()
|
||||||
|
#else:
|
||||||
|
#print("No new valid position found for bot")
|
||||||
|
#moving_bots[bot_id] = false
|
||||||
|
#if turn_based_mode:
|
||||||
|
#end_current_turn()
|
||||||
|
#else:
|
||||||
|
#print("Bot not found or is moving")
|
||||||
|
#if turn_based_mode:
|
||||||
|
#end_current_turn()
|
||||||
func move_bot(bot_id):
|
func move_bot(bot_id):
|
||||||
if multiplayer.is_server():
|
if multiplayer.is_server():
|
||||||
if moving_bots.get(bot_id, false):
|
if moving_bots.get(bot_id, false):
|
||||||
return # Skip if bot is already moving
|
return
|
||||||
|
|
||||||
var bot = get_node(str(bot_id))
|
var bot = get_node(str(bot_id))
|
||||||
if bot and (turn_based_mode or not bot.is_player_moving):
|
if bot and (turn_based_mode or not bot.is_player_moving):
|
||||||
moving_bots[bot_id] = true # Mark bot as moving
|
moving_bots[bot_id] = true
|
||||||
var target_position = bot.find_random_valid_position_in_range() # Use the new function
|
|
||||||
if target_position != bot.current_position:
|
|
||||||
var path = bot.enhanced_gridmap.find_path(Vector2(bot.current_position), Vector2(target_position))
|
|
||||||
|
|
||||||
if path.size() > 1:
|
var best_move = evaluate_bot_move(bot)
|
||||||
path.pop_front()
|
|
||||||
# Trim path to respect movement range
|
match best_move.action:
|
||||||
var trimmed_path = path.slice(0, bot.movement_range)
|
"grab":
|
||||||
bot.move_bot_along_path(trimmed_path, bot_id)
|
if bot.grab_item():
|
||||||
else:
|
bot.has_performed_action = true
|
||||||
print("No valid path found for bot")
|
moving_bots[bot_id] = false
|
||||||
|
# Don't end turn, allow movement after grab
|
||||||
|
move_bot(bot_id) # Try to move after grabbing
|
||||||
|
"put":
|
||||||
|
if bot.put_item():
|
||||||
|
bot.has_performed_action = true
|
||||||
|
moving_bots[bot_id] = false
|
||||||
|
# Don't end turn, allow movement after put
|
||||||
|
move_bot(bot_id) # Try to move after putting
|
||||||
|
"move":
|
||||||
|
if bot.has_performed_action:
|
||||||
|
var path = bot.enhanced_gridmap.find_path(Vector2(bot.current_position), Vector2(best_move.position))
|
||||||
|
if path.size() > 1:
|
||||||
|
path.pop_front()
|
||||||
|
var trimmed_path = path.slice(0, bot.movement_range)
|
||||||
|
bot.rotate_towards_target(best_move.position)
|
||||||
|
bot.move_bot_along_path(trimmed_path, bot_id)
|
||||||
|
else:
|
||||||
|
moving_bots[bot_id] = false
|
||||||
|
if turn_based_mode:
|
||||||
|
end_current_turn()
|
||||||
|
else:
|
||||||
|
moving_bots[bot_id] = false
|
||||||
|
if turn_based_mode:
|
||||||
|
end_current_turn()
|
||||||
|
_:
|
||||||
moving_bots[bot_id] = false
|
moving_bots[bot_id] = false
|
||||||
if turn_based_mode:
|
if turn_based_mode:
|
||||||
end_current_turn()
|
end_current_turn()
|
||||||
else:
|
|
||||||
print("No new valid position found for bot")
|
|
||||||
moving_bots[bot_id] = false
|
|
||||||
if turn_based_mode:
|
|
||||||
end_current_turn()
|
|
||||||
else:
|
|
||||||
print("Bot not found or is moving")
|
|
||||||
if turn_based_mode:
|
|
||||||
end_current_turn()
|
|
||||||
|
|
||||||
# Called when a bot finishes moving
|
# Called when a bot finishes moving
|
||||||
func bot_movement_completed(bot_id):
|
func bot_movement_completed(bot_id):
|
||||||
|
|||||||
+147
-1
@@ -12,6 +12,16 @@ var is_player_moving: bool = false
|
|||||||
@export var center_y: bool = false
|
@export var center_y: bool = false
|
||||||
@export var center_z: bool = false
|
@export var center_z: bool = false
|
||||||
|
|
||||||
|
# Goals & Playerboard Data
|
||||||
|
@export var goals: Array[int] = [0,0,0,0,0,0,0,0,0] # 9 length array for goals
|
||||||
|
@export var playerboard: Array[int] = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] # 25 length array for holding items
|
||||||
|
var has_performed_action: bool = false # Track if grab/put action has been done
|
||||||
|
|
||||||
|
# Player Rotation Config
|
||||||
|
# Add these variables for rotation
|
||||||
|
var target_rotation: float = 0.0
|
||||||
|
var rotation_speed: float = 10.0 # Adjust this to control rotation speed
|
||||||
|
|
||||||
@export var movement_range: int = 1 # How many blocks can be moved at once
|
@export var movement_range: int = 1 # How many blocks can be moved at once
|
||||||
@export var use_diagonal_movement: bool = false: # Allow diagonal movement
|
@export var use_diagonal_movement: bool = false: # Allow diagonal movement
|
||||||
set(value):
|
set(value):
|
||||||
@@ -50,6 +60,13 @@ func _ready():
|
|||||||
|
|
||||||
set_process_unhandled_input(is_multiplayer_authority())
|
set_process_unhandled_input(is_multiplayer_authority())
|
||||||
|
|
||||||
|
# Initialize random goals
|
||||||
|
initialize_random_goals()
|
||||||
|
|
||||||
|
# Initialize playerboard with -1 (empty slots)
|
||||||
|
playerboard.resize(25)
|
||||||
|
playerboard.fill(-1)
|
||||||
|
|
||||||
func find_valid_starting_position() -> Vector2i:
|
func find_valid_starting_position() -> Vector2i:
|
||||||
var rng = RandomNumberGenerator.new()
|
var rng = RandomNumberGenerator.new()
|
||||||
rng.randomize()
|
rng.randomize()
|
||||||
@@ -106,6 +123,16 @@ func _physics_process(_delta):
|
|||||||
if is_multiplayer_authority():
|
if is_multiplayer_authority():
|
||||||
rpc("remote_set_position", global_position)
|
rpc("remote_set_position", global_position)
|
||||||
|
|
||||||
|
# Add this to your _process function if you don't have one
|
||||||
|
func _process(delta):
|
||||||
|
if is_multiplayer_authority():
|
||||||
|
if Input.is_action_just_pressed("grab_item"): # Define this input in project settings
|
||||||
|
if grab_item():
|
||||||
|
rpc("display_message", "Item grabbed!")
|
||||||
|
elif Input.is_action_just_pressed("put_item"): # Define this input in project settings
|
||||||
|
if put_item():
|
||||||
|
rpc("display_message", "Item placed!")
|
||||||
|
|
||||||
func _unhandled_input(event):
|
func _unhandled_input(event):
|
||||||
var main = get_node("/root/Main")
|
var main = get_node("/root/Main")
|
||||||
if not is_multiplayer_authority() or (main.turn_based_mode and (not is_my_turn or is_player_moving)):
|
if not is_multiplayer_authority() or (main.turn_based_mode and (not is_my_turn or is_player_moving)):
|
||||||
@@ -149,6 +176,32 @@ func is_within_movement_range(target_position: Vector2i) -> bool:
|
|||||||
abs(target_position.y - current_position.y)
|
abs(target_position.y - current_position.y)
|
||||||
return distance <= movement_range
|
return distance <= movement_range
|
||||||
|
|
||||||
|
#func move_player_to_clicked_position(grid_position: Vector2i):
|
||||||
|
#if not is_multiplayer_authority():
|
||||||
|
#return
|
||||||
|
#
|
||||||
|
#if is_player_moving:
|
||||||
|
#return
|
||||||
|
#
|
||||||
|
## Check if the movement is within range
|
||||||
|
#if not is_within_movement_range(grid_position):
|
||||||
|
#print("Movement out of range")
|
||||||
|
#return
|
||||||
|
#
|
||||||
|
#var cell_item = enhanced_gridmap.get_cell_item(Vector3i(grid_position.x, 0, grid_position.y))
|
||||||
|
#
|
||||||
|
#if cell_item in enhanced_gridmap.non_walkable_items:
|
||||||
|
#print("Cannot move to non-walkable cell")
|
||||||
|
#return
|
||||||
|
#
|
||||||
|
#var path = enhanced_gridmap.find_path(Vector2(current_position), Vector2(grid_position))
|
||||||
|
#
|
||||||
|
#if path.size() > 1:
|
||||||
|
#path.pop_front()
|
||||||
|
#rpc("start_movement_along_path", path)
|
||||||
|
#else:
|
||||||
|
#print("No valid path found")
|
||||||
|
|
||||||
func move_player_to_clicked_position(grid_position: Vector2i):
|
func move_player_to_clicked_position(grid_position: Vector2i):
|
||||||
if not is_multiplayer_authority():
|
if not is_multiplayer_authority():
|
||||||
return
|
return
|
||||||
@@ -156,7 +209,11 @@ func move_player_to_clicked_position(grid_position: Vector2i):
|
|||||||
if is_player_moving:
|
if is_player_moving:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check if the movement is within range
|
# Check if player has performed grab/put action
|
||||||
|
if not has_performed_action and current_position != grid_position:
|
||||||
|
rpc("display_message", "Must grab or place item before moving!")
|
||||||
|
return
|
||||||
|
|
||||||
if not is_within_movement_range(grid_position):
|
if not is_within_movement_range(grid_position):
|
||||||
print("Movement out of range")
|
print("Movement out of range")
|
||||||
return
|
return
|
||||||
@@ -167,6 +224,8 @@ func move_player_to_clicked_position(grid_position: Vector2i):
|
|||||||
print("Cannot move to non-walkable cell")
|
print("Cannot move to non-walkable cell")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
rotate_towards_target(grid_position)
|
||||||
|
|
||||||
var path = enhanced_gridmap.find_path(Vector2(current_position), Vector2(grid_position))
|
var path = enhanced_gridmap.find_path(Vector2(current_position), Vector2(grid_position))
|
||||||
|
|
||||||
if path.size() > 1:
|
if path.size() > 1:
|
||||||
@@ -189,6 +248,7 @@ func start_movement_along_path(path: Array):
|
|||||||
tween.tween_callback(func():
|
tween.tween_callback(func():
|
||||||
current_position = Vector2i(path[-1].x, path[-1].y)
|
current_position = Vector2i(path[-1].x, path[-1].y)
|
||||||
is_player_moving = false
|
is_player_moving = false
|
||||||
|
has_performed_action = false # Reset the action flag after movement
|
||||||
enhanced_gridmap.clear_path_visualization()
|
enhanced_gridmap.clear_path_visualization()
|
||||||
has_moved_this_turn = true
|
has_moved_this_turn = true
|
||||||
var main = get_node("/root/Main")
|
var main = get_node("/root/Main")
|
||||||
@@ -196,6 +256,7 @@ func start_movement_along_path(path: Array):
|
|||||||
end_turn()
|
end_turn()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func move_bot_along_path(path: Array, bot_id: int):
|
func move_bot_along_path(path: Array, bot_id: int):
|
||||||
if not is_multiplayer_authority():
|
if not is_multiplayer_authority():
|
||||||
return
|
return
|
||||||
@@ -250,6 +311,7 @@ func grid_to_world(grid_position: Vector2i) -> Vector3:
|
|||||||
|
|
||||||
func start_turn():
|
func start_turn():
|
||||||
has_moved_this_turn = false
|
has_moved_this_turn = false
|
||||||
|
has_performed_action = false # Reset action flag at start of turn
|
||||||
is_my_turn = true
|
is_my_turn = true
|
||||||
if is_multiplayer_authority():
|
if is_multiplayer_authority():
|
||||||
rpc("display_message", "It's your turn!")
|
rpc("display_message", "It's your turn!")
|
||||||
@@ -272,3 +334,87 @@ func display_message(message):
|
|||||||
await get_tree().create_timer(3).timeout
|
await get_tree().create_timer(3).timeout
|
||||||
$Bubble.hide()
|
$Bubble.hide()
|
||||||
$Bubble/Message.hide()
|
$Bubble/Message.hide()
|
||||||
|
|
||||||
|
func initialize_random_goals():
|
||||||
|
goals.clear()
|
||||||
|
var rng = RandomNumberGenerator.new()
|
||||||
|
rng.randomize()
|
||||||
|
|
||||||
|
for i in range(9):
|
||||||
|
goals.append(rng.randi_range(7, 10))
|
||||||
|
|
||||||
|
if is_multiplayer_authority():
|
||||||
|
rpc("sync_goals", goals)
|
||||||
|
|
||||||
|
func grab_item() -> bool:
|
||||||
|
if not enhanced_gridmap:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var current_cell = Vector3i(current_position.x, 1, current_position.y)
|
||||||
|
var item = enhanced_gridmap.get_cell_item(current_cell)
|
||||||
|
|
||||||
|
if item == -1: # No item to grab
|
||||||
|
return false
|
||||||
|
|
||||||
|
var empty_slot = playerboard.find(-1)
|
||||||
|
if empty_slot == -1: # No empty slots
|
||||||
|
return false
|
||||||
|
|
||||||
|
playerboard[empty_slot] = item
|
||||||
|
enhanced_gridmap.set_cell_item(current_cell, -1)
|
||||||
|
|
||||||
|
if is_multiplayer_authority():
|
||||||
|
rpc("sync_playerboard", playerboard)
|
||||||
|
|
||||||
|
has_performed_action = true # Set action flag
|
||||||
|
return true
|
||||||
|
|
||||||
|
func put_item() -> bool:
|
||||||
|
if not enhanced_gridmap:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var current_cell = Vector3i(current_position.x, 1, current_position.y)
|
||||||
|
if enhanced_gridmap.get_cell_item(current_cell) != -1:
|
||||||
|
return false # Cell is occupied
|
||||||
|
|
||||||
|
var item_to_put = -1
|
||||||
|
var item_index = -1
|
||||||
|
|
||||||
|
for goal in goals:
|
||||||
|
var index = playerboard.find(goal)
|
||||||
|
if index != -1:
|
||||||
|
item_to_put = goal
|
||||||
|
item_index = index
|
||||||
|
break
|
||||||
|
|
||||||
|
if item_to_put == -1:
|
||||||
|
return false
|
||||||
|
|
||||||
|
enhanced_gridmap.set_cell_item(current_cell, item_to_put)
|
||||||
|
playerboard[item_index] = -1
|
||||||
|
|
||||||
|
if is_multiplayer_authority():
|
||||||
|
rpc("sync_playerboard", playerboard)
|
||||||
|
|
||||||
|
has_performed_action = true # Set action flag
|
||||||
|
return true
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local")
|
||||||
|
func sync_goals(new_goals: Array):
|
||||||
|
goals = new_goals
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local")
|
||||||
|
func sync_playerboard(new_playerboard: Array):
|
||||||
|
playerboard = new_playerboard
|
||||||
|
|
||||||
|
func rotate_towards_target(target_pos: Vector2i):
|
||||||
|
var direction = Vector2(
|
||||||
|
target_pos.x - current_position.x,
|
||||||
|
target_pos.y - current_position.y
|
||||||
|
).normalized()
|
||||||
|
|
||||||
|
target_rotation = atan2(direction.x, direction.y)
|
||||||
|
|
||||||
|
# Create a tween for smooth rotation
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.tween_property(self, "rotation:y", target_rotation, 0.2)
|
||||||
|
|||||||
Reference in New Issue
Block a user