186 lines
4.8 KiB
GDScript3
186 lines
4.8 KiB
GDScript3
|
|
class_name HotbarUI
|
||
|
|
extends Control
|
||
|
|
|
||
|
|
const ItemCatalogType = preload("res://items/item_catalog.gd")
|
||
|
|
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
||
|
|
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
||
|
|
const HotbarSlotType = preload("res://ui/hotbar_slot.gd")
|
||
|
|
const FishingSpotType = preload("res://fishing/fishing_spot.gd")
|
||
|
|
|
||
|
|
@onready var _slot_row: HBoxContainer = %SlotRow
|
||
|
|
@onready var _selected_item_label: Label = %SelectedItemLabel
|
||
|
|
@onready var _item_name_timer: Timer = %ItemNameTimer
|
||
|
|
|
||
|
|
var _hotbar: PlayerHotbarType
|
||
|
|
var _bag: PlayerBagType
|
||
|
|
var _catalog: ItemCatalogType
|
||
|
|
var _fishing_spot: FishingSpotType
|
||
|
|
var _slots: Array[HotbarSlotType] = []
|
||
|
|
var _gameplay_input_enabled: bool = false
|
||
|
|
var _drag_enabled: bool = false
|
||
|
|
var _hovered_slot_index: int = -1
|
||
|
|
var _item_name_suppressed: bool = false
|
||
|
|
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
_item_name_timer.timeout.connect(_on_item_name_timer_timeout)
|
||
|
|
|
||
|
|
|
||
|
|
func setup(
|
||
|
|
hotbar: PlayerHotbarType,
|
||
|
|
bag: PlayerBagType,
|
||
|
|
catalog: ItemCatalogType,
|
||
|
|
fishing_spot: FishingSpotType,
|
||
|
|
) -> void:
|
||
|
|
_hotbar = hotbar
|
||
|
|
_bag = bag
|
||
|
|
_catalog = catalog
|
||
|
|
_fishing_spot = fishing_spot
|
||
|
|
if not _hotbar.slots_changed.is_connected(_refresh):
|
||
|
|
_hotbar.slots_changed.connect(_refresh)
|
||
|
|
if not _hotbar.selected_slot_changed.is_connected(
|
||
|
|
_on_selected_slot_changed
|
||
|
|
):
|
||
|
|
_hotbar.selected_slot_changed.connect(_on_selected_slot_changed)
|
||
|
|
if not _bag.contents_changed.is_connected(_refresh):
|
||
|
|
_bag.contents_changed.connect(_refresh)
|
||
|
|
_build_slots()
|
||
|
|
_refresh()
|
||
|
|
|
||
|
|
|
||
|
|
func set_gameplay_input_enabled(enabled: bool) -> void:
|
||
|
|
_gameplay_input_enabled = enabled
|
||
|
|
|
||
|
|
|
||
|
|
func set_drag_enabled(enabled: bool) -> void:
|
||
|
|
_drag_enabled = enabled
|
||
|
|
for slot: HotbarSlotType in _slots:
|
||
|
|
slot.set_drag_enabled(enabled)
|
||
|
|
if not enabled:
|
||
|
|
_hovered_slot_index = -1
|
||
|
|
_hide_item_name()
|
||
|
|
|
||
|
|
|
||
|
|
func set_item_name_suppressed(suppressed: bool) -> void:
|
||
|
|
_item_name_suppressed = suppressed
|
||
|
|
if suppressed:
|
||
|
|
_hovered_slot_index = -1
|
||
|
|
_hide_item_name()
|
||
|
|
|
||
|
|
|
||
|
|
func _unhandled_input(event: InputEvent) -> void:
|
||
|
|
if (
|
||
|
|
not _gameplay_input_enabled
|
||
|
|
or _hotbar == null
|
||
|
|
or _fishing_spot == null
|
||
|
|
or not _fishing_spot.can_change_hotbar_selection()
|
||
|
|
):
|
||
|
|
return
|
||
|
|
if event is InputEventKey and event.pressed and not event.echo:
|
||
|
|
for index: int in range(PlayerHotbarType.SLOT_COUNT):
|
||
|
|
if event.is_action_pressed("hotbar_%d" % (index + 1)):
|
||
|
|
_hotbar.select_slot(index)
|
||
|
|
get_viewport().set_input_as_handled()
|
||
|
|
return
|
||
|
|
if (
|
||
|
|
event is InputEventMouseButton
|
||
|
|
and event.pressed
|
||
|
|
and not event.shift_pressed
|
||
|
|
):
|
||
|
|
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
||
|
|
_hotbar.cycle_selection(-1)
|
||
|
|
get_viewport().set_input_as_handled()
|
||
|
|
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
||
|
|
_hotbar.cycle_selection(1)
|
||
|
|
get_viewport().set_input_as_handled()
|
||
|
|
|
||
|
|
|
||
|
|
func _build_slots() -> void:
|
||
|
|
for child: Node in _slot_row.get_children():
|
||
|
|
child.queue_free()
|
||
|
|
_slots.clear()
|
||
|
|
for index: int in range(PlayerHotbarType.SLOT_COUNT):
|
||
|
|
var slot := HotbarSlotType.new()
|
||
|
|
slot.toggle_mode = true
|
||
|
|
slot.setup(index, _hotbar, _bag, _catalog)
|
||
|
|
slot.set_drag_enabled(_drag_enabled)
|
||
|
|
slot.item_hovered.connect(_on_slot_item_hovered)
|
||
|
|
slot.item_hover_ended.connect(_on_slot_item_hover_ended)
|
||
|
|
slot.item_drag_started.connect(_on_slot_drag_started)
|
||
|
|
slot.item_drag_finished.connect(_on_slot_drag_finished)
|
||
|
|
_slot_row.add_child(slot)
|
||
|
|
_slots.append(slot)
|
||
|
|
|
||
|
|
|
||
|
|
func _refresh() -> void:
|
||
|
|
for slot: HotbarSlotType in _slots:
|
||
|
|
slot.refresh()
|
||
|
|
|
||
|
|
|
||
|
|
func _on_selected_slot_changed(
|
||
|
|
_slot_index: int,
|
||
|
|
_item_id: StringName,
|
||
|
|
) -> void:
|
||
|
|
_refresh()
|
||
|
|
if _hovered_slot_index < 0:
|
||
|
|
_show_selected_item_briefly()
|
||
|
|
|
||
|
|
|
||
|
|
func _on_slot_item_hovered(
|
||
|
|
slot_index: int,
|
||
|
|
item_id: StringName,
|
||
|
|
) -> void:
|
||
|
|
if _item_name_suppressed:
|
||
|
|
return
|
||
|
|
_hovered_slot_index = slot_index
|
||
|
|
_item_name_timer.stop()
|
||
|
|
_show_item_name(item_id)
|
||
|
|
|
||
|
|
|
||
|
|
func _on_slot_item_hover_ended(slot_index: int) -> void:
|
||
|
|
if slot_index != _hovered_slot_index:
|
||
|
|
return
|
||
|
|
_hovered_slot_index = -1
|
||
|
|
_show_selected_item_briefly()
|
||
|
|
|
||
|
|
|
||
|
|
func _on_slot_drag_started() -> void:
|
||
|
|
_hovered_slot_index = -1
|
||
|
|
_hide_item_name()
|
||
|
|
|
||
|
|
|
||
|
|
func _on_slot_drag_finished() -> void:
|
||
|
|
_show_selected_item_briefly()
|
||
|
|
|
||
|
|
|
||
|
|
func _show_selected_item_briefly() -> void:
|
||
|
|
if _item_name_suppressed or _hotbar == null:
|
||
|
|
_hide_item_name()
|
||
|
|
return
|
||
|
|
_show_item_name(_hotbar.get_selected_item_id())
|
||
|
|
if _selected_item_label.visible:
|
||
|
|
_item_name_timer.start()
|
||
|
|
|
||
|
|
|
||
|
|
func _show_item_name(item_id: StringName) -> void:
|
||
|
|
if item_id.is_empty() or _catalog == null:
|
||
|
|
_hide_item_name()
|
||
|
|
return
|
||
|
|
var item := _catalog.get_item_by_id(item_id)
|
||
|
|
if item == null:
|
||
|
|
_hide_item_name()
|
||
|
|
return
|
||
|
|
_selected_item_label.text = item.display_name
|
||
|
|
_selected_item_label.visible = true
|
||
|
|
|
||
|
|
|
||
|
|
func _hide_item_name() -> void:
|
||
|
|
_item_name_timer.stop()
|
||
|
|
_selected_item_label.text = ""
|
||
|
|
_selected_item_label.visible = false
|
||
|
|
|
||
|
|
|
||
|
|
func _on_item_name_timer_timeout() -> void:
|
||
|
|
if _hovered_slot_index < 0:
|
||
|
|
_hide_item_name()
|