Player can take quests, Adventurers in progress.
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
class_name Adventurer extends Npc
|
||||
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
nav_agent.navigation_finished.connect(_on_nav_agent_finished)
|
||||
pass
|
||||
|
||||
109
ai/tasks/actions/use_guild_equipment.gd
Normal file
109
ai/tasks/actions/use_guild_equipment.gd
Normal file
@@ -0,0 +1,109 @@
|
||||
#*
|
||||
#* use_guild_equipment.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 equipment_name : String = ""
|
||||
|
||||
## Variable that stores desired speed (float)
|
||||
@export var service_name : String = ""
|
||||
|
||||
var equipment : Interactable
|
||||
var queue : GuildQueue
|
||||
var wait_time_remaining : float = 0
|
||||
var phase : Phases
|
||||
|
||||
|
||||
func _generate_name() -> String:
|
||||
return "Use Guild Equipment (%s) - %s" % [
|
||||
equipment_name,
|
||||
service_name
|
||||
]
|
||||
|
||||
func _enter() -> void:
|
||||
var eq = Guild.hall.interactables.get(equipment_name)
|
||||
if !eq:
|
||||
printerr("Use Guild Equipment (%s) - %s, '%s' not found!", equipment_name, service_name, equipment_name)
|
||||
return
|
||||
equipment = eq
|
||||
queue = equipment.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 equipment == 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:
|
||||
equipment.service_provided.connect(_on_service_complete)
|
||||
equipment.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("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 equipment.busy:
|
||||
wait()
|
||||
else:
|
||||
use_service()
|
||||
pass
|
||||
|
||||
func _on_service_complete() -> void:
|
||||
equipment.service_provided.disconnect(_on_service_complete)
|
||||
agent.show_speech_bubble("")
|
||||
queue.remove_member(agent)
|
||||
phase = Phases.COMPLETE
|
||||
|
||||
1
ai/tasks/actions/use_guild_equipment.gd.uid
Normal file
1
ai/tasks/actions/use_guild_equipment.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bhatmue8jr2ab
|
||||
@@ -1,6 +1,7 @@
|
||||
class_name Guildhall extends Node2D
|
||||
|
||||
var employees : Dictionary[String, GuildEmployee] = {}
|
||||
var interactables : Dictionary[String, Interactable] = {}
|
||||
var board : QuestBoard
|
||||
@onready var sprite_node : Node2D = $Sprites
|
||||
@onready var nav_region : NavigationRegion2D = $RoomRegion
|
||||
@@ -14,7 +15,9 @@ func _ready() -> void:
|
||||
|
||||
func register_employee(employee: GuildEmployee) -> void:
|
||||
employees[employee.name] = employee
|
||||
|
||||
|
||||
func register_interactables(equipment: Interactable) -> void:
|
||||
interactables[equipment.name] = equipment
|
||||
|
||||
func add_sprite(sprite : Adventurer) -> void:
|
||||
sprite_node.add_child(sprite)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
[ext_resource type="Texture2D" uid="uid://cg6ptmynq0aq0" path="res://basic-sprite.png" id="4_l3mu1"]
|
||||
[ext_resource type="PackedScene" uid="uid://cf6nnjyp8kv78" path="res://receptionist.tscn" id="5_l3mu1"]
|
||||
[ext_resource type="Texture2D" uid="uid://bnt2dlv7kxw7s" path="res://questboard.png" id="6_2wofw"]
|
||||
[ext_resource type="Script" uid="uid://blo7tb5135vfm" path="res://quest_board.gd" id="7_bog1h"]
|
||||
[ext_resource type="Script" uid="uid://b0q2233msdtgo" path="res://guild_queue.gd" id="7_hph4e"]
|
||||
[ext_resource type="PackedScene" uid="uid://drrtypncppjps" path="res://quest_board_window.tscn" id="8_uo85v"]
|
||||
|
||||
@@ -27,6 +26,18 @@ vertices = PackedVector2Array(117.96875, 286, 9.96875, 286, 9.03125, 0, 117.0312
|
||||
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3)])
|
||||
outlines = Array[PackedVector2Array]([PackedVector2Array(-1, -10, 127, -10, 128, 296, 0, 296)])
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_bog1h"]
|
||||
script/source = "class_name QuestBoard extends Interactable
|
||||
|
||||
signal service_provided()
|
||||
|
||||
func _ready() -> void:
|
||||
queue = $Queue
|
||||
|
||||
func interact(interactor, service : String):
|
||||
service_provided.emit()
|
||||
"
|
||||
|
||||
[node name="Guildhall" type="Node2D"]
|
||||
script = ExtResource("1_lsinl")
|
||||
|
||||
@@ -83,7 +94,7 @@ navigation_polygon = SubResource("NavigationPolygon_l3mu1")
|
||||
|
||||
[node name="Quest Board" type="StaticBody2D" parent="."]
|
||||
position = Vector2(935, 32)
|
||||
script = ExtResource("7_bog1h")
|
||||
script = SubResource("GDScript_bog1h")
|
||||
|
||||
[node name="QuestBoardWindow" parent="Quest Board" instance=ExtResource("8_uo85v")]
|
||||
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
class_name Interactable extends StaticBody2D
|
||||
|
||||
var busy : bool = false
|
||||
var queue : GuildQueue
|
||||
|
||||
signal service_provided()
|
||||
|
||||
func _ready() -> void:
|
||||
queue = $Queue
|
||||
|
||||
func interact(interactor, service : String = ""):
|
||||
service_provided.emit()
|
||||
|
||||
@@ -16,7 +16,7 @@ func _process(delta: float) -> void:
|
||||
func add_quest_progress_bar(quest : Quest) -> void:
|
||||
var qpb : QuestProgressBar = quest_progress_bar_template.instantiate()
|
||||
qpb.setup(quest)
|
||||
%QuestProgressList/VBoxContainer.add_child(qpb)
|
||||
%QuestList.add_child(qpb)
|
||||
#TODO: Change the hero portrait to match
|
||||
if quest.steps > 1:
|
||||
for i in range(quest.steps-1):
|
||||
|
||||
@@ -18,6 +18,7 @@ corner_radius_bottom_left = 3
|
||||
corner_detail = 5
|
||||
|
||||
[node name="MainPanel" type="MarginContainer"]
|
||||
anchors_preset = -1
|
||||
offset_right = 319.0
|
||||
offset_bottom = 189.0
|
||||
theme_override_constants/margin_left = 0
|
||||
@@ -36,7 +37,8 @@ custom_minimum_size = Vector2(260, 100)
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="QuestProgressList"]
|
||||
[node name="QuestList" type="VBoxContainer" parent="QuestProgressList"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(300, 100)
|
||||
layout_mode = 2
|
||||
|
||||
|
||||
@@ -4,15 +4,13 @@ class_name QuestBoard extends Interactable
|
||||
@onready var polygon : CollisionPolygon2D = $CollisionPolygon2D
|
||||
@onready var window : QuestBoardWindow = $QuestBoardWindow
|
||||
|
||||
var busy : bool
|
||||
|
||||
signal interaction_complete()
|
||||
|
||||
func _ready() -> void:
|
||||
register_board.call_deferred()
|
||||
|
||||
func register_board() -> void:
|
||||
Guild.hall.board = self
|
||||
Guild.hall.register_interactables(self)
|
||||
|
||||
func _input(event : InputEvent) -> void:
|
||||
var evt : InputEventMouseButton = event as InputEventMouseButton
|
||||
|
||||
@@ -6,9 +6,11 @@ var quest : Quest = null
|
||||
@onready var tex_icon : TextureRect = %Icon
|
||||
@onready var name_label : Label = %NameLabel
|
||||
@onready var status_label : Label = %StatusLabel
|
||||
var board_window : QuestBoardWindow = null
|
||||
|
||||
func setup(quest : Quest) -> void:
|
||||
self.quest = quest
|
||||
quest.status_changed.connect(_on_quest_status_changed)
|
||||
name_label.text = quest.name
|
||||
status_label.text = "Available" if !quest.taken else "Unavailable"
|
||||
|
||||
@@ -16,9 +18,17 @@ func update() -> void:
|
||||
status_label.text = "Available" if !quest.taken else "Unavailable"
|
||||
|
||||
|
||||
func _on_quest_status_changed(status: Quest.Status) -> void:
|
||||
match(status):
|
||||
Quest.Status.OPEN: status_label.text = "Available"
|
||||
Quest.Status.TAKEN:queue_free()
|
||||
Quest.Status.COMPLETED: queue_free()
|
||||
_: status_label.text = "Unavailable"
|
||||
|
||||
func _on_pressed() -> void:
|
||||
var window = quest_window_template.instantiate()
|
||||
window.setup(quest, true)
|
||||
window.quest_accepted.connect(board_window._on_quest_accepted)
|
||||
add_child(window)
|
||||
window.popup_centered()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
[node name="QuestBoardEntry" type="Button"]
|
||||
custom_minimum_size = Vector2(200, 50)
|
||||
anchors_preset = -1
|
||||
offset_right = 200.0
|
||||
offset_bottom = 50.0
|
||||
script = ExtResource("1_qfdrh")
|
||||
|
||||
@@ -3,22 +3,23 @@ class_name QuestBoardWindow extends Popup
|
||||
const entry_template = preload("res://quest_board_entry.tscn")
|
||||
|
||||
@onready var entry_list : VBoxContainer = %Entries
|
||||
var entries : Array[QuestBoardEntry] = []
|
||||
|
||||
|
||||
func populate(quests : Array[Quest]) -> void:
|
||||
for entry in entries:
|
||||
for entry : QuestBoardEntry in entry_list.get_children():
|
||||
entry.queue_free()
|
||||
entries.clear()
|
||||
for quest in quests:
|
||||
if !quest.taken:
|
||||
add_entry(quest)
|
||||
|
||||
func add_entry(quest : Quest) -> void:
|
||||
var qle : QuestBoardEntry = entry_template.instantiate()
|
||||
entries.append(qle)
|
||||
entry_list.add_child(qle)
|
||||
qle.setup(quest)
|
||||
qle.board_window = self
|
||||
|
||||
func _on_quest_accepted() -> void:
|
||||
hide()
|
||||
|
||||
func _on_close_requested() -> void:
|
||||
hide()
|
||||
|
||||
@@ -15,4 +15,7 @@ func update() -> void:
|
||||
status_label.text = "Available" if !quest.taken else "Unavailable"
|
||||
|
||||
func _on_quest_status_changed(status : Quest.Status) -> void:
|
||||
update()
|
||||
match(status):
|
||||
Quest.Status.OPEN: status_label.text = "Available"
|
||||
Quest.Status.COMPLETED: queue_free()
|
||||
_: status_label.text = "Unavailable"
|
||||
|
||||
@@ -9,7 +9,7 @@ var enabled: bool:
|
||||
enable(value)
|
||||
|
||||
var quest : Quest
|
||||
|
||||
@onready var status_label = %StatusLabel
|
||||
|
||||
func enable(en: bool) -> void:
|
||||
_enabled = en
|
||||
@@ -20,6 +20,7 @@ func enable(en: bool) -> void:
|
||||
|
||||
func setup(qst : Quest) -> void:
|
||||
quest = qst
|
||||
quest.status_changed.connect(_on_quest_status_changed)
|
||||
%NameLabel.text = quest.name
|
||||
#TODO: Add star rating
|
||||
#%LevelLabel.text = str(data.level)
|
||||
@@ -30,3 +31,10 @@ func _on_gui_input(event: InputEvent) -> void:
|
||||
var evt = event as InputEventMouseButton
|
||||
if evt and evt.button_index == MOUSE_BUTTON_LEFT and evt.pressed:
|
||||
print("Quest clicked!")
|
||||
|
||||
func _on_quest_status_changed(status: Quest.Status) -> void:
|
||||
match(status):
|
||||
Quest.Status.OPEN: status_label.text = "OPEN"
|
||||
Quest.Status.COMPLETED: queue_free()
|
||||
Quest.Status.IN_PROGRESS: status_label.text = "IN PROGRESS"
|
||||
_: status_label.text = "Taken"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
extends Window
|
||||
|
||||
var quest : Quest
|
||||
signal quest_accepted()
|
||||
|
||||
func setup(qst : Quest, board : bool) -> void:
|
||||
quest = qst
|
||||
@@ -31,6 +32,8 @@ func _on_quest_status_changed(status : Quest.Status) -> void:
|
||||
|
||||
func _on_accept_pressed() -> void:
|
||||
Guild.assign_quest(Game.player.data, quest)
|
||||
quest_accepted.emit()
|
||||
queue_free()
|
||||
|
||||
func _on_close_button_pressed() -> void:
|
||||
queue_free()
|
||||
|
||||
Reference in New Issue
Block a user