forked from woofmeow/straywild
Polish interface artwork and controller behavior
This commit is contained in:
parent
c6b897718c
commit
f8e02e3844
41 changed files with 1119 additions and 171 deletions
|
|
@ -87,14 +87,25 @@ func _run() -> void:
|
|||
assert(player != null and service != null and toolbar != null)
|
||||
assert(chat_ui != null)
|
||||
assert(bool(game_ui.call("_can_start_virtual_mouse")))
|
||||
var virtual_pointer_states: Array[bool] = []
|
||||
game_ui.virtual_pointer_mode_changed.connect(
|
||||
func(active: bool) -> void: virtual_pointer_states.append(active)
|
||||
)
|
||||
game_ui.call("_begin_virtual_mouse", 0)
|
||||
var virtual_cursor := game_ui.get_node(
|
||||
"%ControllerVirtualCursor"
|
||||
) as ControllerVirtualCursor
|
||||
assert(virtual_cursor.visible)
|
||||
assert(virtual_pointer_states == [true])
|
||||
# PopupMenu subwindows can consume the physical shoulder release. The
|
||||
# polled primary-button state must still release the synthetic mouse click.
|
||||
game_ui.set("_virtual_mouse_button_mask", MOUSE_BUTTON_MASK_LEFT)
|
||||
game_ui.call("_sync_virtual_mouse_primary_button", false)
|
||||
assert(int(game_ui.get("_virtual_mouse_button_mask")) == 0)
|
||||
assert(not player.is_camera_input_enabled())
|
||||
game_ui.call("_end_virtual_mouse")
|
||||
assert(not virtual_cursor.visible)
|
||||
assert(virtual_pointer_states == [true, false])
|
||||
assert(player.is_camera_input_enabled())
|
||||
var settings_panel := game_ui.get(
|
||||
"_pause_settings_panel"
|
||||
|
|
@ -131,6 +142,12 @@ func _run() -> void:
|
|||
changed_docks.paint_dock_right = false
|
||||
assert(settings_manager.apply_settings(changed_docks))
|
||||
await process_frame
|
||||
assert(not chat_ui.is_docked_right())
|
||||
assert(not chat_ui.is_mobile_mode())
|
||||
assert(toolbar.is_docked_right())
|
||||
changed_docks.presentation_layout_customized = true
|
||||
assert(settings_manager.apply_settings(changed_docks))
|
||||
await process_frame
|
||||
assert(chat_ui.is_docked_right())
|
||||
assert(chat_ui.is_mobile_mode())
|
||||
assert(not toolbar.is_docked_right())
|
||||
|
|
@ -153,7 +170,31 @@ func _run() -> void:
|
|||
assert(reloaded_settings.current_settings.chat_dock_right)
|
||||
assert(reloaded_settings.current_settings.chat_mobile_mode)
|
||||
assert(not reloaded_settings.current_settings.paint_dock_right)
|
||||
assert(reloaded_settings.current_settings.presentation_layout_customized)
|
||||
reloaded_settings.queue_free()
|
||||
var legacy_data: Dictionary = JSON.parse_string(
|
||||
FileAccess.get_file_as_string(PlayerSettingsManager.SETTINGS_PATH)
|
||||
) as Dictionary
|
||||
var legacy_presentation := legacy_data.get("presentation", {}) as Dictionary
|
||||
legacy_presentation.erase("layout_customized")
|
||||
legacy_data["presentation"] = legacy_presentation
|
||||
var legacy_file := FileAccess.open(
|
||||
PlayerSettingsManager.SETTINGS_PATH,
|
||||
FileAccess.WRITE,
|
||||
)
|
||||
assert(legacy_file != null)
|
||||
legacy_file.store_string(JSON.stringify(legacy_data, "\t"))
|
||||
legacy_file.close()
|
||||
var migrated_legacy_settings := PlayerSettingsManager.new()
|
||||
root.add_child(migrated_legacy_settings)
|
||||
assert(migrated_legacy_settings.load_settings())
|
||||
assert(not migrated_legacy_settings.current_settings.chat_dock_right)
|
||||
assert(not migrated_legacy_settings.current_settings.chat_mobile_mode)
|
||||
assert(migrated_legacy_settings.current_settings.paint_dock_right)
|
||||
assert(
|
||||
not migrated_legacy_settings.current_settings.presentation_layout_customized
|
||||
)
|
||||
migrated_legacy_settings.queue_free()
|
||||
var default_docks: PlayerSettings = settings_manager.current_settings.copy()
|
||||
default_docks.chat_dock_right = false
|
||||
default_docks.chat_mobile_mode = false
|
||||
|
|
@ -456,18 +497,39 @@ func _run() -> void:
|
|||
assert(grid_option.get_item_text(index).is_empty())
|
||||
assert(brush_option.get_item_icon(index) != null)
|
||||
assert(grid_option.get_item_icon(index) != null)
|
||||
assert(
|
||||
str(brush_option.get_item_icon(index).get_meta(
|
||||
&"channel_mask_source", ""
|
||||
)).ends_with(
|
||||
expected_brush_icons[index]
|
||||
var brush_unlocked: bool = index == 0
|
||||
var grid_unlocked: bool = index == 0
|
||||
if brush_unlocked:
|
||||
assert(
|
||||
str(brush_option.get_item_icon(index).get_meta(
|
||||
&"channel_mask_source", ""
|
||||
)).ends_with(
|
||||
expected_brush_icons[index]
|
||||
)
|
||||
)
|
||||
)
|
||||
assert(
|
||||
grid_option.get_item_icon(index).resource_path.ends_with(
|
||||
expected_grid_icons[index]
|
||||
else:
|
||||
assert(bool(brush_option.get_item_icon(index).get_meta(
|
||||
&"locked_content_icon", false
|
||||
)))
|
||||
if grid_unlocked:
|
||||
assert(
|
||||
grid_option.get_item_icon(index).resource_path.ends_with(
|
||||
expected_grid_icons[index]
|
||||
)
|
||||
)
|
||||
)
|
||||
else:
|
||||
assert(bool(grid_option.get_item_icon(index).get_meta(
|
||||
&"locked_content_icon", false
|
||||
)))
|
||||
var expected_lock_alpha: float = 1.0 if index == 0 else 0.72
|
||||
assert(is_equal_approx(
|
||||
brush_option.get_popup().get_item_icon_modulate(index).a,
|
||||
expected_lock_alpha,
|
||||
))
|
||||
assert(is_equal_approx(
|
||||
grid_option.get_popup().get_item_icon_modulate(index).a,
|
||||
expected_lock_alpha,
|
||||
))
|
||||
assert(not brush_option.get_popup().is_item_disabled(0))
|
||||
assert(brush_option.get_popup().is_item_disabled(1))
|
||||
assert(not grid_option.get_popup().is_item_disabled(0))
|
||||
|
|
@ -478,6 +540,26 @@ func _run() -> void:
|
|||
assert(color_button.focus_mode == Control.FOCUS_NONE)
|
||||
assert(not (color_buttons[&"chalk_white"] as Button).disabled)
|
||||
assert((color_buttons[&"ocean_teal"] as Button).disabled)
|
||||
var base_color_lock := (
|
||||
(color_buttons[&"chalk_white"] as Button).get_node(
|
||||
"UnlockStateIcon"
|
||||
) as TextureRect
|
||||
)
|
||||
var locked_color_lock := (
|
||||
(color_buttons[&"ocean_teal"] as Button).get_node(
|
||||
"UnlockStateIcon"
|
||||
) as TextureRect
|
||||
)
|
||||
assert(not base_color_lock.visible)
|
||||
assert(locked_color_lock.visible)
|
||||
assert(locked_color_lock.size == Vector2(18.0, 18.0))
|
||||
assert(is_equal_approx(locked_color_lock.modulate.a, 0.34))
|
||||
var popup_lock_icon := toolbar.get("_popup_lock_icon") as Texture2D
|
||||
assert(popup_lock_icon.get_width() == 40)
|
||||
assert(popup_lock_icon.get_height() == 40)
|
||||
assert(int(popup_lock_icon.get_meta(
|
||||
&"locked_content_icon_size", 0
|
||||
)) == 24)
|
||||
|
||||
for product_id: StringName in [
|
||||
&"marker_ocean_teal", &"brush_4x", &"grid_128x",
|
||||
|
|
@ -487,6 +569,19 @@ func _run() -> void:
|
|||
assert(not (color_buttons[&"ocean_teal"] as Button).disabled)
|
||||
assert(not brush_option.get_popup().is_item_disabled(3))
|
||||
assert(not grid_option.get_popup().is_item_disabled(3))
|
||||
assert(not locked_color_lock.visible)
|
||||
assert(str(brush_option.get_item_icon(3).get_meta(
|
||||
&"channel_mask_source", ""
|
||||
)).ends_with(expected_brush_icons[3]))
|
||||
assert(grid_option.get_item_icon(3).resource_path.ends_with(
|
||||
expected_grid_icons[3]
|
||||
))
|
||||
assert(is_equal_approx(
|
||||
brush_option.get_popup().get_item_icon_modulate(3).a, 1.0
|
||||
))
|
||||
assert(is_equal_approx(
|
||||
grid_option.get_popup().get_item_icon_modulate(3).a, 1.0
|
||||
))
|
||||
assert(service.set_color_id(&"ocean_teal"))
|
||||
assert(service.set_brush_size(4))
|
||||
assert(service.set_grid_size(128))
|
||||
|
|
|
|||
|
|
@ -42,11 +42,30 @@ func _run() -> void:
|
|||
stage.add_child(second_button)
|
||||
await process_frame
|
||||
|
||||
standard_button.grab_focus()
|
||||
await process_frame
|
||||
_expect(
|
||||
root.gui_get_focus_owner() == null,
|
||||
"a menu's programmatic first focus is visible before navigation input",
|
||||
)
|
||||
_expect(
|
||||
presentation.get("_neutral_focus_seed") == standard_button,
|
||||
"the neutral menu focus seed did not remember the first action",
|
||||
)
|
||||
var first_navigation := InputEventJoypadButton.new()
|
||||
first_navigation.button_index = JOY_BUTTON_DPAD_DOWN
|
||||
first_navigation.pressed = true
|
||||
presentation._input(first_navigation)
|
||||
await process_frame
|
||||
_expect(
|
||||
root.gui_get_focus_owner() == standard_button,
|
||||
"the first directional input did not activate the neutral focus seed",
|
||||
)
|
||||
|
||||
var controller_event := InputEventJoypadButton.new()
|
||||
controller_event.button_index = JOY_BUTTON_A
|
||||
controller_event.pressed = true
|
||||
presentation._input(controller_event)
|
||||
standard_button.grab_focus()
|
||||
await process_frame
|
||||
var focus_arrow := presentation.get("_focus_arrow") as TextureRect
|
||||
var focus_shadow := presentation.get("_focus_arrow_shadow") as TextureRect
|
||||
|
|
@ -111,8 +130,8 @@ func _run() -> void:
|
|||
root.gui_get_hovered_control() == standard_button,
|
||||
"the pointer did not reach the hover-suppression test button",
|
||||
)
|
||||
presentation._input(first_navigation)
|
||||
presentation._input(controller_event)
|
||||
standard_button.grab_focus()
|
||||
await process_frame
|
||||
_expect(
|
||||
standard_button.get_theme_stylebox("hover") == normal_style,
|
||||
|
|
@ -154,6 +173,10 @@ func _run() -> void:
|
|||
not focus_shadow.visible,
|
||||
"mouse motion leaves the controller focus shadow visible",
|
||||
)
|
||||
_expect(
|
||||
root.gui_get_focus_owner() == null,
|
||||
"mouse motion leaves a stale menu action focused",
|
||||
)
|
||||
_expect(
|
||||
standard_button.get_theme_stylebox("focus") == old_focus_style,
|
||||
"native theme overrides were not restored after controller use",
|
||||
|
|
@ -162,8 +185,6 @@ func _run() -> void:
|
|||
standard_button.get_theme_stylebox("hover") == old_hover_style,
|
||||
"mouse hover styling was not restored after controller use",
|
||||
)
|
||||
presentation._input(controller_event)
|
||||
|
||||
var item_list := ItemList.new()
|
||||
item_list.position = Vector2(80.0, 160.0)
|
||||
item_list.size = Vector2(240.0, 150.0)
|
||||
|
|
@ -175,6 +196,9 @@ func _run() -> void:
|
|||
item_list.select(0)
|
||||
item_list.grab_focus()
|
||||
await process_frame
|
||||
presentation._input(first_navigation)
|
||||
presentation._input(controller_event)
|
||||
await process_frame
|
||||
var first_item_arrow_y: float = focus_arrow.position.y
|
||||
item_list.select(2)
|
||||
await process_frame
|
||||
|
|
@ -329,6 +353,42 @@ func _run() -> void:
|
|||
not focus_arrow.visible,
|
||||
"focus arrow remains after its control becomes unfocusable",
|
||||
)
|
||||
var event_focused_button := Button.new()
|
||||
event_focused_button.text = "event focused"
|
||||
event_focused_button.position = Vector2(700.0, 360.0)
|
||||
event_focused_button.custom_minimum_size = Vector2(160.0, 50.0)
|
||||
stage.add_child(event_focused_button)
|
||||
await process_frame
|
||||
presentation._input(first_navigation)
|
||||
event_focused_button.grab_focus()
|
||||
await process_frame
|
||||
_expect(
|
||||
root.gui_get_focus_owner() == event_focused_button,
|
||||
(
|
||||
"a menu focus established by the current directional event was "
|
||||
+ "mistaken for an automatic default"
|
||||
),
|
||||
)
|
||||
|
||||
presentation.set_virtual_pointer_active(true)
|
||||
await process_frame
|
||||
_expect(
|
||||
not focus_arrow.visible,
|
||||
"focus arrow competes with active virtual-pointer presentation",
|
||||
)
|
||||
presentation._input(controller_event)
|
||||
await process_frame
|
||||
_expect(
|
||||
not focus_arrow.visible,
|
||||
"controller input stole presentation from the held virtual pointer",
|
||||
)
|
||||
presentation.set_virtual_pointer_active(false)
|
||||
presentation._input(controller_event)
|
||||
await process_frame
|
||||
_expect(
|
||||
focus_arrow.visible,
|
||||
"controller focus presentation did not resume after virtual-pointer use",
|
||||
)
|
||||
|
||||
stage.queue_free()
|
||||
if _failures.is_empty():
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ extends SceneTree
|
|||
const JoinGamePageScene = preload(
|
||||
"res://ui/network/join_game_page.tscn"
|
||||
)
|
||||
const TitleScreenScene = preload("res://ui/title_screen.tscn")
|
||||
const PauseMenuScene = preload("res://ui/pause_menu.tscn")
|
||||
const SettingsPanelScene = preload("res://ui/settings_panel.tscn")
|
||||
const BubbleConfirmationScene = preload(
|
||||
"res://ui/components/bubble_menu/bubble_confirmation_page.tscn"
|
||||
|
|
@ -40,6 +42,7 @@ func _initialize() -> void:
|
|||
|
||||
func _run() -> void:
|
||||
root.size = Vector2i(1280, 720)
|
||||
await _validate_primary_menu_navigation()
|
||||
await _validate_join_game_navigation()
|
||||
await _validate_data_settings_navigation()
|
||||
await _validate_settings_adjustment_navigation()
|
||||
|
|
@ -61,6 +64,49 @@ func _run() -> void:
|
|||
quit(1)
|
||||
|
||||
|
||||
func _validate_primary_menu_navigation() -> void:
|
||||
var title := TitleScreenScene.instantiate() as Control
|
||||
root.add_child(title)
|
||||
await process_frame
|
||||
(title.get_node("%ButtonCenter") as Control).show()
|
||||
(title.get_node("%BubbleField") as Control).show()
|
||||
title.call("_update_title_layout")
|
||||
title.call("_set_title_bubbles_interactive", true)
|
||||
var title_controls: Array[Control] = []
|
||||
for candidate: Variant in title.call("_get_title_buttons"):
|
||||
var control := candidate as Control
|
||||
if control is BaseButton:
|
||||
(control as BaseButton).disabled = false
|
||||
title_controls.append(control)
|
||||
_expect(
|
||||
title_controls.size() == 7,
|
||||
"Title menu does not expose all seven primary actions.",
|
||||
)
|
||||
_assert_directionally_reachable(title_controls.front(), title_controls)
|
||||
title.queue_free()
|
||||
await process_frame
|
||||
|
||||
var pause := PauseMenuScene.instantiate() as Control
|
||||
root.add_child(pause)
|
||||
pause.show()
|
||||
var root_page := pause.get_node("%RootPage") as Control
|
||||
root_page.call("show_page", false)
|
||||
for _frame: int in 2:
|
||||
await process_frame
|
||||
var pause_controls: Array[Control] = [
|
||||
pause.get_node("%ResumeButton") as Control,
|
||||
pause.get_node("%SaveButton") as Control,
|
||||
pause.get_node("%JoinGameButton") as Control,
|
||||
pause.get_node("%SettingsButton") as Control,
|
||||
pause.get_node("%ReturnToTitleButton") as Control,
|
||||
pause.get_node("%ResetProgressButton") as Control,
|
||||
pause.get_node("%QuitButton") as Control,
|
||||
]
|
||||
_assert_directionally_reachable(pause_controls.front(), pause_controls)
|
||||
pause.queue_free()
|
||||
await process_frame
|
||||
|
||||
|
||||
func _validate_join_game_navigation() -> void:
|
||||
var page := JoinGamePageScene.instantiate() as Control
|
||||
root.add_child(page)
|
||||
|
|
@ -541,12 +587,21 @@ func _validate_settings_presentation_requires_apply() -> void:
|
|||
_expect(
|
||||
not settings_manager.current_settings.chat_dock_right
|
||||
and not settings_manager.current_settings.chat_mobile_mode
|
||||
and settings_manager.current_settings.paint_dock_right,
|
||||
and settings_manager.current_settings.paint_dock_right
|
||||
and not settings_manager.current_settings.presentation_layout_customized,
|
||||
(
|
||||
"Navigating presentation choices changed saved docking settings "
|
||||
+ "before Apply."
|
||||
),
|
||||
)
|
||||
panel.call("_apply_settings")
|
||||
_expect(
|
||||
settings_manager.current_settings.chat_dock_right
|
||||
and settings_manager.current_settings.chat_mobile_mode
|
||||
and not settings_manager.current_settings.paint_dock_right
|
||||
and settings_manager.current_settings.presentation_layout_customized,
|
||||
"Applying deliberate presentation choices did not retain them.",
|
||||
)
|
||||
panel.close_panel(true)
|
||||
panel.queue_free()
|
||||
settings_manager.queue_free()
|
||||
|
|
@ -622,6 +677,7 @@ func _validate_profile_confirmation_focus() -> void:
|
|||
account_controls.append(item as Control)
|
||||
var preview := page.get("_preview") as Control
|
||||
var reset_view := page.get("_reset_view_button") as Button
|
||||
var reset_view_hint := page.get("_reset_view_controller_hint") as Label
|
||||
_expect(
|
||||
suggestion in account_controls,
|
||||
"Profile name-conflict choices are outside the account zone.",
|
||||
|
|
@ -638,6 +694,34 @@ func _validate_profile_confirmation_focus() -> void:
|
|||
reset_view.focus_mode == Control.FOCUS_NONE,
|
||||
"The profile reset-view button must not take controller focus.",
|
||||
)
|
||||
_expect(
|
||||
reset_view_hint != null
|
||||
and reset_view_hint.text == "Reset View: RS"
|
||||
and reset_view_hint.focus_mode == Control.FOCUS_NONE,
|
||||
"The profile preview does not present its right-stick reset hint.",
|
||||
)
|
||||
preview.set("_camera_yaw", 1.0)
|
||||
preview.set("_camera_pitch", 0.4)
|
||||
preview.set("_camera_distance", 2.5)
|
||||
var reset_view_event := InputEventJoypadButton.new()
|
||||
reset_view_event.button_index = JOY_BUTTON_RIGHT_STICK
|
||||
reset_view_event.pressed = true
|
||||
_expect(
|
||||
bool(page.call("handle_controller_input", reset_view_event)),
|
||||
"Profile customization did not consume right-stick reset.",
|
||||
)
|
||||
_expect(
|
||||
is_equal_approx(float(preview.get("_camera_yaw")), 0.0)
|
||||
and is_equal_approx(
|
||||
float(preview.get("_camera_pitch")),
|
||||
ProfilePreview.DEFAULT_CAMERA_PITCH,
|
||||
)
|
||||
and is_equal_approx(
|
||||
float(preview.get("_camera_distance")),
|
||||
ProfilePreview.DEFAULT_CAMERA_DISTANCE,
|
||||
),
|
||||
"Right-stick click did not restore the default profile preview view.",
|
||||
)
|
||||
page.call("_show_confirmation", "defaults")
|
||||
var confirmation := page.get("_discard_confirmation") as Control
|
||||
var confirm := page.get("_confirmation_confirm") as Button
|
||||
|
|
@ -1087,11 +1171,13 @@ func _validate_inventory_tab_zone_transitions() -> void:
|
|||
inventory_state.add_child(node)
|
||||
bag.setup(ItemCatalogResource)
|
||||
layout.setup(bag, catches, ItemCatalogResource, storage_capacity)
|
||||
assert(layout.restore_backpack_level(1))
|
||||
bag.set_inventory_layout(layout)
|
||||
catches.set_inventory_layout(layout)
|
||||
hotbar.setup(bag, ItemCatalogResource, catches, layout)
|
||||
assert(bag.add_item(&"basic_fishing_rod", 1))
|
||||
assert(bag.add_item(&"coffee", 1))
|
||||
assert(bag.add_item(&"worms", 1))
|
||||
assert(layout.move_entry(
|
||||
PlayerInventoryLayout.EntryKind.ITEM,
|
||||
&"basic_fishing_rod",
|
||||
|
|
@ -1415,6 +1501,47 @@ func _validate_inventory_tab_zone_transitions() -> void:
|
|||
)
|
||||
for _frame: int in 2:
|
||||
await process_frame
|
||||
|
||||
menu.call("_show_section_immediate", PlayerMenuType.Section.TACKLE_BOX)
|
||||
menu.call("_set_content_interactive", true)
|
||||
menu.set(
|
||||
"_controller_ownership",
|
||||
PlayerMenuType.ControllerOwnership.ITEM_LIST,
|
||||
)
|
||||
menu.call("_apply_inventory_controller_zone_focus_modes")
|
||||
menu.call("_configure_tackle_item_focus")
|
||||
for _frame: int in 2:
|
||||
await process_frame
|
||||
var tackle_buttons: Dictionary = menu.get("_tackle_item_buttons")
|
||||
var worms_button := tackle_buttons.get(&"worms") as Button
|
||||
_expect(worms_button != null, "Tackle test could not find unlocked worms.")
|
||||
if worms_button != null:
|
||||
worms_button.grab_focus()
|
||||
menu.call("_handle_controller_ownership_input", accept)
|
||||
menu.call("_handle_controller_ownership_input", accept_release)
|
||||
_expect(
|
||||
StringName(menu.get("_selected_tackle_item_id")).is_empty(),
|
||||
"Controller A still activates a bait or lure inventory action.",
|
||||
)
|
||||
_expect(
|
||||
not (menu.get_node("%TackleDetailPanel") as Control).visible,
|
||||
"Controller A opened the tackle notepad reserved for Y.",
|
||||
)
|
||||
_expect(
|
||||
bool(menu.call(
|
||||
"_handle_controller_ownership_input", context_press
|
||||
)),
|
||||
"Controller Y did not open the bait/lure equip notepad.",
|
||||
)
|
||||
_expect(
|
||||
menu.get("_controller_ownership")
|
||||
== PlayerMenuType.ControllerOwnership.NOTEPAD_ACTIONS,
|
||||
"Tackle notepad did not take controller ownership after Y.",
|
||||
)
|
||||
_expect(
|
||||
(menu.get_node("%TackleDetailPanel") as Control).visible,
|
||||
"Controller Y left the bait/lure equip notepad hidden.",
|
||||
)
|
||||
menu.queue_free()
|
||||
inventory_state.queue_free()
|
||||
await process_frame
|
||||
|
|
|
|||
|
|
@ -215,6 +215,13 @@ func _validate_settings_navigation_contract() -> void:
|
|||
settings.crisp_reset_focus_requested.connect(
|
||||
reset_overlay.focus_reset_button
|
||||
)
|
||||
var reset_cursor_presentation := reset_overlay.get_node(
|
||||
"ControllerFocusPresentation"
|
||||
) as ControllerFocusPresentation
|
||||
var controller_right := InputEventJoypadButton.new()
|
||||
controller_right.button_index = JOY_BUTTON_DPAD_RIGHT
|
||||
controller_right.pressed = true
|
||||
reset_cursor_presentation._input(controller_right)
|
||||
var focus_reset_event := InputEventAction.new()
|
||||
focus_reset_event.action = &"ui_right"
|
||||
focus_reset_event.pressed = true
|
||||
|
|
@ -224,6 +231,9 @@ func _validate_settings_navigation_contract() -> void:
|
|||
root.gui_get_focus_owner()
|
||||
== reset_overlay.get_node("%ResetPixelationButton")
|
||||
)
|
||||
assert(
|
||||
(reset_cursor_presentation.get("_focus_arrow") as TextureRect).visible
|
||||
)
|
||||
reset_overlay.return_to_settings_requested.connect(
|
||||
settings.focus_back_button
|
||||
)
|
||||
|
|
|
|||
|
|
@ -806,15 +806,15 @@ func _test_fishing_shop_sale_ui(
|
|||
assert(bait_receipt.contains(" spent on "))
|
||||
assert(bait_receipt.ends_with(" worms"))
|
||||
assert(snails_button.get_node_or_null("SupplyQuantityBadge") == null)
|
||||
assert(worms_button.get_node_or_null("UnlockStateIcon") == null)
|
||||
assert(worms_button.get_node_or_null("UnlockStateBadge") == null)
|
||||
var snails_lock_icon := snails_button.get_node(
|
||||
"UnlockStateIcon"
|
||||
"UnlockStateBadge/UnlockStateIcon"
|
||||
) as TextureRect
|
||||
assert(not bool(snails_lock_icon.get_meta(&"unlocked")))
|
||||
assert(snails_lock_icon.texture.resource_path.ends_with(
|
||||
"/lock_light.png"
|
||||
))
|
||||
assert(is_equal_approx(snails_lock_icon.modulate.a, 0.75))
|
||||
assert(is_equal_approx(snails_lock_icon.modulate.a, 0.88))
|
||||
await _activate_pointer_control(equipment_tab, ui_viewport)
|
||||
await process_frame
|
||||
var equipment_sections: Array[String] = []
|
||||
|
|
@ -836,7 +836,7 @@ func _test_fishing_shop_sale_ui(
|
|||
assert(basic_rod_button != null)
|
||||
assert(basic_rod_button.custom_minimum_size == Vector2(144.0, 144.0))
|
||||
assert(basic_rod_button.icon != null and basic_rod_button.disabled)
|
||||
assert(basic_rod_button.get_node_or_null("UnlockStateIcon") == null)
|
||||
assert(basic_rod_button.get_node_or_null("UnlockStateBadge") == null)
|
||||
assert(rod_cards.find_child("Rod_aurora_rod", true, false) == null)
|
||||
await _activate_pointer_control(art_supplies_tab, ui_viewport)
|
||||
await process_frame
|
||||
|
|
@ -886,8 +886,13 @@ func _test_fishing_shop_sale_ui(
|
|||
var product_unlocked: bool = (
|
||||
player.art_unlocks.owns_product(product_id)
|
||||
)
|
||||
var state_icon := upgrade_button.get_node_or_null(
|
||||
"UnlockStateIcon"
|
||||
var state_badge := upgrade_button.get_node_or_null(
|
||||
"UnlockStateBadge"
|
||||
) as Panel
|
||||
var state_icon := (
|
||||
state_badge.get_node("UnlockStateIcon") as TextureRect
|
||||
if state_badge != null
|
||||
else null
|
||||
) as TextureRect
|
||||
assert((state_icon == null) == product_unlocked)
|
||||
if state_icon != null:
|
||||
|
|
|
|||
|
|
@ -20,20 +20,25 @@ func _initialize() -> void:
|
|||
shop.call(
|
||||
"_add_unlock_state_icon", locked_button, false, Vector2(72.0, 72.0)
|
||||
)
|
||||
var locked_icon := locked_button.get_node(
|
||||
var locked_badge := locked_button.get_node(
|
||||
"UnlockStateBadge"
|
||||
) as Panel
|
||||
var locked_icon := locked_badge.get_node(
|
||||
"UnlockStateIcon"
|
||||
) as TextureRect
|
||||
assert(locked_badge.position == Vector2(4.0, 4.0))
|
||||
assert(locked_badge.size == Vector2(30.0, 30.0))
|
||||
assert(locked_icon.texture.resource_path.ends_with("/lock_light.png"))
|
||||
assert(locked_icon.size == Vector2(48.0, 48.0))
|
||||
assert(locked_icon.position == Vector2(12.0, 6.0))
|
||||
assert(is_equal_approx(locked_icon.modulate.a, 0.75))
|
||||
assert(locked_icon.size == Vector2(18.0, 18.0))
|
||||
assert(locked_icon.position == Vector2(6.0, 6.0))
|
||||
assert(is_equal_approx(locked_icon.modulate.a, 0.88))
|
||||
assert(not bool(locked_icon.get_meta(&"unlocked")))
|
||||
locked_button.free()
|
||||
var unlocked_button := Button.new()
|
||||
shop.call(
|
||||
"_add_unlock_state_icon", unlocked_button, true, Vector2(72.0, 72.0)
|
||||
)
|
||||
assert(unlocked_button.get_node_or_null("UnlockStateIcon") == null)
|
||||
assert(unlocked_button.get_node_or_null("UnlockStateBadge") == null)
|
||||
unlocked_button.free()
|
||||
shop.free()
|
||||
|
||||
|
|
@ -54,13 +59,14 @@ func _initialize() -> void:
|
|||
)
|
||||
assert(crab_net != null)
|
||||
assert(crab_net.icon != null)
|
||||
assert(crab_net.icon.resource_path.ends_with("/equipment/temp_net.png"))
|
||||
assert(crab_net.icon.resource_path.ends_with("/equipment/net.png"))
|
||||
var shovel: ItemDataType = ItemCatalogResource.get_available_item_by_id(
|
||||
&"standard_shovel"
|
||||
)
|
||||
assert(shovel != null)
|
||||
assert(shovel.category == ItemDataType.Category.TOOL)
|
||||
assert(shovel.icon != null)
|
||||
assert(shovel.icon.resource_path.ends_with("/equipment/shovel.png"))
|
||||
assert(shovel.equippable)
|
||||
assert(shovel.hotbar_allowed)
|
||||
assert(FishingShopStockType.get_price(&"standard_shovel") == 75)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue