Loading and saving of ItemStack based inventory works.
parent
421a7636df
commit
2422f72be9
23
inventory.gd
23
inventory.gd
|
@ -4,19 +4,18 @@ var _content:Array[ItemStack] = []
|
||||||
const INVENTORY_SIZE:int = 36
|
const INVENTORY_SIZE:int = 36
|
||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
_content.resize(INVENTORY_SIZE)
|
clear()
|
||||||
|
|
||||||
func get_free_item_stack_index() -> int:
|
func get_free_item_stack_index() -> int:
|
||||||
for i:int in range(_content.size()):
|
for i:int in range(_content.size()):
|
||||||
if _content[i] == null:
|
if _content[i].count == 0:
|
||||||
return i
|
return i
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
func add_item(item:Item) -> bool:
|
func add_item(item:Item) -> bool:
|
||||||
for item_stack:ItemStack in _content:
|
for item_stack:ItemStack in _content:
|
||||||
if item_stack == null:
|
if item_stack.count == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if item_stack.item.resource_path != item.resource_path:
|
if item_stack.item.resource_path != item.resource_path:
|
||||||
|
@ -28,10 +27,8 @@ func add_item(item:Item) -> bool:
|
||||||
|
|
||||||
var item_stack_index:int = get_free_item_stack_index()
|
var item_stack_index:int = get_free_item_stack_index()
|
||||||
if item_stack_index >= 0:
|
if item_stack_index >= 0:
|
||||||
var item_stack:ItemStack = ItemStack.new()
|
_content[item_stack_index].item = item
|
||||||
item_stack.item = item
|
_content[item_stack_index].count = 1
|
||||||
item_stack.count = 1
|
|
||||||
_content[item_stack_index] = item_stack
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -39,14 +36,12 @@ func add_item(item:Item) -> bool:
|
||||||
func remove_item(item:Item):
|
func remove_item(item:Item):
|
||||||
for i in range(_content.size() - 1, -1, -1):
|
for i in range(_content.size() - 1, -1, -1):
|
||||||
var item_stack:ItemStack = _content[i]
|
var item_stack:ItemStack = _content[i]
|
||||||
if item_stack == null:
|
if item_stack.count == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if item_stack.item.resource_path == item.resource_path:
|
if item_stack.item.resource_path == item.resource_path:
|
||||||
if item_stack.count > 1:
|
if item_stack.count > 1:
|
||||||
item_stack.count = item_stack.count - 1
|
item_stack.count = item_stack.count - 1
|
||||||
else:
|
|
||||||
_content[i] = null
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -57,13 +52,17 @@ func get_item_stacks() -> Array[ItemStack]:
|
||||||
|
|
||||||
func clear() -> void:
|
func clear() -> void:
|
||||||
_content.clear()
|
_content.clear()
|
||||||
|
_content.resize(INVENTORY_SIZE)
|
||||||
|
for i:int in range(_content.size()):
|
||||||
|
if _content[i] == null:
|
||||||
|
_content[i] = ItemStack.new()
|
||||||
|
|
||||||
|
|
||||||
func has_all(items:Array[Item]) -> bool:
|
func has_all(items:Array[Item]) -> bool:
|
||||||
var needed:Array[Item] = items.duplicate()
|
var needed:Array[Item] = items.duplicate()
|
||||||
|
|
||||||
for item_stack:ItemStack in _content:
|
for item_stack:ItemStack in _content:
|
||||||
if item_stack == null:
|
if item_stack.count == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for i in range (item_stack.count):
|
for i in range (item_stack.count):
|
||||||
|
|
|
@ -5,5 +5,5 @@ extends Resource
|
||||||
@export var player_name:String
|
@export var player_name:String
|
||||||
@export var quest_states:Dictionary
|
@export var quest_states:Dictionary
|
||||||
@export var player_transform:Transform3D
|
@export var player_transform:Transform3D
|
||||||
@export var inventory:Array[Item]
|
@export var inventory:Array
|
||||||
@export var level_pickup_items:Array[NodePath]
|
@export var level_pickup_items:Array[NodePath]
|
||||||
|
|
|
@ -28,8 +28,8 @@ func save_game():
|
||||||
if (property.usage & PROPERTY_USAGE_STORAGE != 0) and (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) != 0:
|
if (property.usage & PROPERTY_USAGE_STORAGE != 0) and (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) != 0:
|
||||||
save_game.quest_states[node.name][property.name] = node.get(property.name)
|
save_game.quest_states[node.name][property.name] = node.get(property.name)
|
||||||
|
|
||||||
for item in player.inventory.get_items():
|
for item_stack in player.inventory.get_item_stacks():
|
||||||
save_game.inventory.append(item)
|
save_game.inventory.append({"item": item_stack.item, "count": item_stack.count})
|
||||||
|
|
||||||
ResourceSaver.save(save_game, "user://savegame.tres")
|
ResourceSaver.save(save_game, "user://savegame.tres")
|
||||||
root_ui.activate_ui_panel(%GameUI)
|
root_ui.activate_ui_panel(%GameUI)
|
||||||
|
@ -57,8 +57,13 @@ func load_game():
|
||||||
|
|
||||||
# Inventory
|
# Inventory
|
||||||
player.inventory.clear()
|
player.inventory.clear()
|
||||||
for item in save_game.inventory:
|
var inventory_item_stacks:Array[ItemStack] = player.inventory.get_item_stacks()
|
||||||
player.inventory.add_item(item)
|
|
||||||
|
assert(inventory_item_stacks.size() >= save_game.inventory.size())
|
||||||
|
|
||||||
|
for i in range(save_game.inventory.size()):
|
||||||
|
inventory_item_stacks[i].item = save_game.inventory[i]["item"]
|
||||||
|
inventory_item_stacks[i].count = save_game.inventory[i]["count"]
|
||||||
|
|
||||||
# Picked up items
|
# Picked up items
|
||||||
for item_path in save_game.level_pickup_items:
|
for item_path in save_game.level_pickup_items:
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
class_name ItemDrag
|
||||||
|
|
||||||
|
signal drag_completed(data:ItemDrag)
|
||||||
|
|
||||||
|
var source:Control = null
|
||||||
|
var destination:Control = null
|
||||||
|
|
||||||
|
var preview:Control
|
||||||
|
|
||||||
|
func _init(source_control: Control, preview_control:Control):
|
||||||
|
self.source = source_control
|
||||||
|
self.preview = preview_control
|
||||||
|
self.preview.tree_exiting.connect(self._on_tree_exiting)
|
||||||
|
|
||||||
|
func _on_tree_exiting()->void:
|
||||||
|
drag_completed.emit(self)
|
|
@ -11,10 +11,11 @@ func displayStacks(item_stacks:Array[ItemStack]):
|
||||||
|
|
||||||
for item_stack in item_stacks:
|
for item_stack in item_stacks:
|
||||||
var slot:ItemSlot = slot_scene.instantiate()
|
var slot:ItemSlot = slot_scene.instantiate()
|
||||||
|
slot.set_drag_drop_flags(ItemSlot.ALLOW_DRAG | ItemSlot.ALLOW_DROP)
|
||||||
add_child(slot)
|
add_child(slot)
|
||||||
|
|
||||||
if item_stack != null:
|
if item_stack != null:
|
||||||
slot.display(item_stack.item, item_stack.count)
|
slot.display(item_stack)
|
||||||
|
|
||||||
var item_count = rows * columns
|
var item_count = rows * columns
|
||||||
|
|
||||||
|
@ -29,7 +30,10 @@ func display(item_stacks:Array[Item]):
|
||||||
for item in item_stacks:
|
for item in item_stacks:
|
||||||
var slot:ItemSlot = slot_scene.instantiate()
|
var slot:ItemSlot = slot_scene.instantiate()
|
||||||
add_child(slot)
|
add_child(slot)
|
||||||
slot.display(item, 1)
|
var item_stack:ItemStack = ItemStack.new()
|
||||||
|
item_stack.item = item
|
||||||
|
item_stack.count = 1
|
||||||
|
slot.display(item_stack)
|
||||||
|
|
||||||
var item_count = rows * columns
|
var item_count = rows * columns
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,33 @@
|
||||||
class_name ItemSlot
|
class_name ItemSlot
|
||||||
extends PanelContainer
|
extends PanelContainer
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ALLOW_DRAG = 1,
|
||||||
|
ALLOW_DROP = 2
|
||||||
|
}
|
||||||
|
|
||||||
@onready var texture_rect:TextureRect = %TextureRect
|
@onready var texture_rect:TextureRect = %TextureRect
|
||||||
@onready var count_label = %CountLabel
|
@onready var count_label = %CountLabel
|
||||||
|
|
||||||
func display(item:Item, count:int):
|
var drag_drop_flags:int = 0
|
||||||
if item != null:
|
var _item_stack:ItemStack = null
|
||||||
texture_rect.texture = item.icon
|
|
||||||
update_quantity_text(count)
|
func set_drag_drop_flags(flags:int) -> void:
|
||||||
|
drag_drop_flags = flags
|
||||||
|
|
||||||
|
func display(item_stack):
|
||||||
|
_item_stack = item_stack
|
||||||
|
|
||||||
|
func _process(_delta)->void:
|
||||||
|
if _item_stack == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
if _item_stack.count == 0:
|
||||||
|
texture_rect.texture = null
|
||||||
|
update_quantity_text(0)
|
||||||
|
else:
|
||||||
|
texture_rect.texture = _item_stack.item.icon
|
||||||
|
update_quantity_text(_item_stack.count)
|
||||||
|
|
||||||
func update_quantity_text(stack_size) -> void:
|
func update_quantity_text(stack_size) -> void:
|
||||||
if stack_size <= 1:
|
if stack_size <= 1:
|
||||||
|
@ -15,3 +35,50 @@ func update_quantity_text(stack_size) -> void:
|
||||||
else:
|
else:
|
||||||
count_label.text = str(stack_size)
|
count_label.text = str(stack_size)
|
||||||
count_label.show()
|
count_label.show()
|
||||||
|
|
||||||
|
func _get_drag_data(_at_position:Vector2)->Variant:
|
||||||
|
if drag_drop_flags & ALLOW_DRAG == 0:
|
||||||
|
return null
|
||||||
|
|
||||||
|
if _item_stack == null:
|
||||||
|
return null
|
||||||
|
|
||||||
|
var drag_data:ItemDrag = ItemDrag.new(self, self)
|
||||||
|
|
||||||
|
var drag_preview = load("res://ui/item_slot.tscn").instantiate()
|
||||||
|
var drag_stack = ItemStack.new()
|
||||||
|
drag_stack.item = _item_stack.item
|
||||||
|
drag_stack.count = _item_stack.count
|
||||||
|
drag_preview.display(drag_stack)
|
||||||
|
set_drag_preview(drag_preview)
|
||||||
|
|
||||||
|
return drag_data
|
||||||
|
|
||||||
|
func _can_drop_data(_at_position:Vector2, data:Variant)->bool:
|
||||||
|
if drag_drop_flags & ALLOW_DROP == 0:
|
||||||
|
return false
|
||||||
|
|
||||||
|
if !data is ItemDrag:
|
||||||
|
return false
|
||||||
|
|
||||||
|
return _item_stack.count == 0
|
||||||
|
|
||||||
|
func _drop_data(_at_position:Vector2, data:Variant)->void:
|
||||||
|
if drag_drop_flags & ALLOW_DROP == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
if !data is ItemDrag:
|
||||||
|
return
|
||||||
|
|
||||||
|
var drag_data := data as ItemDrag
|
||||||
|
|
||||||
|
drag_data.destination = self
|
||||||
|
if drag_data.source is ItemSlot:
|
||||||
|
var source_slot := drag_data.source as ItemSlot
|
||||||
|
|
||||||
|
# add stuff to the destination
|
||||||
|
self._item_stack.item = source_slot._item_stack.item
|
||||||
|
self._item_stack.count = source_slot._item_stack.count
|
||||||
|
|
||||||
|
# remove it from the source
|
||||||
|
source_slot._item_stack.count = 0
|
||||||
|
|
|
@ -2,8 +2,4 @@ class_name ItemStack
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
var item:Item = null
|
var item:Item = null
|
||||||
@export var count:int = 1
|
var count:int = 0
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
|
||||||
func _ready():
|
|
||||||
pass # Replace with function body.
|
|
||||||
|
|
|
@ -6,8 +6,3 @@ extends HBoxContainer
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready():
|
func _ready():
|
||||||
pass # Replace with function body.
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
||||||
func _process(delta):
|
|
||||||
pass
|
|
||||||
|
|
Loading…
Reference in New Issue