# This file is part of open-fpsz. # copyright (c) 2024 - anyreso & open-fpsz contributors # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . @tool ## This component allows its entity to hold [Weapon] nodes. class_name Inventory extends Node3D signal selection_changed(index : int) signal selected(node: Node) signal unselected(node: Node) const _max_items = 3 ## This is the total capacity of inventory. @export_range(0, _max_items) var capacity : int = _max_items: set(value): capacity = clamp(value, 1, _max_items) @export_range(0, _max_items - 1) var cursor : int = 0: set = set_cursor # Function to set the cursor position in the inventory func set_cursor(new_cursor: int) -> void: # Ensure the cursor is within the valid range if new_cursor >= 0 and new_cursor < _max_items: # emit unselected signal _emit_child(unselected, cursor) # update cursor position cursor = new_cursor # emit selected signal _emit_child(selected, cursor) # helper function to emit the selected signal for the current cursor position func _emit_child(sig: Signal, idx: int) -> void: var child : Node = get_child(idx) if child: sig.emit(child) func _ready() -> void: unselected.connect(_on_unselected) selected.connect(_on_selected) func _on_unselected(node: Node) -> void: node.hide() func _on_selected(node: Node) -> void: node.show() ## This method overrides [method Node.add_child] to make sure not to exceed ## inventory capacity. func _add_child(node: Node, force_readable_name: bool = false, internal: InternalMode = InternalMode.INTERNAL_MODE_DISABLED) -> void: if get_child_count() <= capacity: super.add_child(node, force_readable_name, internal) else: push_warning("inventory is full") ## This method moves the [member selection] cursor to specified item index. func select(index : int) -> void: cursor = wrapi(index, 0, get_child_count()) ## This method cycles through items in the inventory. func cycle(shift : int = 1) -> void: select(cursor + shift)