From cf149e676c29edf211245416241af9d4667a1ff7 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 7 May 2025 11:49:52 -0500 Subject: [PATCH] Add quest objectives to quest menu --- scenes/Maps/TestMap/TestMap.tscn | 3 +- scenes/Singletons/Quest.tscn | 9 +-- scenes/UI/QuestMenu.tscn | 21 +++++- scripts/Event/Quest/EventShowQuest.gd | 6 +- scripts/Event/Quest/EventStartQuest.gd | 6 ++ scripts/Event/Quest/EventStartQuest.gd.uid | 1 + scripts/Quest/Quest.gd | 23 +++++++ scripts/Quest/QuestObjective.gd | 8 +-- scripts/Quest/QuestStage.gd | 3 - scripts/Singleton/Quest.gd | 4 ++ scripts/UI/QuestMenu.gd | 78 +++++++++++++++++++--- 11 files changed, 132 insertions(+), 30 deletions(-) create mode 100644 scripts/Event/Quest/EventStartQuest.gd create mode 100644 scripts/Event/Quest/EventStartQuest.gd.uid delete mode 100644 scripts/Quest/QuestStage.gd diff --git a/scenes/Maps/TestMap/TestMap.tscn b/scenes/Maps/TestMap/TestMap.tscn index dcb4d26..595a717 100644 --- a/scenes/Maps/TestMap/TestMap.tscn +++ b/scenes/Maps/TestMap/TestMap.tscn @@ -6,7 +6,7 @@ [ext_resource type="PackedScene" uid="uid://boj5o4fx41rv8" path="res://scenes/Maps/TestMap/TestMapBuilding.tscn" id="4_brp0k"] [ext_resource type="Script" uid="uid://tkfc88q8m86f" path="res://scripts/Event/EventConversation.gd" id="5_cg1ph"] [ext_resource type="Script" uid="uid://y7ckj1tn5cro" path="res://scripts/Event/EventTextbox.gd" id="6_gxq5o"] -[ext_resource type="Script" uid="uid://dd6ppw243a5x7" path="res://scripts/Event/Quest/EventShowQuest.gd" id="7_brp0k"] +[ext_resource type="Script" uid="uid://c4d7nithqnx5y" path="res://scripts/Event/Quest/EventStartQuest.gd" id="7_brp0k"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_e1h75"] sky_horizon_color = Color(0.59625, 0.6135, 0.6375, 1) @@ -64,6 +64,7 @@ text = "I am giving you a quest to gather some ingredients." [node name="Quest" type="Node" parent="Events/TestConversation"] script = ExtResource("7_brp0k") +metadata/_custom_type_script = "uid://c4d7nithqnx5y" [node name="Text 1" type="Node" parent="Events/TestConversation"] script = ExtResource("6_gxq5o") diff --git a/scenes/Singletons/Quest.tscn b/scenes/Singletons/Quest.tscn index 3e5604f..fbe6988 100644 --- a/scenes/Singletons/Quest.tscn +++ b/scenes/Singletons/Quest.tscn @@ -1,8 +1,7 @@ -[gd_scene load_steps=5 format=3 uid="uid://cs3kmmd0rfm8w"] +[gd_scene load_steps=4 format=3 uid="uid://cs3kmmd0rfm8w"] [ext_resource type="Script" uid="uid://d0060jeyftia7" path="res://scripts/Singleton/Quest.gd" id="1_v2h4q"] [ext_resource type="Script" uid="uid://dn0kxbe85n40f" path="res://scripts/Quest/Quest.gd" id="2_n4ii1"] -[ext_resource type="Script" uid="uid://db4yhcxyhiosq" path="res://scripts/Quest/QuestStage.gd" id="3_1ynnx"] [ext_resource type="Script" uid="uid://de1ao4huhy0hm" path="res://scripts/Quest/QuestObjective.gd" id="3_l8p7p"] [node name="QuestSystem" type="Node"] @@ -13,10 +12,6 @@ script = ExtResource("1_v2h4q") [node name="Some Quest" type="Node" parent="Quests"] script = ExtResource("2_n4ii1") -[node name="Find Ingredients" type="Node" parent="Quests/Some Quest"] -script = ExtResource("3_1ynnx") -stageName = "Find Ingredients" - -[node name="Find Onion" type="Node" parent="Quests/Some Quest/Find Ingredients"] +[node name="Find Onion" type="Node" parent="Quests/Some Quest"] script = ExtResource("3_l8p7p") objectiveName = "Find Onions" diff --git a/scenes/UI/QuestMenu.tscn b/scenes/UI/QuestMenu.tscn index 722469b..f345032 100644 --- a/scenes/UI/QuestMenu.tscn +++ b/scenes/UI/QuestMenu.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" uid="uid://cbsrw36kkucje" path="res://scripts/UI/QuestMenu.gd" id="1_a7vj2"] -[node name="QuestMenu" type="Panel" node_paths=PackedStringArray("questList", "questName", "closeButton")] +[node name="QuestMenu" type="Panel" node_paths=PackedStringArray("questList", "questName", "closeButton", "questObjectiveList", "questObjectiveInfo")] anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -12,6 +12,8 @@ script = ExtResource("1_a7vj2") questList = NodePath("VBoxContainer/HBoxContainer/QuestList") questName = NodePath("VBoxContainer/HBoxContainer/Control/VBoxContainer/QuestName") closeButton = NodePath("VBoxContainer/HBoxContainer2/Close") +questObjectiveList = NodePath("VBoxContainer/HBoxContainer/Control/VBoxContainer/HBoxContainer/QuestObjectiveList") +questObjectiveInfo = NodePath("VBoxContainer/HBoxContainer/Control/VBoxContainer/HBoxContainer/QuestObjectiveInfo") metadata/_custom_type_script = "uid://cbsrw36kkucje" [node name="VBoxContainer" type="VBoxContainer" parent="."] @@ -62,3 +64,20 @@ grow_vertical = 2 [node name="QuestName" type="Label" parent="VBoxContainer/HBoxContainer/Control/VBoxContainer"] layout_mode = 2 text = "QuestName" + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer/Control/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="QuestObjectiveList" type="ItemList" parent="VBoxContainer/HBoxContainer/Control/VBoxContainer/HBoxContainer"] +custom_minimum_size = Vector2(150, 0) +layout_mode = 2 +item_count = 2 +item_0/text = "Quest Objective 1" +item_1/text = "Quest Objective 2" + +[node name="QuestObjectiveInfo" type="Label" parent="VBoxContainer/HBoxContainer/Control/VBoxContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 1 +text = "Quest Objective Information" diff --git a/scripts/Event/Quest/EventShowQuest.gd b/scripts/Event/Quest/EventShowQuest.gd index 58bfae0..baed943 100644 --- a/scripts/Event/Quest/EventShowQuest.gd +++ b/scripts/Event/Quest/EventShowQuest.gd @@ -2,16 +2,18 @@ class_name EventShowQuest extends "res://scripts/Event/Event.gd" @export var quest:QuestSystem.QuestKey = QuestSystem.QuestKey.TEST_QUEST @export var waitUntilClosed:bool = true +@export var showQuest:bool = true func start(): - UI.QUEST_MENU.open(quest) + if showQuest: + UI.QUEST_MENU.open(quest) pass func isDone() -> bool: if !super.isDone(): return false - if waitUntilClosed: + if waitUntilClosed and showQuest: return !UI.QUEST_MENU.isOpen() return true diff --git a/scripts/Event/Quest/EventStartQuest.gd b/scripts/Event/Quest/EventStartQuest.gd new file mode 100644 index 0000000..a9de778 --- /dev/null +++ b/scripts/Event/Quest/EventStartQuest.gd @@ -0,0 +1,6 @@ +class_name EventStartQuest extends "res://scripts/Event/Quest/EventShowQuest.gd" + +func start(): + assert(QUEST.quests.has(quest), "Quest not found.") + QUEST.quests[quest].start() + super.start() \ No newline at end of file diff --git a/scripts/Event/Quest/EventStartQuest.gd.uid b/scripts/Event/Quest/EventStartQuest.gd.uid new file mode 100644 index 0000000..639bfb3 --- /dev/null +++ b/scripts/Event/Quest/EventStartQuest.gd.uid @@ -0,0 +1 @@ +uid://c4d7nithqnx5y diff --git a/scripts/Quest/Quest.gd b/scripts/Quest/Quest.gd index 53001aa..9057b0b 100644 --- a/scripts/Quest/Quest.gd +++ b/scripts/Quest/Quest.gd @@ -2,3 +2,26 @@ class_name Quest extends Node @export var questName:String = "Some quest" @export var questKey:QuestSystem.QuestKey = QuestSystem.QuestKey.TEST_QUEST + +var questStarted:bool = false +var questComplete:bool = false + +var objectives:Array[QuestObjective] + +func _ready() -> void: + objectives = [] + for child in get_children(): + if child is QuestObjective: + objectives.append(child) + +func start() -> void: + questStarted = true + questComplete = false + QUEST.questStarted.emit(questKey) + QUEST.questUpdated.emit(questKey) + +func isCompleted() -> bool: + return questComplete + +func isStarted() -> bool: + return questStarted diff --git a/scripts/Quest/QuestObjective.gd b/scripts/Quest/QuestObjective.gd index 9e28dab..2384fe6 100644 --- a/scripts/Quest/QuestObjective.gd +++ b/scripts/Quest/QuestObjective.gd @@ -1,9 +1,7 @@ class_name QuestObjective extends Node -enum Type { - Item, -} +# enum Type { +# } @export var objectiveName:String = "Some objective" - -@export var objectiveType:Type = Type.Item \ No newline at end of file +# @export var objectiveType:Type = Type.Item \ No newline at end of file diff --git a/scripts/Quest/QuestStage.gd b/scripts/Quest/QuestStage.gd deleted file mode 100644 index e5b4b5e..0000000 --- a/scripts/Quest/QuestStage.gd +++ /dev/null @@ -1,3 +0,0 @@ -class_name QuestStage extends Node - -@export var stageName:String = "Some stage" \ No newline at end of file diff --git a/scripts/Singleton/Quest.gd b/scripts/Singleton/Quest.gd index 45aa18a..948d397 100644 --- a/scripts/Singleton/Quest.gd +++ b/scripts/Singleton/Quest.gd @@ -6,6 +6,10 @@ enum QuestKey { var quests:Dictionary[int, Quest] +signal questStarted(questKey:QuestKey) +signal questUpdated(questKey:QuestKey) +signal questCompleted(questKey:QuestKey) + func _ready() -> void: _updateQuests() diff --git a/scripts/UI/QuestMenu.gd b/scripts/UI/QuestMenu.gd index f230db1..1e648f2 100644 --- a/scripts/UI/QuestMenu.gd +++ b/scripts/UI/QuestMenu.gd @@ -3,44 +3,100 @@ class_name QuestMenu extends Panel @export var questList:ItemList @export var questName:Label @export var closeButton:Button +@export var questObjectiveList:ItemList +@export var questObjectiveInfo:Label + +var currentQuestKey +var currentQuestObjective + func _ready() -> void: hide() # Setup quests - questList.clear() - for questKey in QUEST.quests: - var q = QUEST.quests[questKey] - questList.add_item(q.questName) + _updateQuestList() + setQuest(null) # Connect signals questList.item_selected.connect(_onQuestSelected) closeButton.pressed.connect(_onCloseClicked) + questObjectiveList.item_selected.connect(_onQuestObjectiveSelected) + QUEST.questUpdated.connect(_onQuestUpdated) -func _onQuestSelected(index:int) -> void: - setQuest(index) - pass func setQuest(questKey = null): - if questKey == null: + if questKey == null || questKey == -1: + currentQuestKey = -1 + setQuestObjective(-1) questList.deselect_all() return assert(QUEST.quests.has(questKey), "Quest with key %s does not exist" % questKey) + + currentQuestKey = questKey + setQuestObjective(-1) var quest = QUEST.quests[questKey]; questList.select(questKey) + questName.text = quest.questName - pass + questObjectiveList.clear() + questObjectiveList.deselect_all() + for objective in quest.objectives: + questObjectiveList.add_item(objective.objectiveName) + + +func setQuestObjective(objective = null): + if objective == null || objective == -1: + currentQuestObjective = -1 + questObjectiveList.deselect_all() + questObjectiveList.clear() + return + + assert(QUEST.quests.has(objective), "Quest with key %s does not exist" % objective) + currentQuestObjective = objective + var quest = QUEST.quests[currentQuestKey]; + var questObjective = quest.objectives[objective] + questObjectiveList.select(objective) + + questObjectiveInfo.text = questObjective.objectiveName + "\n" -func _onCloseClicked() -> void: - self.close() func open(questKey = null) -> void: setQuest(questKey) self.show() + func close() -> void: self.hide() + func isOpen() -> bool: return self.visible + + +# Private methods +func _updateQuestList(): + questList.clear() + questList.deselect_all() + for questKey in QUEST.quests: + var q = QUEST.quests[questKey] + var n = q.questName; + if q.isCompleted(): + n += " (Complete)" + elif q.isStarted(): + n += " (Started)" + questList.add_item(n) + + +# Event handlers +func _onQuestSelected(index:int) -> void: + setQuest(index) + +func _onQuestObjectiveSelected(index:int) -> void: + setQuestObjective(index) + +func _onQuestUpdated(questKey:QuestSystem.QuestKey) -> void: + _updateQuestList() + +func _onCloseClicked() -> void: + self.close()