New art assets, work on implementing more adventurer behavior and making them work better together, and steps towards completing the first quest loop.
This commit is contained in:
103
ai/tasks/actions/get_quest.gd
Normal file
103
ai/tasks/actions/get_quest.gd
Normal file
@@ -0,0 +1,103 @@
|
||||
#*
|
||||
#* use_guild_service.gd
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Moves the agent to the specified position, favoring horizontal movement. [br]
|
||||
## Returns [code]SUCCESS[/code] when close to the target position (see [member tolerance]);
|
||||
## otherwise returns [code]RUNNING[/code].
|
||||
|
||||
|
||||
enum Phases {
|
||||
ARRIVE,
|
||||
QUEUE,
|
||||
WAIT,
|
||||
OBTAIN,
|
||||
COMPLETE
|
||||
}
|
||||
|
||||
var board : QuestBoard
|
||||
|
||||
var queue : GuildQueue
|
||||
var wait_time_remaining : float = 0
|
||||
var phase : Phases
|
||||
|
||||
|
||||
func _generate_name() -> String:
|
||||
return "Get a Quest"
|
||||
|
||||
func _enter() -> void:
|
||||
var brd = Guild.hall.board
|
||||
if !brd:
|
||||
printerr("Get a Quest: Board not found!")
|
||||
return
|
||||
board = brd
|
||||
queue = board.queue
|
||||
phase = Phases.ARRIVE
|
||||
queue.add_member(agent)
|
||||
agent.approach(queue.get_last_position())
|
||||
agent.navigation_finished.connect(_on_navigation_complete)
|
||||
agent.navigation_failed.connect(_on_navigation_failed)
|
||||
|
||||
func _tick(delta: float) -> Status:
|
||||
if board == null:
|
||||
return FAILURE
|
||||
match(phase):
|
||||
Phases.ARRIVE:
|
||||
if wait_time_remaining > 0:
|
||||
wait_time_remaining -= delta
|
||||
if wait_time_remaining <= 0:
|
||||
agent.navigation_finished.connect(_on_navigation_complete)
|
||||
agent.approach(queue.get_member_position(agent))
|
||||
Phases.QUEUE:
|
||||
pass
|
||||
Phases.WAIT:
|
||||
pass
|
||||
Phases.OBTAIN:
|
||||
if wait_time_remaining:
|
||||
wait_time_remaining -= delta
|
||||
if wait_time_remaining <= 0:
|
||||
board.interaction_complete.connect(_on_interaction_complete)
|
||||
board.interact(agent, "quest")
|
||||
phase = Phases.OBTAIN
|
||||
Phases.COMPLETE:
|
||||
return SUCCESS
|
||||
return RUNNING
|
||||
|
||||
func _on_navigation_complete() -> void:
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
agent.navigation_failed.disconnect(_on_navigation_failed)
|
||||
queue.advanced.connect(_on_queue_advanced)
|
||||
phase = Phases.QUEUE
|
||||
|
||||
func _on_navigation_failed() -> void:
|
||||
wait_time_remaining = randf_range(.5, 2)
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
|
||||
func get_quest():
|
||||
phase = Phases.OBTAIN
|
||||
wait_time_remaining = randf_range(2,5)
|
||||
agent.show_speech_bubble("busy")
|
||||
|
||||
func wait():
|
||||
wait_time_remaining = 1
|
||||
phase = Phases.WAIT
|
||||
|
||||
|
||||
func _on_queue_advanced() -> void:
|
||||
if queue.front == agent:
|
||||
queue.advanced.disconnect(_on_queue_advanced)
|
||||
if board.busy:
|
||||
wait()
|
||||
else:
|
||||
get_quest()
|
||||
pass
|
||||
|
||||
func _on_interaction_complete() -> void:
|
||||
board.interaction_complete.disconnect(_on_interaction_complete)
|
||||
if agent.data.quest != null:
|
||||
agent.show_speech_bubble("happy", 1.5)
|
||||
else:
|
||||
agent.show_speech_bubble("angry", 1.5)
|
||||
queue.remove_member(agent)
|
||||
phase = Phases.COMPLETE
|
||||
1
ai/tasks/actions/get_quest.gd.uid
Normal file
1
ai/tasks/actions/get_quest.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ders6t7axct24
|
||||
48
ai/tasks/actions/go_to.gd
Normal file
48
ai/tasks/actions/go_to.gd
Normal file
@@ -0,0 +1,48 @@
|
||||
#*
|
||||
#* go_to.gd
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Moves the agent to the specified position, favoring horizontal movement. [br]
|
||||
## Returns [code]SUCCESS[/code] when close to the target position (see [member tolerance]);
|
||||
## otherwise returns [code]RUNNING[/code].
|
||||
|
||||
## Blackboard variable that stores the target position (Vector2)
|
||||
@export var target_position_var := &"pos"
|
||||
var wait_time_remaining : float = 0
|
||||
var goal_position : Vector2
|
||||
|
||||
var done : bool
|
||||
|
||||
func _generate_name() -> String:
|
||||
return "Go to Position: %s" % [LimboUtility.decorate_var(target_position_var)]
|
||||
|
||||
func _enter() -> void:
|
||||
done = false
|
||||
goal_position = blackboard.get_var(target_position_var, Vector2.ZERO)
|
||||
go_to(goal_position)
|
||||
|
||||
func _tick(delta: float) -> Status:
|
||||
if done:
|
||||
return SUCCESS
|
||||
#If we were interrupted, wait a little bit and try again
|
||||
if wait_time_remaining > 0:
|
||||
wait_time_remaining -= delta
|
||||
if wait_time_remaining <= 0:
|
||||
go_to(goal_position)
|
||||
return RUNNING
|
||||
|
||||
func go_to(pos : Vector2) -> void:
|
||||
agent.navigation_finished.connect(_on_navigation_complete)
|
||||
agent.navigation_failed.connect(_on_navigation_failed)
|
||||
agent.approach(pos)
|
||||
|
||||
func _on_navigation_complete() -> void:
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
agent.navigation_failed.disconnect(_on_navigation_failed)
|
||||
done = true
|
||||
|
||||
func _on_navigation_failed() -> void:
|
||||
wait_time_remaining = randf_range(.5, 2)
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
agent.navigation_failed.disconnect(_on_navigation_failed)
|
||||
1
ai/tasks/actions/go_to.gd.uid
Normal file
1
ai/tasks/actions/go_to.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://h113xg55h4r8
|
||||
111
ai/tasks/actions/use_guild_service.gd
Normal file
111
ai/tasks/actions/use_guild_service.gd
Normal file
@@ -0,0 +1,111 @@
|
||||
#*
|
||||
#* use_guild_service.gd
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Moves the agent to the specified position, favoring horizontal movement. [br]
|
||||
## Returns [code]SUCCESS[/code] when close to the target position (see [member tolerance]);
|
||||
## otherwise returns [code]RUNNING[/code].
|
||||
|
||||
|
||||
enum Phases {
|
||||
ARRIVE,
|
||||
QUEUE,
|
||||
WAIT,
|
||||
SERVICE,
|
||||
COMPLETE
|
||||
}
|
||||
|
||||
## Blackboard variable that stores the target position (Vector2)
|
||||
@export var employee_name : String = ""
|
||||
|
||||
## Variable that stores desired speed (float)
|
||||
@export var service_name : String = ""
|
||||
|
||||
var employee : GuildEmployee
|
||||
var queue : GuildQueue
|
||||
var wait_time_remaining : float = 0
|
||||
var phase : Phases
|
||||
|
||||
|
||||
func _generate_name() -> String:
|
||||
return "Use Guild Service (%s) - %s" % [
|
||||
employee_name,
|
||||
service_name
|
||||
]
|
||||
|
||||
func _enter() -> void:
|
||||
var emp = Guild.hall.employees.get(employee_name)
|
||||
if !emp:
|
||||
printerr("Use Guild Service (%s) - %s, '%s' not found!", employee_name, service_name, employee_name)
|
||||
return
|
||||
employee = emp
|
||||
queue = employee.queue
|
||||
phase = Phases.ARRIVE
|
||||
queue.add_member(agent)
|
||||
agent.approach(queue.get_last_position())
|
||||
agent.navigation_finished.connect(_on_navigation_complete)
|
||||
agent.navigation_failed.connect(_on_navigation_failed)
|
||||
|
||||
func _tick(delta: float) -> Status:
|
||||
if employee == null:
|
||||
return FAILURE
|
||||
match(phase):
|
||||
Phases.ARRIVE:
|
||||
if wait_time_remaining > 0:
|
||||
wait_time_remaining -= delta
|
||||
if wait_time_remaining <= 0:
|
||||
agent.navigation_finished.connect(_on_navigation_complete)
|
||||
agent.approach(queue.get_member_position(agent))
|
||||
Phases.QUEUE:
|
||||
pass
|
||||
Phases.WAIT:
|
||||
pass
|
||||
Phases.SERVICE:
|
||||
if wait_time_remaining > 0:
|
||||
wait_time_remaining -= delta
|
||||
if wait_time_remaining <= 0:
|
||||
employee.service_provided.connect(_on_service_complete)
|
||||
employee.interact(agent, service_name)
|
||||
Phases.COMPLETE:
|
||||
return SUCCESS
|
||||
return RUNNING
|
||||
|
||||
func _on_navigation_complete() -> void:
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
agent.navigation_failed.disconnect(_on_navigation_failed)
|
||||
queue.advanced.connect(_on_queue_advanced)
|
||||
phase = Phases.QUEUE
|
||||
|
||||
func _on_navigation_failed() -> void:
|
||||
wait_time_remaining = randf_range(.5, 2)
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
|
||||
func use_service():
|
||||
phase = Phases.SERVICE
|
||||
wait_time_remaining = randf_range(2,5)
|
||||
#TODO: Make them both do the talking emoji
|
||||
agent.show_speech_bubble("talk")
|
||||
employee.show_speech_bubble("talk")
|
||||
|
||||
func wait():
|
||||
wait_time_remaining = 1
|
||||
phase = Phases.WAIT
|
||||
|
||||
|
||||
func _on_queue_advanced() -> void:
|
||||
if queue.front == agent:
|
||||
queue.advanced.disconnect(_on_queue_advanced)
|
||||
if employee.busy:
|
||||
wait()
|
||||
else:
|
||||
use_service()
|
||||
pass
|
||||
|
||||
func _on_service_complete() -> void:
|
||||
employee.service_provided.disconnect(_on_service_complete)
|
||||
agent.show_speech_bubble("")
|
||||
employee.show_speech_bubble("")
|
||||
queue.remove_member(agent)
|
||||
phase = Phases.COMPLETE
|
||||
|
||||
1
ai/tasks/actions/use_guild_service.gd.uid
Normal file
1
ai/tasks/actions/use_guild_service.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bsq5dxul0uto
|
||||
50
ai/tasks/actions/wander.gd
Normal file
50
ai/tasks/actions/wander.gd
Normal file
@@ -0,0 +1,50 @@
|
||||
#*
|
||||
#* go_to.gd
|
||||
#*
|
||||
@tool
|
||||
extends BTAction
|
||||
## Moves the agent to the specified position, favoring horizontal movement. [br]
|
||||
## Returns [code]SUCCESS[/code] when close to the target position (see [member tolerance]);
|
||||
## otherwise returns [code]RUNNING[/code].
|
||||
|
||||
var wait_time_remaining : float = 0
|
||||
var goal_position : Vector2
|
||||
var retries : int
|
||||
var done : bool
|
||||
|
||||
func _generate_name() -> String:
|
||||
return "Wander to New Position"
|
||||
|
||||
func _enter() -> void:
|
||||
done = false
|
||||
retries = 0
|
||||
goal_position = NavigationServer2D.region_get_random_point(Guild.hall.nav_region.get_rid(),1,false)
|
||||
go_to(goal_position)
|
||||
|
||||
func _tick(delta: float) -> Status:
|
||||
if done:
|
||||
return SUCCESS
|
||||
#If we were interrupted, wait a little bit and try again
|
||||
if wait_time_remaining > 0:
|
||||
wait_time_remaining -= delta
|
||||
if wait_time_remaining <= 0:
|
||||
go_to(goal_position)
|
||||
return RUNNING
|
||||
|
||||
func go_to(pos : Vector2) -> void:
|
||||
agent.navigation_finished.connect(_on_navigation_complete)
|
||||
agent.navigation_failed.connect(_on_navigation_failed)
|
||||
agent.approach(pos)
|
||||
|
||||
func _on_navigation_complete() -> void:
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
agent.navigation_failed.disconnect(_on_navigation_failed)
|
||||
done = true
|
||||
|
||||
func _on_navigation_failed() -> void:
|
||||
wait_time_remaining = randf_range(.5, 2)
|
||||
retries += 1
|
||||
if retries >= 3:
|
||||
done = true
|
||||
agent.navigation_finished.disconnect(_on_navigation_complete)
|
||||
agent.navigation_failed.disconnect(_on_navigation_failed)
|
||||
1
ai/tasks/actions/wander.gd.uid
Normal file
1
ai/tasks/actions/wander.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://767b4fdlrgr
|
||||
7
ai/tasks/conditions/has_quest.gd
Normal file
7
ai/tasks/conditions/has_quest.gd
Normal file
@@ -0,0 +1,7 @@
|
||||
extends BTCondition
|
||||
var invert : bool
|
||||
func _tick(delta: float) -> Status:
|
||||
if agent.data and ((agent.data.quest == null) == invert):
|
||||
return SUCCESS
|
||||
else:
|
||||
return FAILURE
|
||||
1
ai/tasks/conditions/has_quest.gd.uid
Normal file
1
ai/tasks/conditions/has_quest.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://xom38ohdwfms
|
||||
7
ai/tasks/conditions/is_unregistered.gd
Normal file
7
ai/tasks/conditions/is_unregistered.gd
Normal file
@@ -0,0 +1,7 @@
|
||||
extends BTCondition
|
||||
|
||||
func _tick(delta: float) -> Status:
|
||||
if agent.data and !Guild.has_guild_member(agent.data):
|
||||
return SUCCESS
|
||||
else:
|
||||
return FAILURE
|
||||
1
ai/tasks/conditions/is_unregistered.gd.uid
Normal file
1
ai/tasks/conditions/is_unregistered.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bcbfnm21rtkuo
|
||||
22
ai/tasks/decorators/busy.gd
Normal file
22
ai/tasks/decorators/busy.gd
Normal file
@@ -0,0 +1,22 @@
|
||||
@tool
|
||||
extends BTDecorator
|
||||
|
||||
|
||||
var prev_busy : bool
|
||||
|
||||
func _get_task_icon():
|
||||
return load("res://ai/icons/stopwatch.png")
|
||||
|
||||
|
||||
func _enter() -> void:
|
||||
if agent.get("busy") != null:
|
||||
prev_busy = agent.busy
|
||||
agent.busy = true
|
||||
|
||||
func _exit() -> void:
|
||||
if agent.get("busy") != null:
|
||||
agent.busy = prev_busy
|
||||
|
||||
# Called to generate a display name for the task (requires @tool).
|
||||
func _generate_name() -> String:
|
||||
return "Busy"
|
||||
1
ai/tasks/decorators/busy.gd.uid
Normal file
1
ai/tasks/decorators/busy.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b2vuw12mttm40
|
||||
Reference in New Issue
Block a user