Skip to content

Instantly share code, notes, and snippets.

@N-Carter
Created May 27, 2022 16:14
Show Gist options
  • Save N-Carter/0e92d14607715e9efa4e9c5ebffaa685 to your computer and use it in GitHub Desktop.
Save N-Carter/0e92d14607715e9efa4e9c5ebffaa685 to your computer and use it in GitHub Desktop.
Inventory from Depths
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