feat: add controller hotbar management
This commit is contained in:
parent
4ac7d5edb8
commit
ded8494cc6
4 changed files with 159 additions and 7 deletions
|
|
@ -1102,6 +1102,9 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||||
):
|
):
|
||||||
_game_ui.set_shop_prompt_visible(false)
|
_game_ui.set_shop_prompt_visible(false)
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
|
elif event is InputEventJoypadButton and _player != null:
|
||||||
|
_player.hotbar.clear_slot(_player.hotbar.get_selected_slot())
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
|
|
|
||||||
|
|
@ -210,10 +210,16 @@ func _ready() -> void:
|
||||||
_on_hotbar_presentation_transition_finished
|
_on_hotbar_presentation_transition_finished
|
||||||
)
|
)
|
||||||
_player_menu.controller_hotbar_placement_requested.connect(
|
_player_menu.controller_hotbar_placement_requested.connect(
|
||||||
_hotbar_ui.begin_controller_placement
|
_on_controller_hotbar_placement_requested
|
||||||
)
|
)
|
||||||
_player_menu.controller_hotbar_placement_ended.connect(
|
_player_menu.controller_hotbar_placement_ended.connect(
|
||||||
_hotbar_ui.end_controller_placement
|
_on_controller_hotbar_placement_ended
|
||||||
|
)
|
||||||
|
_player_menu.controller_hotbar_management_requested.connect(
|
||||||
|
_on_controller_hotbar_management_requested
|
||||||
|
)
|
||||||
|
_player_menu.controller_hotbar_management_ended.connect(
|
||||||
|
_on_controller_hotbar_management_ended
|
||||||
)
|
)
|
||||||
_title_settings_panel.panel_visibility_changed.connect(
|
_title_settings_panel.panel_visibility_changed.connect(
|
||||||
_on_settings_visibility_changed
|
_on_settings_visibility_changed
|
||||||
|
|
@ -2045,6 +2051,48 @@ func _on_inventory_hotbar_context_changed(show_hotbar: bool) -> void:
|
||||||
_refresh_hotbar_visibility()
|
_refresh_hotbar_visibility()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_controller_hotbar_placement_requested(
|
||||||
|
assignment_kind: PlayerHotbarType.AssignmentKind,
|
||||||
|
identity: StringName,
|
||||||
|
initial_slot: int,
|
||||||
|
) -> void:
|
||||||
|
_player_menu_hotbar_visible = true
|
||||||
|
_hotbar_ui.set_player_menu_context(true)
|
||||||
|
_hotbar_ui.set_drag_enabled(false)
|
||||||
|
_hotbar_ui.set_presentation_visible(true, false)
|
||||||
|
_hotbar_ui.begin_controller_placement(
|
||||||
|
assignment_kind,
|
||||||
|
identity,
|
||||||
|
initial_slot,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_controller_hotbar_placement_ended() -> void:
|
||||||
|
_hotbar_ui.end_controller_placement()
|
||||||
|
_hotbar_ui.set_drag_enabled(
|
||||||
|
_player_menu_open
|
||||||
|
and _player_menu_hotbar_visible
|
||||||
|
and not _system_menu_open
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_controller_hotbar_management_requested(initial_slot: int) -> void:
|
||||||
|
_player_menu_hotbar_visible = true
|
||||||
|
_hotbar_ui.set_player_menu_context(true)
|
||||||
|
_hotbar_ui.set_drag_enabled(false)
|
||||||
|
_hotbar_ui.set_presentation_visible(true, false)
|
||||||
|
_hotbar_ui.begin_controller_management(initial_slot)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_controller_hotbar_management_ended() -> void:
|
||||||
|
_hotbar_ui.end_controller_management()
|
||||||
|
_hotbar_ui.set_drag_enabled(
|
||||||
|
_player_menu_open
|
||||||
|
and _player_menu_hotbar_visible
|
||||||
|
and not _system_menu_open
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _on_hotbar_presentation_transition_finished(
|
func _on_hotbar_presentation_transition_finished(
|
||||||
is_visible: bool,
|
is_visible: bool,
|
||||||
) -> void:
|
) -> void:
|
||||||
|
|
|
||||||
38
ui/hotbar.gd
38
ui/hotbar.gd
|
|
@ -4,6 +4,7 @@ extends Control
|
||||||
signal presentation_transition_finished(is_visible: bool)
|
signal presentation_transition_finished(is_visible: bool)
|
||||||
|
|
||||||
const ItemCatalogType = preload("res://items/item_catalog.gd")
|
const ItemCatalogType = preload("res://items/item_catalog.gd")
|
||||||
|
const ItemDataType = preload("res://items/item_data.gd")
|
||||||
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
||||||
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
||||||
const FishInventoryType = preload("res://inventory/fish_inventory.gd")
|
const FishInventoryType = preload("res://inventory/fish_inventory.gd")
|
||||||
|
|
@ -42,6 +43,7 @@ var _motion_elapsed: float = 0.0
|
||||||
var _compact_layout: bool = false
|
var _compact_layout: bool = false
|
||||||
var _player_menu_context: bool = false
|
var _player_menu_context: bool = false
|
||||||
var _controller_placement_active: bool = false
|
var _controller_placement_active: bool = false
|
||||||
|
var _controller_management_active: bool = false
|
||||||
var _controller_placement_kind: PlayerHotbarType.AssignmentKind = (
|
var _controller_placement_kind: PlayerHotbarType.AssignmentKind = (
|
||||||
PlayerHotbarType.AssignmentKind.EMPTY
|
PlayerHotbarType.AssignmentKind.EMPTY
|
||||||
)
|
)
|
||||||
|
|
@ -147,6 +149,36 @@ func end_controller_placement() -> void:
|
||||||
_show_selected_item_briefly()
|
_show_selected_item_briefly()
|
||||||
|
|
||||||
|
|
||||||
|
func begin_controller_management(initial_slot: int) -> void:
|
||||||
|
if _hotbar == null or _slots.is_empty():
|
||||||
|
return
|
||||||
|
_controller_management_active = true
|
||||||
|
var slot_count: int = _slots.size()
|
||||||
|
for index: int in slot_count:
|
||||||
|
var slot: BubbleHotbarSlotType = _slots[index]
|
||||||
|
slot.focus_mode = Control.FOCUS_ALL
|
||||||
|
slot.focus_neighbor_left = slot.get_path_to(
|
||||||
|
_slots[wrapi(index - 1, 0, slot_count)]
|
||||||
|
)
|
||||||
|
slot.focus_neighbor_right = slot.get_path_to(
|
||||||
|
_slots[wrapi(index + 1, 0, slot_count)]
|
||||||
|
)
|
||||||
|
slot.focus_neighbor_top = slot.get_path_to(slot)
|
||||||
|
slot.focus_neighbor_bottom = slot.get_path_to(slot)
|
||||||
|
var target_index: int = clampi(initial_slot, 0, slot_count - 1)
|
||||||
|
_hotbar.select_slot(target_index)
|
||||||
|
_slots[target_index].call_deferred("grab_focus")
|
||||||
|
|
||||||
|
|
||||||
|
func end_controller_management() -> void:
|
||||||
|
if not _controller_management_active:
|
||||||
|
return
|
||||||
|
_controller_management_active = false
|
||||||
|
for slot: BubbleHotbarSlotType in _slots:
|
||||||
|
slot.focus_mode = Control.FOCUS_NONE
|
||||||
|
_show_selected_item_briefly()
|
||||||
|
|
||||||
|
|
||||||
func _resolve_controller_placement_texture() -> Texture2D:
|
func _resolve_controller_placement_texture() -> Texture2D:
|
||||||
if (
|
if (
|
||||||
_controller_placement_kind == PlayerHotbarType.AssignmentKind.FISH
|
_controller_placement_kind == PlayerHotbarType.AssignmentKind.FISH
|
||||||
|
|
@ -368,9 +400,13 @@ func _on_selected_slot_changed(
|
||||||
|
|
||||||
|
|
||||||
func _on_controller_slot_focused(slot_index: int) -> void:
|
func _on_controller_slot_focused(slot_index: int) -> void:
|
||||||
if not _controller_placement_active or _hotbar == null:
|
if (
|
||||||
|
not (_controller_placement_active or _controller_management_active)
|
||||||
|
or _hotbar == null
|
||||||
|
):
|
||||||
return
|
return
|
||||||
_hotbar.select_slot(slot_index)
|
_hotbar.select_slot(slot_index)
|
||||||
|
if _controller_placement_active:
|
||||||
_refresh_controller_placement_preview()
|
_refresh_controller_placement_preview()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ signal controller_hotbar_placement_requested(
|
||||||
initial_slot: int,
|
initial_slot: int,
|
||||||
)
|
)
|
||||||
signal controller_hotbar_placement_ended
|
signal controller_hotbar_placement_ended
|
||||||
|
signal controller_hotbar_management_requested(initial_slot: int)
|
||||||
|
signal controller_hotbar_management_ended
|
||||||
signal menu_exit_started
|
signal menu_exit_started
|
||||||
signal shop_cooler_modal_changed(is_open: bool)
|
signal shop_cooler_modal_changed(is_open: bool)
|
||||||
|
|
||||||
|
|
@ -133,6 +135,7 @@ enum CloseReason {
|
||||||
enum ControllerOwnership {
|
enum ControllerOwnership {
|
||||||
ITEM_LIST,
|
ITEM_LIST,
|
||||||
NOTEPAD_ACTIONS,
|
NOTEPAD_ACTIONS,
|
||||||
|
HOTBAR_MANAGEMENT,
|
||||||
HOTBAR_PLACEMENT,
|
HOTBAR_PLACEMENT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,6 +681,17 @@ func _handle_controller_ownership_input(event: InputEvent) -> bool:
|
||||||
JOY_BUTTON_Y,
|
JOY_BUTTON_Y,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if _controller_ownership == ControllerOwnership.HOTBAR_MANAGEMENT:
|
||||||
|
if cancel_pressed:
|
||||||
|
_release_controller_ownership(true, false)
|
||||||
|
return true
|
||||||
|
if alternate_pressed:
|
||||||
|
if _hotbar != null:
|
||||||
|
_hotbar.clear_slot(_hotbar.get_selected_slot())
|
||||||
|
return true
|
||||||
|
if accept_pressed:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
if _controller_ownership == ControllerOwnership.HOTBAR_PLACEMENT:
|
if _controller_ownership == ControllerOwnership.HOTBAR_PLACEMENT:
|
||||||
if accept_pressed:
|
if accept_pressed:
|
||||||
_confirm_controller_hotbar_placement()
|
_confirm_controller_hotbar_placement()
|
||||||
|
|
@ -902,6 +916,11 @@ func _release_controller_ownership(
|
||||||
if restore_previous_hotbar_slot and _hotbar != null:
|
if restore_previous_hotbar_slot and _hotbar != null:
|
||||||
_hotbar.select_slot(_controller_previous_hotbar_slot)
|
_hotbar.select_slot(_controller_previous_hotbar_slot)
|
||||||
controller_hotbar_placement_ended.emit()
|
controller_hotbar_placement_ended.emit()
|
||||||
|
if prior_ownership == ControllerOwnership.HOTBAR_MANAGEMENT:
|
||||||
|
controller_hotbar_management_ended.emit()
|
||||||
|
inventory_hotbar_context_changed.emit(
|
||||||
|
_current_section in [Section.COOLER, Section.BAG]
|
||||||
|
)
|
||||||
if restore_source_focus:
|
if restore_source_focus:
|
||||||
call_deferred(
|
call_deferred(
|
||||||
"_restore_controller_item_focus",
|
"_restore_controller_item_focus",
|
||||||
|
|
@ -914,7 +933,10 @@ func _restore_controller_item_focus(
|
||||||
section: Section,
|
section: Section,
|
||||||
identity: StringName,
|
identity: StringName,
|
||||||
) -> void:
|
) -> void:
|
||||||
if not visible or section != _current_section or identity.is_empty():
|
if not visible or section != _current_section:
|
||||||
|
return
|
||||||
|
if identity.is_empty():
|
||||||
|
_focus_current_section()
|
||||||
return
|
return
|
||||||
var target: Control
|
var target: Control
|
||||||
if section == Section.COOLER:
|
if section == Section.COOLER:
|
||||||
|
|
@ -940,6 +962,8 @@ func _restore_controller_item_focus(
|
||||||
and target.focus_mode != Control.FOCUS_NONE
|
and target.focus_mode != Control.FOCUS_NONE
|
||||||
):
|
):
|
||||||
target.grab_focus()
|
target.grab_focus()
|
||||||
|
else:
|
||||||
|
_focus_current_section()
|
||||||
|
|
||||||
|
|
||||||
func _handle_controller_page_switch(event: InputEvent) -> bool:
|
func _handle_controller_page_switch(event: InputEvent) -> bool:
|
||||||
|
|
@ -1047,6 +1071,10 @@ func _handle_controller_secondary_switch(event: InputEvent) -> bool:
|
||||||
return false
|
return false
|
||||||
if not button_event.pressed:
|
if not button_event.pressed:
|
||||||
return true
|
return true
|
||||||
|
var direction: int = -1 if uses_left_bumper else 1
|
||||||
|
if _controller_ownership == ControllerOwnership.HOTBAR_MANAGEMENT:
|
||||||
|
_cycle_from_controller_hotbar_management(direction)
|
||||||
|
return true
|
||||||
if (
|
if (
|
||||||
_transitioning
|
_transitioning
|
||||||
or _page_transitioning
|
or _page_transitioning
|
||||||
|
|
@ -1055,12 +1083,17 @@ func _handle_controller_secondary_switch(event: InputEvent) -> bool:
|
||||||
or _controller_ownership != ControllerOwnership.ITEM_LIST
|
or _controller_ownership != ControllerOwnership.ITEM_LIST
|
||||||
):
|
):
|
||||||
return true
|
return true
|
||||||
var direction: int = -1 if uses_left_bumper else 1
|
|
||||||
if _is_inventory_section(_current_section):
|
if _is_inventory_section(_current_section):
|
||||||
|
if (
|
||||||
|
(direction > 0 and _current_section == Section.BAG)
|
||||||
|
or (direction < 0 and _current_section == Section.COOLER)
|
||||||
|
):
|
||||||
|
_begin_controller_hotbar_management()
|
||||||
|
return true
|
||||||
var inventory_sections: Array[Section] = [
|
var inventory_sections: Array[Section] = [
|
||||||
Section.COOLER,
|
Section.COOLER,
|
||||||
Section.BAG,
|
|
||||||
Section.TACKLE_BOX,
|
Section.TACKLE_BOX,
|
||||||
|
Section.BAG,
|
||||||
]
|
]
|
||||||
var inventory_index: int = inventory_sections.find(_current_section)
|
var inventory_index: int = inventory_sections.find(_current_section)
|
||||||
_show_section(inventory_sections[wrapi(
|
_show_section(inventory_sections[wrapi(
|
||||||
|
|
@ -1073,6 +1106,35 @@ func _handle_controller_secondary_switch(event: InputEvent) -> bool:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func _begin_controller_hotbar_management() -> void:
|
||||||
|
if _hotbar == null:
|
||||||
|
return
|
||||||
|
_controller_source_section = _current_section
|
||||||
|
_controller_source_identity = StringName()
|
||||||
|
var focus_owner: Control = get_viewport().gui_get_focus_owner()
|
||||||
|
if _current_section == Section.COOLER:
|
||||||
|
var fish_node := focus_owner as CoolerFishSpriteType
|
||||||
|
if fish_node != null:
|
||||||
|
_controller_source_identity = fish_node.catch_id
|
||||||
|
elif _current_section == Section.BAG:
|
||||||
|
var item_node := focus_owner as BagItemSpriteType
|
||||||
|
if item_node != null:
|
||||||
|
_controller_source_identity = item_node.item_id
|
||||||
|
_controller_ownership = ControllerOwnership.HOTBAR_MANAGEMENT
|
||||||
|
controller_hotbar_management_requested.emit(_hotbar.get_selected_slot())
|
||||||
|
|
||||||
|
|
||||||
|
func _cycle_from_controller_hotbar_management(direction: int) -> void:
|
||||||
|
_release_controller_ownership(false, false)
|
||||||
|
var target_section: Section = (
|
||||||
|
Section.COOLER if direction > 0 else Section.BAG
|
||||||
|
)
|
||||||
|
if target_section == _current_section:
|
||||||
|
call_deferred("_focus_current_section")
|
||||||
|
else:
|
||||||
|
_show_section(target_section)
|
||||||
|
|
||||||
|
|
||||||
func _cycle_visible_secondary_tabs(direction: int) -> bool:
|
func _cycle_visible_secondary_tabs(direction: int) -> bool:
|
||||||
var navigation_cluster := get_node_or_null("%NavigationCluster") as Control
|
var navigation_cluster := get_node_or_null("%NavigationCluster") as Control
|
||||||
var grouped_buttons: Dictionary = {}
|
var grouped_buttons: Dictionary = {}
|
||||||
|
|
@ -1257,6 +1319,9 @@ func open_menu() -> void:
|
||||||
_update_shell_layout()
|
_update_shell_layout()
|
||||||
_begin_menu_entry()
|
_begin_menu_entry()
|
||||||
menu_visibility_changed.emit(true)
|
menu_visibility_changed.emit(true)
|
||||||
|
inventory_hotbar_context_changed.emit(
|
||||||
|
_current_section in [Section.COOLER, Section.BAG]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func open_section(section: Section) -> bool:
|
func open_section(section: Section) -> bool:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue