Created
May 27, 2022 16:14
-
-
Save N-Carter/0e92d14607715e9efa4e9c5ebffaa685 to your computer and use it in GitHub Desktop.
Inventory from Depths
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class_name InventoryPanel | |
extends PopupDialog | |
export var item_slot_scene : PackedScene | |
export var scroll : NodePath | |
onready var scroll_node : ScrollContainer = get_node(scroll) | |
export var grid : NodePath | |
onready var grid_node : GridContainer = get_node(grid) | |
export var background : NodePath | |
onready var background_node : TextureRect = get_node(background) | |
export var category_label : NodePath | |
onready var category_label_node : Label = get_node(category_label) | |
export var name_label : NodePath | |
onready var name_label_node : Label = get_node(name_label) | |
export var description_label : NodePath | |
onready var description_label_node : RichTextLabel = get_node(description_label) | |
var inventory := [] | |
var is_just_looking : bool | |
var result : Pickup | |
signal on_inventory_closed | |
#func _input(event): | |
# if event.is_action_pressed("ui_cancel", false): | |
# deactivate() | |
func pick_up(pickup : Pickup): | |
# If it's a stackable object, find an existing one and add this one to it, then delete it: | |
if pickup: | |
if not is_instance_valid(pickup): | |
print("InventoryPanel.pick_up: pickup instance %s is not valid." % pickup.name) | |
var max_stack_size := pickup.get_max_stack_size() | |
if max_stack_size > 0: | |
var inventory_item := _find_matching_pickup(pickup) | |
if inventory_item: | |
inventory_item.stack_size += pickup.stack_size | |
pickup.queue_free() | |
return | |
# If it isn't stackable or we just don't have one yet, add it to the inventory: | |
inventory.append(pickup) | |
func release_one(pickup : Pickup) -> Pickup: | |
# Removes an item from the inventory and returns it, taking into account stackable items. | |
if not pickup: | |
return null | |
pickup = _find_matching_pickup(pickup) | |
assert(pickup) # It's an error for the parameter to be valid but not found in the inventory. | |
if pickup: | |
if pickup.max_stack_size > 0 and pickup.stack_size > 1: | |
# Reduce the stack size of a stackable object with more than one left: | |
pickup.stack_size -= 1 | |
var new_pickup : Pickup = pickup.duplicate() | |
new_pickup.stack_size = 1 | |
return new_pickup | |
else: | |
# Remove it from its slot in the status window: | |
var slot : ItemSlot = pickup.item_slot | |
if slot: | |
slot.contents = null | |
pickup.item_slot = null | |
# Remove the pickup from the inventory but don't delete it: | |
inventory.erase(pickup) | |
return pickup | |
func activate(mode : int, find_pickup : Pickup, just_looking : bool): | |
# mode : PickupType | |
# find_pickup - if non-null, search for the pickup and focus its item slot. | |
# just_looking - puts the inventory into a mode where it doesn't return anything. | |
is_just_looking = just_looking | |
grab_focus() | |
# print("PickupType %d" % mode) | |
name_label_node.text = "Nothing" | |
description_label_node.bbcode_text = "[center]...[/center]" | |
match mode: | |
Globals.PickupType.ANY: | |
category_label_node.text = "Inventory" | |
Globals.PickupType.ARTEFACT: | |
category_label_node.text = "Artefacts" | |
Globals.PickupType.ITEM: | |
category_label_node.text = "Items" | |
Globals.PickupType.NECKLACE: | |
category_label_node.text = "Necklaces" | |
Globals.PickupType.BRACELET: | |
category_label_node.text = "Bracelets & Anklets" | |
for pickup in inventory: | |
if mode == Globals.PickupType.ANY or pickup.type == mode: | |
# print("Adding %s to inventory grid" % pickup.name) | |
var item_slot : ItemSlot = item_slot_scene.instance() | |
item_slot.contents = pickup | |
grid_node.add_child(item_slot) | |
var _q = item_slot.connect("focus_entered", self, "_on_slot_focus", [item_slot]) | |
_q = item_slot.connect("mouse_entered", self, "_on_slot_mouse_entered", [item_slot]) | |
_q = item_slot.connect("pressed", self, "_on_slot_pressed", [item_slot]) | |
if pickup.item_slot: | |
item_slot.equipped = true | |
grid_node.connect_children() | |
call_deferred("_fix_background") | |
if find_pickup: | |
for slot in grid_node.get_children(): | |
if slot.contents == find_pickup: | |
# print("Setting inventory focus to slot %s" % slot.name) | |
call_deferred("_really_grab_focus", slot) | |
Game.paused = true | |
popup_centered() | |
func deactivate(): | |
# Calling hide() also causes _on_popup_hide() to be called by signal: | |
hide() | |
func _find_matching_pickup(pickup : Pickup) -> Pickup: | |
if not pickup: | |
return null | |
for item in inventory: | |
if item.display_name == pickup.display_name: | |
return item | |
return null | |
func _purge_grid(): | |
for child in grid_node.get_children(): | |
# print("Removing %s from inventory grid" % child.contents.name) | |
grid_node.remove_child(child) | |
child.queue_free() | |
func _on_popup_hide(): | |
# print("Hide inventory") | |
_purge_grid() | |
emit_signal("on_inventory_closed", null if is_just_looking else result) | |
result = null | |
Game.paused = false | |
func _on_slot_focus(item_slot : ItemSlot) -> void: | |
name_label_node.text = item_slot.contents.display_name | |
description_label_node.text = item_slot.contents.basic_description | |
func _on_slot_mouse_entered(item_slot : ItemSlot) -> void: | |
item_slot.grab_focus() | |
func _on_slot_pressed(item_slot : ItemSlot) -> void: | |
result = item_slot.contents | |
deactivate() | |
func _really_grab_focus(control : Control) -> void: | |
# Follow focus doesn't always scroll to the right slot if it's out of view, but this seems to work: | |
control.release_focus() | |
control.call_deferred("grab_focus") | |
func _fix_background() -> void: | |
if background_node: | |
print("Grid height: %d, scroll height: %d" % [grid_node.rect_size.y, scroll_node.rect_size.y]) | |
background_node.rect_min_size.y = grid_node.rect_size.y if grid_node.rect_size.y > scroll_node.rect_size.y else 0.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment