Quest menu closeable
This commit is contained in:
@@ -64,3 +64,7 @@ text = "I am giving you a quest to gather some ingredients."
|
|||||||
|
|
||||||
[node name="Quest" type="Node" parent="Events/TestConversation"]
|
[node name="Quest" type="Node" parent="Events/TestConversation"]
|
||||||
script = ExtResource("7_brp0k")
|
script = ExtResource("7_brp0k")
|
||||||
|
|
||||||
|
[node name="Text 1" type="Node" parent="Events/TestConversation"]
|
||||||
|
script = ExtResource("6_gxq5o")
|
||||||
|
text = "Thanks for closing the quest menu"
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cbsrw36kkucje" path="res://scripts/UI/QuestMenu.gd" id="1_a7vj2"]
|
[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
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@@ -11,6 +11,7 @@ grow_vertical = 2
|
|||||||
script = ExtResource("1_a7vj2")
|
script = ExtResource("1_a7vj2")
|
||||||
questList = NodePath("VBoxContainer/HBoxContainer/QuestList")
|
questList = NodePath("VBoxContainer/HBoxContainer/QuestList")
|
||||||
questName = NodePath("VBoxContainer/HBoxContainer/Control/VBoxContainer/QuestName")
|
questName = NodePath("VBoxContainer/HBoxContainer/Control/VBoxContainer/QuestName")
|
||||||
|
closeButton = NodePath("VBoxContainer/HBoxContainer2/Close")
|
||||||
metadata/_custom_type_script = "uid://cbsrw36kkucje"
|
metadata/_custom_type_script = "uid://cbsrw36kkucje"
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
@@ -21,10 +22,18 @@ anchor_bottom = 1.0
|
|||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
|
||||||
[node name="Quests" type="Label" parent="VBoxContainer"]
|
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Quests" type="Label" parent="VBoxContainer/HBoxContainer2"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
text = "Quests"
|
text = "Quests"
|
||||||
|
|
||||||
|
[node name="Close" type="Button" parent="VBoxContainer/HBoxContainer2"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Close"
|
||||||
|
|
||||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
|
@@ -4,7 +4,7 @@ class_name EventShowQuest extends "res://scripts/Event/Event.gd"
|
|||||||
@export var waitUntilClosed:bool = true
|
@export var waitUntilClosed:bool = true
|
||||||
|
|
||||||
func start():
|
func start():
|
||||||
UI.showQuestsMenu(quest)
|
UI.QUEST_MENU.open(quest)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func isDone() -> bool:
|
func isDone() -> bool:
|
||||||
@@ -12,6 +12,6 @@ func isDone() -> bool:
|
|||||||
return false
|
return false
|
||||||
|
|
||||||
if waitUntilClosed:
|
if waitUntilClosed:
|
||||||
return false
|
return !UI.QUEST_MENU.isOpen()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
102
scripts/Item/Inventory.gd
Normal file
102
scripts/Item/Inventory.gd
Normal file
@@ -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)
|
1
scripts/Item/Inventory.gd.uid
Normal file
1
scripts/Item/Inventory.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dgunweso54t2t
|
@@ -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()
|
|
@@ -1 +0,0 @@
|
|||||||
uid://d36d3fnpi8y30
|
|
@@ -1,106 +1,8 @@
|
|||||||
extends Node
|
extends Node
|
||||||
|
const Inventory = preload("res://scripts/Item/Inventory.gd")
|
||||||
|
|
||||||
const Item = preload("res://scripts/Item/Item.gd");
|
# Item Constants
|
||||||
const ItemStack = preload("res://scripts/Item/ItemStack.gd");
|
static var POTION = preload("res://scripts/Item/Potion.gd").new();
|
||||||
|
|
||||||
enum ItemSortType {
|
# Static inventories
|
||||||
NAME,
|
static var PLAYER_INVENTORY = Inventory.new();
|
||||||
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)
|
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
class_name UISystem extends Control
|
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:
|
func _process(delta: float) -> void:
|
||||||
# This needs to always be at the end of the parent node's tree
|
# 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)
|
get_parent().move_child(self, get_parent().get_child_count() - 1)
|
||||||
|
|
||||||
func showQuestsMenu(questKey = null) -> void:
|
|
||||||
$QuestMenu.setQuest(questKey)
|
|
||||||
$QuestMenu.show()
|
|
||||||
|
@@ -10,6 +10,7 @@ func _ready() -> void:
|
|||||||
$Cooking.connect("pressed", _on_Cooking_pressed);
|
$Cooking.connect("pressed", _on_Cooking_pressed);
|
||||||
$Battle.connect("pressed", _on_Battle_pressed);
|
$Battle.connect("pressed", _on_Battle_pressed);
|
||||||
|
|
||||||
|
# Overworld List
|
||||||
var i:int = 0;
|
var i:int = 0;
|
||||||
for map in OVERWORLD.MAPS.keys():
|
for map in OVERWORLD.MAPS.keys():
|
||||||
$OverworldOption/MapDropdown.add_item(map, i);
|
$OverworldOption/MapDropdown.add_item(map, i);
|
||||||
@@ -18,23 +19,27 @@ func _ready() -> void:
|
|||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
if Input.is_action_just_pressed("debug"):
|
if Input.is_action_just_pressed("debug"):
|
||||||
print("Debug key pressed")
|
print("Debug key pressed")
|
||||||
if is_visible():
|
if isOpen():
|
||||||
hide()
|
close()
|
||||||
else:
|
else:
|
||||||
show()
|
open()
|
||||||
|
|
||||||
func _on_MainMenu_pressed():
|
func _on_MainMenu_pressed():
|
||||||
SCENE_MANAGER.setScene("MainMenu");
|
SCENE_MANAGER.setScene("MainMenu");
|
||||||
hide()
|
close()
|
||||||
|
|
||||||
func _on_Overworld_pressed():
|
func _on_Overworld_pressed():
|
||||||
var keys:Array[String] = OVERWORLD.MAPS.keys()
|
var keys:Array[String] = OVERWORLD.MAPS.keys()
|
||||||
OVERWORLD.setMap(keys[$OverworldOption/MapDropdown.selected])
|
OVERWORLD.setMap(keys[$OverworldOption/MapDropdown.selected])
|
||||||
SCENE_MANAGER.setScene("Overworld");
|
SCENE_MANAGER.setScene("Overworld");
|
||||||
hide()
|
close()
|
||||||
|
|
||||||
func _on_Quests_pressed():
|
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():
|
func _on_Custscene_pressed():
|
||||||
print("Cutscene pressed")
|
print("Cutscene pressed")
|
||||||
@@ -44,3 +49,12 @@ func _on_Cooking_pressed():
|
|||||||
|
|
||||||
func _on_Battle_pressed():
|
func _on_Battle_pressed():
|
||||||
print("Battle pressed")
|
print("Battle pressed")
|
||||||
|
|
||||||
|
func open() -> void:
|
||||||
|
show()
|
||||||
|
|
||||||
|
func close() -> void:
|
||||||
|
hide()
|
||||||
|
|
||||||
|
func isOpen() -> bool:
|
||||||
|
return visible
|
||||||
|
@@ -2,6 +2,7 @@ class_name QuestMenu extends Panel
|
|||||||
|
|
||||||
@export var questList:ItemList
|
@export var questList:ItemList
|
||||||
@export var questName:Label
|
@export var questName:Label
|
||||||
|
@export var closeButton:Button
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
hide()
|
hide()
|
||||||
@@ -14,6 +15,7 @@ func _ready() -> void:
|
|||||||
|
|
||||||
# Connect signals
|
# Connect signals
|
||||||
questList.item_selected.connect(_onQuestSelected)
|
questList.item_selected.connect(_onQuestSelected)
|
||||||
|
closeButton.pressed.connect(_onCloseClicked)
|
||||||
|
|
||||||
func _onQuestSelected(index:int) -> void:
|
func _onQuestSelected(index:int) -> void:
|
||||||
setQuest(index)
|
setQuest(index)
|
||||||
@@ -29,3 +31,16 @@ func setQuest(questKey = null):
|
|||||||
questList.select(questKey)
|
questList.select(questKey)
|
||||||
questName.text = quest.questName
|
questName.text = quest.questName
|
||||||
pass
|
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
|
||||||
|
Reference in New Issue
Block a user