From 55081f777a37bb41ec134840456d8fd38cac0728 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 7 May 2025 11:16:08 -0500 Subject: [PATCH] Quest menu closeable --- scenes/Maps/TestMap/TestMap.tscn | 4 + scenes/UI/QuestMenu.tscn | 13 +++- scripts/Event/Quest/EventShowQuest.gd | 6 +- scripts/Item/Inventory.gd | 102 ++++++++++++++++++++++++ scripts/Item/Inventory.gd.uid | 1 + scripts/Singleton/Debug.gd | 22 ------ scripts/Singleton/Debug.gd.uid | 1 - scripts/Singleton/Item.gd | 108 ++------------------------ scripts/Singleton/UI.gd | 11 ++- scripts/UI/DebugMenu.gd | 26 +++++-- scripts/UI/QuestMenu.gd | 15 ++++ 11 files changed, 168 insertions(+), 141 deletions(-) create mode 100644 scripts/Item/Inventory.gd create mode 100644 scripts/Item/Inventory.gd.uid delete mode 100644 scripts/Singleton/Debug.gd delete mode 100644 scripts/Singleton/Debug.gd.uid diff --git a/scenes/Maps/TestMap/TestMap.tscn b/scenes/Maps/TestMap/TestMap.tscn index 37a6169..dcb4d26 100644 --- a/scenes/Maps/TestMap/TestMap.tscn +++ b/scenes/Maps/TestMap/TestMap.tscn @@ -64,3 +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") + +[node name="Text 1" type="Node" parent="Events/TestConversation"] +script = ExtResource("6_gxq5o") +text = "Thanks for closing the quest menu" diff --git a/scenes/UI/QuestMenu.tscn b/scenes/UI/QuestMenu.tscn index b24c8fe..722469b 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")] +[node name="QuestMenu" type="Panel" node_paths=PackedStringArray("questList", "questName", "closeButton")] anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -11,6 +11,7 @@ grow_vertical = 2 script = ExtResource("1_a7vj2") questList = NodePath("VBoxContainer/HBoxContainer/QuestList") questName = NodePath("VBoxContainer/HBoxContainer/Control/VBoxContainer/QuestName") +closeButton = NodePath("VBoxContainer/HBoxContainer2/Close") metadata/_custom_type_script = "uid://cbsrw36kkucje" [node name="VBoxContainer" type="VBoxContainer" parent="."] @@ -21,10 +22,18 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -[node name="Quests" type="Label" parent="VBoxContainer"] +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"] layout_mode = 2 + +[node name="Quests" type="Label" parent="VBoxContainer/HBoxContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 text = "Quests" +[node name="Close" type="Button" parent="VBoxContainer/HBoxContainer2"] +layout_mode = 2 +text = "Close" + [node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] layout_mode = 2 size_flags_vertical = 3 diff --git a/scripts/Event/Quest/EventShowQuest.gd b/scripts/Event/Quest/EventShowQuest.gd index a9103e3..58bfae0 100644 --- a/scripts/Event/Quest/EventShowQuest.gd +++ b/scripts/Event/Quest/EventShowQuest.gd @@ -4,7 +4,7 @@ class_name EventShowQuest extends "res://scripts/Event/Event.gd" @export var waitUntilClosed:bool = true func start(): - UI.showQuestsMenu(quest) + UI.QUEST_MENU.open(quest) pass func isDone() -> bool: @@ -12,6 +12,6 @@ func isDone() -> bool: return false if waitUntilClosed: - return false + return !UI.QUEST_MENU.isOpen() - return true \ No newline at end of file + return true diff --git a/scripts/Item/Inventory.gd b/scripts/Item/Inventory.gd new file mode 100644 index 0000000..e059840 --- /dev/null +++ b/scripts/Item/Inventory.gd @@ -0,0 +1,102 @@ +class_name Inventory +const Item = preload("res://scripts/Item/Item.gd"); +const ItemStack = preload("res://scripts/Item/ItemStack.gd"); + +enum ItemSortType { + NAME, + TYPE +}; + +class ItemStackNameComparator: + static func _sort(a, b): + return a.item.getName().to_lower() < b.item.getName().to_lower() + +class ItemStackTypeComparator: + static func _sort(a, b): + return a.item.getCategory() < b.item.getCategory() + +const ITEM_STACK_SIZE_MAX = 99; + +var contents:Array[ItemStack] = []; + +func addItem(item: Item, quantity: int = 1) -> void: + if !item.isStackable(): + # Item cannot be stacked, add each item to inv + for i in range(quantity): + contents.append(ItemStack.new(item, 1)) + return + + # Check for existing stacks + for stack in contents: + if stack.item != item or stack.quantity >= ITEM_STACK_SIZE_MAX: + continue + + var spaceAvailable = ITEM_STACK_SIZE_MAX - stack.quantity + + if quantity <= spaceAvailable: + stack.quantity += quantity; + return + + stack.quantity = ITEM_STACK_SIZE_MAX; + quantity -= spaceAvailable; + + # Add any remaining inventory as new stack. + while quantity > 0: + var newStackQuantity = min(quantity, ITEM_STACK_SIZE_MAX); + contents.append(ItemStack.new(item, newStackQuantity)); + quantity -= newStackQuantity; + +func removeItem(item: Item, quantity: int) -> void: + var totalQuantity = 0 + + # Calculate total quantity of the item in the inventory + for stack in contents: + if stack.item != item: + continue + totalQuantity += stack.quantity + + if totalQuantity < quantity: + push_error("Not enough quantity to remove"); + return + + # Remove the quantity from the stacks + for stack in contents: + if stack.item != item: + continue + + if stack.quantity < quantity: + quantity -= stack.quantity + contents.erase(stack) + + stack.quantity -= quantity + if stack.quantity == 0: + contents.erase(stack) + + if quantity == 0: + return + +func removeStack(stack: ItemStack) -> void: + self.removeItem(stack.item, stack.quantity); + +func hasItem(item: Item, quantity: int = 1) -> bool: + var totalQuantity = 0 + + for stack in contents: + if stack.item != item: + continue + + totalQuantity += stack.quantity + + if totalQuantity >= quantity: + return true + + return false + +func sortBy(by:ItemSortType) -> void: + match by: + ItemSortType.NAME: + contents.sort_custom(ItemStackNameComparator._sort) + ItemSortType.TYPE: + contents.sort_custom(ItemStackTypeComparator._sort) + _: + assert(false, "Invalid sort type: %s" % by) \ No newline at end of file diff --git a/scripts/Item/Inventory.gd.uid b/scripts/Item/Inventory.gd.uid new file mode 100644 index 0000000..c9b8af7 --- /dev/null +++ b/scripts/Item/Inventory.gd.uid @@ -0,0 +1 @@ +uid://dgunweso54t2t diff --git a/scripts/Singleton/Debug.gd b/scripts/Singleton/Debug.gd deleted file mode 100644 index a01081f..0000000 --- a/scripts/Singleton/Debug.gd +++ /dev/null @@ -1,22 +0,0 @@ -extends Node - -var debugMenu:DebugMenu - -func _ready() -> void: - debugMenu = $SubsceneUI/DebugMenu; - debugMenu.hide() - -func _process(delta: float) -> void: - if Input.is_action_just_pressed("debug"): - print("Debug key pressed") - if debugMenu.is_visible(): - hideMenu() - else: - showMenu() - -func showMenu() -> void: - debugMenu.show() - print("Debug menu shown") - -func hideMenu() -> void: - debugMenu.hide() diff --git a/scripts/Singleton/Debug.gd.uid b/scripts/Singleton/Debug.gd.uid deleted file mode 100644 index 3478388..0000000 --- a/scripts/Singleton/Debug.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://d36d3fnpi8y30 diff --git a/scripts/Singleton/Item.gd b/scripts/Singleton/Item.gd index d970f30..b508141 100644 --- a/scripts/Singleton/Item.gd +++ b/scripts/Singleton/Item.gd @@ -1,106 +1,8 @@ extends Node +const Inventory = preload("res://scripts/Item/Inventory.gd") -const Item = preload("res://scripts/Item/Item.gd"); -const ItemStack = preload("res://scripts/Item/ItemStack.gd"); +# Item Constants +static var POTION = preload("res://scripts/Item/Potion.gd").new(); -enum ItemSortType { - NAME, - TYPE -}; - -class ItemStackNameComparator: - static func _sort(a, b): - return a.item.getName().to_lower() < b.item.getName().to_lower() - -class ItemStackTypeComparator: - static func _sort(a, b): - return a.item.getCategory() < b.item.getCategory() - -# Constants -const ITEM_STACK_SIZE_MAX = 99; -static var ITEM_POTION = preload("res://scripts/Item/Potion.gd").new(); - -# Class -var inventory:Array[ItemStack] = []; - -# Methods -func addItem(item: Item, quantity: int = 1) -> void: - print("Adding ", quantity, "x ", item.getName()); - if !item.isStackable(): - # Item cannot be stacked, add each item to inv - for i in range(quantity): - inventory.append(ItemStack.new(item, 1)) - return - - # Check for existing stacks - for stack in inventory: - if stack.item != item or stack.quantity >= ITEM_STACK_SIZE_MAX: - continue - - var spaceAvailable = ITEM_STACK_SIZE_MAX - stack.quantity - - if quantity <= spaceAvailable: - stack.quantity += quantity; - return - - stack.quantity = ITEM_STACK_SIZE_MAX; - quantity -= spaceAvailable; - - # Add any remaining inventory as new stack. - while quantity > 0: - var newStackQuantity = min(quantity, ITEM_STACK_SIZE_MAX); - inventory.append(ItemStack.new(item, newStackQuantity)); - quantity -= newStackQuantity; - -func removeItem(item: Item, quantity: int) -> void: - var totalQuantity = 0 - - # Calculate total quantity of the item in the inventory - for stack in inventory: - if stack.item != item: - continue - totalQuantity += stack.quantity - - if totalQuantity < quantity: - push_error("Not enough quantity to remove"); - return - - # Remove the quantity from the stacks - for stack in inventory: - if stack.item != item: - continue - - if stack.quantity < quantity: - quantity -= stack.quantity - inventory.erase(stack) - - stack.quantity -= quantity - if stack.quantity == 0: - inventory.erase(stack) - - if quantity == 0: - return - -func removeStack(stack: ItemStack) -> void: - self.removeItem(stack.item, stack.quantity); - -func hasItem(item: Item, quantity: int = 1) -> bool: - var totalQuantity = 0 - - for stack in inventory: - if stack.item != item: - continue - - totalQuantity += stack.quantity - - if totalQuantity >= quantity: - return true - - return false - -func sortBy(by:ItemSortType) -> void: - match by: - ItemSortType.NAME: - inventory.sort_custom(ItemStackNameComparator._sort) - ItemSortType.TYPE: - inventory.sort_custom(ItemStackTypeComparator._sort) +# Static inventories +static var PLAYER_INVENTORY = Inventory.new(); diff --git a/scripts/Singleton/UI.gd b/scripts/Singleton/UI.gd index 636fdb8..ac92807 100644 --- a/scripts/Singleton/UI.gd +++ b/scripts/Singleton/UI.gd @@ -1,9 +1,12 @@ class_name UISystem extends Control +var QUEST_MENU:QuestMenu +var DEBUG_MENU:DebugMenu + +func _ready() -> void: + QUEST_MENU = $QuestMenu + DEBUG_MENU = $DebugMenu + func _process(delta: float) -> void: # This needs to always be at the end of the parent node's tree get_parent().move_child(self, get_parent().get_child_count() - 1) - -func showQuestsMenu(questKey = null) -> void: - $QuestMenu.setQuest(questKey) - $QuestMenu.show() diff --git a/scripts/UI/DebugMenu.gd b/scripts/UI/DebugMenu.gd index 3204560..0724240 100644 --- a/scripts/UI/DebugMenu.gd +++ b/scripts/UI/DebugMenu.gd @@ -10,6 +10,7 @@ func _ready() -> void: $Cooking.connect("pressed", _on_Cooking_pressed); $Battle.connect("pressed", _on_Battle_pressed); + # Overworld List var i:int = 0; for map in OVERWORLD.MAPS.keys(): $OverworldOption/MapDropdown.add_item(map, i); @@ -18,23 +19,27 @@ func _ready() -> void: func _process(delta: float) -> void: if Input.is_action_just_pressed("debug"): print("Debug key pressed") - if is_visible(): - hide() + if isOpen(): + close() else: - show() + open() func _on_MainMenu_pressed(): SCENE_MANAGER.setScene("MainMenu"); - hide() + close() func _on_Overworld_pressed(): var keys:Array[String] = OVERWORLD.MAPS.keys() OVERWORLD.setMap(keys[$OverworldOption/MapDropdown.selected]) SCENE_MANAGER.setScene("Overworld"); - hide() + close() func _on_Quests_pressed(): - UI.showQuestsMenu() + close() + if UI.QUEST_MENU.isOpen(): + UI.QUEST_MENU.close() + else: + UI.QUEST_MENU.open() func _on_Custscene_pressed(): print("Cutscene pressed") @@ -44,3 +49,12 @@ func _on_Cooking_pressed(): func _on_Battle_pressed(): print("Battle pressed") + +func open() -> void: + show() + +func close() -> void: + hide() + +func isOpen() -> bool: + return visible diff --git a/scripts/UI/QuestMenu.gd b/scripts/UI/QuestMenu.gd index 3f6acc5..f230db1 100644 --- a/scripts/UI/QuestMenu.gd +++ b/scripts/UI/QuestMenu.gd @@ -2,6 +2,7 @@ class_name QuestMenu extends Panel @export var questList:ItemList @export var questName:Label +@export var closeButton:Button func _ready() -> void: hide() @@ -14,6 +15,7 @@ func _ready() -> void: # Connect signals questList.item_selected.connect(_onQuestSelected) + closeButton.pressed.connect(_onCloseClicked) func _onQuestSelected(index:int) -> void: setQuest(index) @@ -29,3 +31,16 @@ func setQuest(questKey = null): questList.select(questKey) questName.text = quest.questName pass + +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