Revise Art Kit workflow and refresh fox patterns
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.5 KiB |
BIN
items/icons/art/art_kit_grid_finish_light.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
40
items/icons/art/art_kit_grid_finish_light.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dm24dy3ebvqmv"
|
||||
path="res://.godot/imported/art_kit_grid_finish_light.png-fe16d574640fb174cb8b6ff3cfb95e5e.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://items/icons/art/art_kit_grid_finish_light.png"
|
||||
dest_files=["res://.godot/imported/art_kit_grid_finish_light.png-fe16d574640fb174cb8b6ff3cfb95e5e.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
items/icons/art/art_kit_grid_hidden_light.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
40
items/icons/art/art_kit_grid_hidden_light.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cv6yicrysb0vs"
|
||||
path="res://.godot/imported/art_kit_grid_hidden_light.png-e92350d8a3e2c3e3bf286658f1ae0c41.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://items/icons/art/art_kit_grid_hidden_light.png"
|
||||
dest_files=["res://.godot/imported/art_kit_grid_hidden_light.png-e92350d8a3e2c3e3bf286658f1ae0c41.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
items/icons/art/art_kit_grid_light.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
40
items/icons/art/art_kit_grid_light.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dh2tu3ptqe6f7"
|
||||
path="res://.godot/imported/art_kit_grid_light.png-d445eba68746a34d73bbf1744fe56777.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://items/icons/art/art_kit_grid_light.png"
|
||||
dest_files=["res://.godot/imported/art_kit_grid_light.png-d445eba68746a34d73bbf1744fe56777.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
items/icons/art/art_kit_grid_restore_light.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
40
items/icons/art/art_kit_grid_restore_light.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ckxdpi5sqerao"
|
||||
path="res://.godot/imported/art_kit_grid_restore_light.png-d2f2458a90dabc79430d7ff0e0e3385d.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://items/icons/art/art_kit_grid_restore_light.png"
|
||||
dest_files=["res://.godot/imported/art_kit_grid_restore_light.png-d2f2458a90dabc79430d7ff0e0e3385d.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
|
Before Width: | Height: | Size: 945 B After Width: | Height: | Size: 945 B |
|
|
@ -554,6 +554,7 @@ func _initialize_application(dedicated: bool) -> void:
|
|||
_player,
|
||||
_surface_drawings_root,
|
||||
_player.bag,
|
||||
_player.hotbar,
|
||||
_player.art_unlocks,
|
||||
)
|
||||
_network_player_list.set_surface_drawing_service(
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ var _spawn_service: PlayerSpawnService
|
|||
var _relationships: PlayerRelationshipStore
|
||||
var _local_player: Player
|
||||
var _bag: PlayerBag
|
||||
var _hotbar: PlayerHotbar
|
||||
var _art_unlocks: PlayerArtUnlocks
|
||||
var _drawing_root: Node3D
|
||||
var _canvas_states: Dictionary[String, Dictionary] = {}
|
||||
|
|
@ -87,6 +88,7 @@ func setup(
|
|||
local_player: Player,
|
||||
drawing_root: Node3D,
|
||||
bag: PlayerBag,
|
||||
hotbar: PlayerHotbar,
|
||||
art_unlocks: PlayerArtUnlocks,
|
||||
) -> void:
|
||||
_session = session
|
||||
|
|
@ -95,6 +97,7 @@ func setup(
|
|||
_local_player = local_player
|
||||
_drawing_root = drawing_root
|
||||
_bag = bag
|
||||
_hotbar = hotbar
|
||||
_art_unlocks = art_unlocks
|
||||
_refresh_local_unlocks()
|
||||
if _session != null:
|
||||
|
|
@ -123,20 +126,6 @@ func handle_input(
|
|||
can_open: bool,
|
||||
pointer_screen_position: Vector2 = INVALID_POINTER_SCREEN_POSITION,
|
||||
) -> bool:
|
||||
if event is InputEventKey:
|
||||
var key_event := event as InputEventKey
|
||||
if (
|
||||
key_event.pressed
|
||||
and not key_event.echo
|
||||
and key_event.physical_keycode == KEY_P
|
||||
):
|
||||
if _active:
|
||||
deactivate()
|
||||
return true
|
||||
if can_open and can_activate():
|
||||
activate(pointer_screen_position)
|
||||
return true
|
||||
return false
|
||||
if not _active:
|
||||
return false
|
||||
if not can_open:
|
||||
|
|
@ -149,8 +138,7 @@ func handle_input(
|
|||
if _placing_grid:
|
||||
_set_placement_mode(false)
|
||||
return true
|
||||
deactivate()
|
||||
return true
|
||||
return false
|
||||
if event is InputEventKey:
|
||||
var key_event := event as InputEventKey
|
||||
if not key_event.pressed or key_event.echo:
|
||||
|
|
@ -172,28 +160,19 @@ func handle_input(
|
|||
return true
|
||||
if event is InputEventMouseButton:
|
||||
var mouse_event := event as InputEventMouseButton
|
||||
# Ordinary wheel input always belongs to Hotbar selection. Brush size is
|
||||
# selected explicitly in the Art Kit toolbar.
|
||||
if mouse_event.button_index in [
|
||||
MOUSE_BUTTON_WHEEL_UP,
|
||||
MOUSE_BUTTON_WHEEL_DOWN,
|
||||
]:
|
||||
return false
|
||||
_set_pointer_from_input(
|
||||
mouse_event.position,
|
||||
pointer_screen_position,
|
||||
)
|
||||
_update_aim()
|
||||
if (
|
||||
mouse_event.shift_pressed
|
||||
and mouse_event.button_index in [
|
||||
MOUSE_BUTTON_WHEEL_UP,
|
||||
MOUSE_BUTTON_WHEEL_DOWN,
|
||||
]
|
||||
):
|
||||
return false
|
||||
match mouse_event.button_index:
|
||||
MOUSE_BUTTON_WHEEL_UP:
|
||||
if mouse_event.pressed and not _placing_grid:
|
||||
_set_brush_size(_brush_size + 1)
|
||||
return true
|
||||
MOUSE_BUTTON_WHEEL_DOWN:
|
||||
if mouse_event.pressed and not _placing_grid:
|
||||
_set_brush_size(_brush_size - 1)
|
||||
return true
|
||||
MOUSE_BUTTON_LEFT:
|
||||
if _placing_grid:
|
||||
if mouse_event.pressed:
|
||||
|
|
@ -241,7 +220,7 @@ func activate(
|
|||
if _active or not can_activate():
|
||||
return
|
||||
_active = true
|
||||
_placing_grid = true
|
||||
_placing_grid = false
|
||||
_eraser_mode = false
|
||||
_clear_armed_guide_action(false)
|
||||
_refresh_local_unlocks()
|
||||
|
|
@ -257,9 +236,7 @@ func activate(
|
|||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
_update_aim()
|
||||
_refresh_stencil_visibility()
|
||||
_emit_hud_state(
|
||||
"click to place a shared grid"
|
||||
)
|
||||
_emit_hud_state("marker selected")
|
||||
|
||||
|
||||
func deactivate() -> void:
|
||||
|
|
@ -288,7 +265,11 @@ func is_placement_mode() -> bool:
|
|||
|
||||
|
||||
func can_activate() -> bool:
|
||||
return _drawing_available() and _owns_art_kit()
|
||||
return (
|
||||
_drawing_available()
|
||||
and _owns_art_kit()
|
||||
and _art_kit_is_selected()
|
||||
)
|
||||
|
||||
|
||||
func set_placement_mode(enabled: bool) -> void:
|
||||
|
|
@ -415,6 +396,15 @@ func _owns_art_kit() -> bool:
|
|||
return _bag != null and _bag.owns_item(ArtShopStockType.ART_KIT_ITEM_ID)
|
||||
|
||||
|
||||
func _art_kit_is_selected() -> bool:
|
||||
return (
|
||||
_hotbar != null
|
||||
and _hotbar.get_selected_assignment_kind()
|
||||
== PlayerHotbar.AssignmentKind.ITEM
|
||||
and _hotbar.get_selected_item_id() == ArtShopStockType.ART_KIT_ITEM_ID
|
||||
)
|
||||
|
||||
|
||||
func _local_entitlement() -> Dictionary:
|
||||
return {
|
||||
"has_kit": _owns_art_kit(),
|
||||
|
|
@ -550,8 +540,7 @@ func request_canvas_at_surface(
|
|||
tangent: Vector3,
|
||||
) -> bool:
|
||||
if (
|
||||
not _drawing_available()
|
||||
or not _owns_art_kit()
|
||||
not can_activate()
|
||||
or _art_unlocks == null
|
||||
or not _art_unlocks.is_grid_size_unlocked(_grid_size)
|
||||
or normal.is_zero_approx()
|
||||
|
|
@ -581,8 +570,7 @@ func request_cell_edits(
|
|||
stroke_id: String = "",
|
||||
) -> bool:
|
||||
if (
|
||||
not _drawing_available()
|
||||
or not _owns_art_kit()
|
||||
not can_activate()
|
||||
or canvas_id.is_empty()
|
||||
or edits.is_empty()
|
||||
):
|
||||
|
|
@ -613,7 +601,7 @@ func request_guide_visibility(
|
|||
should_be_visible: bool,
|
||||
should_finalize: bool = false,
|
||||
) -> bool:
|
||||
if not _drawing_available() or not _owns_art_kit() or canvas_id.is_empty():
|
||||
if not can_activate() or canvas_id.is_empty():
|
||||
return false
|
||||
var data: Dictionary = {
|
||||
"request_id": _new_request_id("guide"),
|
||||
|
|
@ -633,8 +621,7 @@ func request_guide_visibility(
|
|||
|
||||
func request_undo_last_stroke() -> bool:
|
||||
if (
|
||||
not _drawing_available()
|
||||
or not _owns_art_kit()
|
||||
not can_activate()
|
||||
or _last_local_stroke_id.is_empty()
|
||||
):
|
||||
_emit_hud_state("nothing to undo")
|
||||
|
|
@ -698,6 +685,9 @@ func get_canvas_state(canvas_id: String) -> Dictionary:
|
|||
func _process(_delta: float) -> void:
|
||||
if not _active:
|
||||
return
|
||||
if not can_activate():
|
||||
deactivate()
|
||||
return
|
||||
_update_aim()
|
||||
if _placing_grid:
|
||||
return
|
||||
|
|
@ -2171,7 +2161,7 @@ func _on_peer_removed(peer_id: int) -> void:
|
|||
|
||||
|
||||
func _on_local_art_entitlement_changed() -> void:
|
||||
if _active and not _owns_art_kit():
|
||||
if _active and not can_activate():
|
||||
deactivate()
|
||||
_publish_local_entitlement()
|
||||
|
||||
|
|
|
|||
|
|
@ -259,8 +259,7 @@ func _run() -> void:
|
|||
assert(game_ui.is_gameplay_hud_hidden())
|
||||
assert(player_menu.visible)
|
||||
assert(root.gui_get_focus_owner() is not LineEdit)
|
||||
player_menu.close_menu()
|
||||
for _frame: int in 12:
|
||||
player_menu.close_menu(PlayerMenu.CloseReason.SESSION_END)
|
||||
await process_frame
|
||||
game_ui.call("_on_quick_action_selected", &"hud")
|
||||
await process_frame
|
||||
|
|
@ -269,14 +268,17 @@ func _run() -> void:
|
|||
assert(not service.can_activate())
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
assert(player.bag.add_item(ArtShopStock.ART_KIT_ITEM_ID, 1))
|
||||
assert(service.can_activate())
|
||||
|
||||
player.hotbar.select_slot(1)
|
||||
assert(player.hotbar.assign_item(0, ArtShopStock.ART_KIT_ITEM_ID))
|
||||
assert(not service.can_activate())
|
||||
var paint_key := InputEventKey.new()
|
||||
paint_key.physical_keycode = KEY_P
|
||||
paint_key.pressed = true
|
||||
assert(service.handle_input(paint_key, true))
|
||||
assert(not service.handle_input(paint_key, true))
|
||||
assert(not service.is_active())
|
||||
player.hotbar.select_slot(0)
|
||||
await process_frame
|
||||
assert(service.is_active() and service.is_placement_mode())
|
||||
assert(service.is_active() and not service.is_placement_mode())
|
||||
assert(toolbar.visible)
|
||||
var ui_root := game_ui.get_node("%UIRoot") as Control
|
||||
assert(toolbar.get_parent() == ui_root)
|
||||
|
|
@ -291,6 +293,8 @@ func _run() -> void:
|
|||
assert(toolbar.get_global_rect().end.y <= 720.0)
|
||||
var top_panel := toolbar.get_node("%TopPanel") as PanelContainer
|
||||
var color_panel := toolbar.get_node("%ColorPanel") as PanelContainer
|
||||
assert(is_equal_approx(toolbar.size.x, SurfaceDrawingToolbar.TOOLBAR_WIDTH))
|
||||
assert(is_equal_approx(top_panel.size.x, SurfaceDrawingToolbar.TOOLBAR_WIDTH))
|
||||
assert(top_panel.position.is_equal_approx(Vector2.ZERO))
|
||||
assert(color_panel.position.x > 0.0)
|
||||
assert(is_equal_approx(color_panel.get_rect().end.x, top_panel.get_rect().end.x))
|
||||
|
|
@ -315,7 +319,6 @@ func _run() -> void:
|
|||
var hide_button := toolbar.get_node("%HideGuideButton") as Button
|
||||
var restore_button := toolbar.get_node("%RestoreGuideButton") as Button
|
||||
var finalize_button := toolbar.get_node("%FinalizeGuideButton") as Button
|
||||
var close_button := toolbar.get_node("%CloseButton") as Button
|
||||
assert(
|
||||
mode_button != null
|
||||
and eraser_button != null
|
||||
|
|
@ -323,16 +326,30 @@ func _run() -> void:
|
|||
and hide_button != null
|
||||
and restore_button != null
|
||||
and finalize_button != null
|
||||
and close_button != null
|
||||
)
|
||||
assert(eraser_button.text.is_empty())
|
||||
assert(eraser_button.icon != null)
|
||||
assert(toolbar.get_node_or_null("%CloseButton") == null)
|
||||
var expected_toolbar_icons: Dictionary[Button, String] = {
|
||||
mode_button: "/art/art_kit_marker.png",
|
||||
eraser_button: "/art/art_kit_eraser.png",
|
||||
hide_button: "/art/art_kit_grid_hidden_light.png",
|
||||
restore_button: "/art/art_kit_grid_restore_light.png",
|
||||
finalize_button: "/art/art_kit_grid_finish_light.png",
|
||||
}
|
||||
for icon_button: Button in expected_toolbar_icons:
|
||||
assert(icon_button.text.is_empty())
|
||||
assert(icon_button.icon != null)
|
||||
assert(
|
||||
eraser_button.icon.resource_path.ends_with(
|
||||
"/art/art_kit_eraser.png"
|
||||
icon_button.icon.resource_path.ends_with(
|
||||
expected_toolbar_icons[icon_button]
|
||||
)
|
||||
)
|
||||
for icon_button: Button in [eraser_button, undo_button]:
|
||||
for icon_button: Button in [
|
||||
eraser_button,
|
||||
undo_button,
|
||||
hide_button,
|
||||
restore_button,
|
||||
finalize_button,
|
||||
]:
|
||||
assert(icon_button.custom_minimum_size == Vector2(48, 44))
|
||||
assert(icon_button.get_theme_constant("icon_max_width") == 40)
|
||||
var icon_style := (
|
||||
|
|
@ -340,6 +357,9 @@ func _run() -> void:
|
|||
)
|
||||
assert(is_equal_approx(icon_style.content_margin_left, 4.0))
|
||||
assert(is_equal_approx(icon_style.content_margin_top, 2.0))
|
||||
assert(mode_button.custom_minimum_size == Vector2(48, 48))
|
||||
assert(mode_button.get_theme_constant("icon_max_width") == 40)
|
||||
assert(mode_button.get_index() > finalize_button.get_index())
|
||||
assert(hide_button.button_group != null)
|
||||
assert(hide_button.button_group == restore_button.button_group)
|
||||
assert(hide_button.button_group == finalize_button.button_group)
|
||||
|
|
@ -371,7 +391,12 @@ func _run() -> void:
|
|||
assert(service.get_grid_size() == 128)
|
||||
|
||||
mode_button.pressed.emit()
|
||||
assert(not service.is_placement_mode())
|
||||
assert(service.is_placement_mode())
|
||||
assert(
|
||||
mode_button.icon.resource_path.ends_with(
|
||||
"/art/art_kit_grid_light.png"
|
||||
)
|
||||
)
|
||||
eraser_button.pressed.emit()
|
||||
assert(service.is_eraser_mode())
|
||||
assert(eraser_button.button_pressed)
|
||||
|
|
@ -427,18 +452,8 @@ func _run() -> void:
|
|||
assert(not service.is_eraser_mode())
|
||||
undo_button.pressed.emit()
|
||||
assert(service.is_active())
|
||||
close_button.pressed.emit()
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
|
||||
assert(service.handle_input(paint_key, true))
|
||||
await process_frame
|
||||
assert(not service.handle_input(paint_key, true))
|
||||
assert(service.is_active() and toolbar.visible)
|
||||
|
||||
assert(service.handle_input(paint_key, true))
|
||||
await process_frame
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
assert(player.hotbar.assign_item(0, ArtShopStock.ART_KIT_ITEM_ID))
|
||||
player.hotbar.select_slot(0)
|
||||
var fishing_spot := main.get_node("%FishingSpot") as FishingSpot
|
||||
await process_frame
|
||||
var held_art_kit_display := player.get("_held_art_kit_display") as Node3D
|
||||
|
|
@ -472,12 +487,36 @@ func _run() -> void:
|
|||
assert(service.get_grid_size() == 128)
|
||||
assert(service.handle_input(world_click, true))
|
||||
assert(service.is_active() and toolbar.visible)
|
||||
player.hotbar.select_slot(1)
|
||||
var hotbar_ui := game_ui.get_node("%Hotbar") as HotbarUI
|
||||
var wheel_down := InputEventMouseButton.new()
|
||||
wheel_down.button_index = MOUSE_BUTTON_WHEEL_DOWN
|
||||
wheel_down.pressed = true
|
||||
assert(not service.handle_input(wheel_down, true))
|
||||
hotbar_ui._unhandled_input(wheel_down)
|
||||
await process_frame
|
||||
assert(player.hotbar.get_selected_slot() == 1)
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
assert(service.handle_input(paint_key, true))
|
||||
|
||||
var number_one := InputEventKey.new()
|
||||
number_one.physical_keycode = KEY_1
|
||||
number_one.pressed = true
|
||||
assert(not service.handle_input(number_one, true))
|
||||
hotbar_ui._unhandled_input(number_one)
|
||||
await process_frame
|
||||
assert(service.is_active() and toolbar.visible)
|
||||
assert(player.hotbar.get_selected_slot() == 0)
|
||||
var number_two := InputEventKey.new()
|
||||
number_two.physical_keycode = KEY_2
|
||||
number_two.pressed = true
|
||||
assert(not service.handle_input(number_two, true))
|
||||
hotbar_ui._unhandled_input(number_two)
|
||||
await process_frame
|
||||
assert(player.hotbar.get_selected_slot() == 1)
|
||||
assert(not service.is_active() and not toolbar.visible)
|
||||
game_ui.call("_on_quick_action_selected", &"paint")
|
||||
await process_frame
|
||||
assert(player.hotbar.get_selected_slot() == 0)
|
||||
assert(service.is_active() and toolbar.visible)
|
||||
|
||||
print("Art tools validation: PASS")
|
||||
var session := main.get_node("%NetworkSession") as NetworkSession
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ func _run_host() -> void:
|
|||
await physics_frame
|
||||
var player := main.get("_player") as Player
|
||||
assert(player.bag.add_item(&"art_kit", 1))
|
||||
assert(player.hotbar.assign_item(0, &"art_kit"))
|
||||
assert(player.hotbar.select_slot(0))
|
||||
assert(player.art_unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK))
|
||||
|
||||
var service := main.get_node(
|
||||
|
|
@ -140,6 +142,8 @@ func _run_client() -> void:
|
|||
))
|
||||
var player := main.get("_player") as Player
|
||||
assert(player.bag.add_item(&"art_kit", 1))
|
||||
assert(player.hotbar.assign_item(0, &"art_kit"))
|
||||
assert(player.hotbar.select_slot(0))
|
||||
assert(player.art_unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK))
|
||||
|
||||
var service := main.get_node(
|
||||
|
|
|
|||
|
|
@ -29,12 +29,15 @@ func _run() -> void:
|
|||
|
||||
var player := main.get("_player") as Player
|
||||
assert(player.bag.add_item(&"art_kit", 1))
|
||||
assert(player.hotbar.assign_item(0, &"art_kit"))
|
||||
assert(player.hotbar.select_slot(0))
|
||||
assert(player.art_unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK))
|
||||
var service := main.get_node(
|
||||
"%NetworkSurfaceDrawingService"
|
||||
) as NetworkSurfaceDrawingService
|
||||
assert(service != null)
|
||||
assert(session.supports_server_capability(SurfaceDrawingProtocol.CAPABILITY))
|
||||
service.deactivate()
|
||||
_validate_marker_controls(service, player)
|
||||
var query := PhysicsRayQueryParameters3D.create(
|
||||
player.global_position + Vector3.UP * 3.0,
|
||||
|
|
@ -124,7 +127,7 @@ func _validate_marker_controls(
|
|||
var activation_pointer := Vector2(824.0, 318.0)
|
||||
service.activate(activation_pointer)
|
||||
assert(service.is_active())
|
||||
assert(service.is_placement_mode())
|
||||
assert(not service.is_placement_mode())
|
||||
assert(service.get_pointer_screen_position() == activation_pointer)
|
||||
if DisplayServer.get_name() != "headless":
|
||||
assert(Input.mouse_mode == Input.MOUSE_MODE_VISIBLE)
|
||||
|
|
@ -133,7 +136,7 @@ func _validate_marker_controls(
|
|||
placement_key.physical_keycode = KEY_R
|
||||
placement_key.pressed = true
|
||||
assert(service.handle_input(placement_key, true))
|
||||
assert(not service.is_placement_mode())
|
||||
assert(service.is_placement_mode())
|
||||
|
||||
var pointer_before: Vector2 = service.get_pointer_screen_position()
|
||||
var pointer_motion := InputEventMouseMotion.new()
|
||||
|
|
@ -171,6 +174,6 @@ func _validate_marker_controls(
|
|||
assert(not service.handle_input(camera_release, true))
|
||||
|
||||
assert(service.handle_input(placement_key, true))
|
||||
assert(service.is_placement_mode())
|
||||
assert(not service.is_placement_mode())
|
||||
service.deactivate()
|
||||
assert(Input.mouse_mode == prior_mouse_mode)
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ const SHOP_ANIMALESE_VOICE_ID: String = "natural"
|
|||
const SHOP_ANIMALESE_BASE_PITCH: float = 1.08
|
||||
const SHOP_SPEECH_CHARACTERS_PER_SECOND: float = 28.0
|
||||
const SHOP_NPC_SPEECH_COOLDOWN_MILLISECONDS: int = 5000
|
||||
const ART_KIT_ITEM_ID: StringName = &"art_kit"
|
||||
|
||||
|
||||
@onready var _canonical_stage: Control = %CanonicalStage
|
||||
|
|
@ -164,6 +165,7 @@ var _network_chat_service: NetworkChatService
|
|||
var _network_profile: NetworkProfilePreferences
|
||||
var _spawn_service: PlayerSpawnService
|
||||
var _bag: PlayerBagType
|
||||
var _hotbar: PlayerHotbarType
|
||||
var _item_catalog: ItemCatalogType
|
||||
var _player_menu_open: bool = false
|
||||
var _gameplay_ui_enabled: bool = false
|
||||
|
|
@ -177,6 +179,7 @@ var _item_effects: PlayerItemEffectsType
|
|||
var _main_shop_buyer: FishBuyerProfileType
|
||||
var _shop_interaction: ShopInteractionType
|
||||
var _surface_drawing: NetworkSurfaceDrawingService
|
||||
var _surface_drawing_hotbar_selected: bool = false
|
||||
var _experience: PlayerExperienceType
|
||||
var _experience_award_queue: Array[Dictionary] = []
|
||||
var _experience_animation_active: bool = false
|
||||
|
|
@ -293,6 +296,7 @@ func setup(
|
|||
_network_profile = network_profile
|
||||
_spawn_service = spawn_service
|
||||
_bag = bag
|
||||
_hotbar = hotbar
|
||||
_item_catalog = item_catalog
|
||||
_settings_manager = settings_manager
|
||||
_fishing_spot = fishing_spot
|
||||
|
|
@ -448,16 +452,7 @@ func _input(event: InputEvent) -> void:
|
|||
)
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
var drawing_can_open: bool = (
|
||||
_gameplay_ui_enabled
|
||||
and not _system_menu_open
|
||||
and not _player_menu_open
|
||||
and not _shop_open
|
||||
and not _chat_input_open
|
||||
and not _showcase_active
|
||||
and _fishing_spot != null
|
||||
and _fishing_spot.can_use_surface_drawing()
|
||||
)
|
||||
var drawing_can_open: bool = _can_surface_drawing_be_active()
|
||||
if (
|
||||
_surface_drawing != null
|
||||
and _surface_drawing.handle_input(
|
||||
|
|
@ -630,7 +625,7 @@ func _on_quick_action_selected(action_id: StringName) -> void:
|
|||
&"online":
|
||||
_player_menu.open_section(PlayerMenuType.Section.PLAYERS)
|
||||
&"paint":
|
||||
_toggle_surface_drawing()
|
||||
_select_art_kit_hotbar_slot()
|
||||
&"chat":
|
||||
_chat_ui.open_chat()
|
||||
&"freecam":
|
||||
|
|
@ -1121,25 +1116,46 @@ static func get_virtual_mouse_window_bounds(window_size: Vector2) -> Rect2:
|
|||
return Rect2(cursor_margin, bounds_size)
|
||||
|
||||
|
||||
func _toggle_surface_drawing() -> void:
|
||||
if _surface_drawing == null:
|
||||
func _select_art_kit_hotbar_slot() -> void:
|
||||
if _hotbar == null:
|
||||
return
|
||||
for slot_index: int in range(PlayerHotbarType.SLOT_COUNT):
|
||||
if _hotbar.get_item_id(slot_index) == ART_KIT_ITEM_ID:
|
||||
_hotbar.select_slot(slot_index)
|
||||
return
|
||||
if _surface_drawing.is_active():
|
||||
_surface_drawing.deactivate()
|
||||
elif _surface_drawing.can_activate():
|
||||
_surface_drawing.activate(_drawing_pointer_window_position())
|
||||
|
||||
|
||||
func set_surface_drawing_hotbar_selected(is_selected: bool) -> void:
|
||||
_surface_drawing_hotbar_selected = is_selected
|
||||
_refresh_surface_drawing_activation()
|
||||
|
||||
|
||||
func _refresh_surface_drawing_activation() -> void:
|
||||
if _surface_drawing == null:
|
||||
return
|
||||
if is_selected:
|
||||
if not _surface_drawing.is_active() and _surface_drawing.can_activate():
|
||||
var should_be_active: bool = _can_surface_drawing_be_active()
|
||||
if should_be_active and not _surface_drawing.is_active():
|
||||
_surface_drawing.activate(_drawing_pointer_window_position())
|
||||
elif _surface_drawing.is_active():
|
||||
elif not should_be_active and _surface_drawing.is_active():
|
||||
_surface_drawing.deactivate()
|
||||
|
||||
|
||||
func _can_surface_drawing_be_active() -> bool:
|
||||
return (
|
||||
_surface_drawing_hotbar_selected
|
||||
and _gameplay_ui_enabled
|
||||
and not _system_menu_open
|
||||
and not _player_menu_open
|
||||
and not _shop_open
|
||||
and not _chat_input_open
|
||||
and not _showcase_active
|
||||
and _fishing_spot != null
|
||||
and _fishing_spot.can_use_surface_drawing()
|
||||
and _surface_drawing != null
|
||||
and _surface_drawing.can_activate()
|
||||
)
|
||||
|
||||
|
||||
func _drawing_pointer_window_position() -> Vector2:
|
||||
if _virtual_mouse_active:
|
||||
return _virtual_mouse_window_position
|
||||
|
|
@ -1462,6 +1478,7 @@ func set_gameplay_ui_enabled(enabled: bool) -> void:
|
|||
_hotbar_ui.set_gameplay_input_enabled(true)
|
||||
_refresh_fishing_panel_visibility()
|
||||
call_deferred("_start_next_experience_animation")
|
||||
_refresh_surface_drawing_activation()
|
||||
|
||||
|
||||
func set_gameplay_hud_hidden(hidden: bool) -> void:
|
||||
|
|
@ -1505,8 +1522,7 @@ func _refresh_gameplay_hud_visibility() -> void:
|
|||
|
||||
func set_system_menu_open(is_open: bool) -> void:
|
||||
_system_menu_open = is_open
|
||||
if is_open and _surface_drawing != null:
|
||||
_surface_drawing.deactivate()
|
||||
_refresh_surface_drawing_activation()
|
||||
_refresh_gameplay_hud_visibility()
|
||||
_refresh_chat_availability()
|
||||
_refresh_hotbar_visibility()
|
||||
|
|
@ -1862,6 +1878,7 @@ func _on_showcase_changed(
|
|||
showcase_visible: bool,
|
||||
) -> void:
|
||||
_showcase_active = showcase_visible
|
||||
_refresh_surface_drawing_activation()
|
||||
if not showcase_visible:
|
||||
_set_fishing_panel_showcase_position(false)
|
||||
_showcase_details.text = ""
|
||||
|
|
@ -2103,8 +2120,7 @@ func _on_player_menu_visibility_changed(is_open: bool) -> void:
|
|||
_player_menu_open = is_open
|
||||
if is_open:
|
||||
_end_virtual_mouse()
|
||||
if is_open and _surface_drawing != null:
|
||||
_surface_drawing.deactivate()
|
||||
_refresh_surface_drawing_activation()
|
||||
_refresh_gameplay_hud_visibility()
|
||||
if is_open:
|
||||
_hotbar_ui.set_drag_enabled(false)
|
||||
|
|
@ -2156,8 +2172,7 @@ func _on_shop_exit_started() -> void:
|
|||
|
||||
func _on_shop_visibility_changed(is_open: bool) -> void:
|
||||
_shop_open = is_open
|
||||
if is_open and _surface_drawing != null:
|
||||
_surface_drawing.deactivate()
|
||||
_refresh_surface_drawing_activation()
|
||||
if is_open:
|
||||
shop_backdrop_visibility_changed.emit(true)
|
||||
if not is_open and _player_menu.is_shop_cooler_mounted():
|
||||
|
|
@ -2309,8 +2324,7 @@ func _emit_interactive_pointer_ui_changed() -> void:
|
|||
|
||||
func _on_chat_text_entry_ownership_changed(active: bool) -> void:
|
||||
_chat_input_open = active
|
||||
if active and _surface_drawing != null:
|
||||
_surface_drawing.deactivate()
|
||||
_refresh_surface_drawing_activation()
|
||||
_refresh_chat_availability()
|
||||
_emit_interactive_pointer_ui_changed()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,13 @@ class_name SurfaceDrawingToolbar
|
|||
extends Control
|
||||
|
||||
const UtilityPageStyleType = preload("res://ui/utility_page_style.gd")
|
||||
const TOOLBAR_WIDTH: float = 580.0
|
||||
const MARKER_MODE_ICON: Texture2D = preload(
|
||||
"res://items/icons/art/art_kit_marker.png"
|
||||
)
|
||||
const GRID_MODE_ICON: Texture2D = preload(
|
||||
"res://items/icons/art/art_kit_grid_light.png"
|
||||
)
|
||||
const TOOLBAR_WIDTH: float = 510.0
|
||||
const TOOLBAR_HEIGHT: float = 373.0
|
||||
const COLOR_RAIL_WIDTH: float = 46.0
|
||||
|
||||
|
|
@ -17,7 +23,6 @@ const COLOR_RAIL_WIDTH: float = 46.0
|
|||
@onready var _hide_guide_button: Button = %HideGuideButton
|
||||
@onready var _restore_guide_button: Button = %RestoreGuideButton
|
||||
@onready var _finalize_guide_button: Button = %FinalizeGuideButton
|
||||
@onready var _close_button: Button = %CloseButton
|
||||
|
||||
var _service: NetworkSurfaceDrawingService
|
||||
var _unlocks: PlayerArtUnlocks
|
||||
|
|
@ -36,10 +41,11 @@ func _ready() -> void:
|
|||
UtilityPageStyleType.apply_ocean_button(button)
|
||||
button.custom_minimum_size = Vector2(48, 44)
|
||||
_make_button_round(button, 22)
|
||||
_enlarge_action_icon(_eraser_button)
|
||||
_enlarge_action_icon(_undo_button)
|
||||
_mode_button.custom_minimum_size = Vector2(48, 48)
|
||||
_make_button_round(_mode_button, 24)
|
||||
_enlarge_action_icon(_mode_button)
|
||||
for button: Button in _action_buttons():
|
||||
_enlarge_action_icon(button)
|
||||
_mode_button.pressed.connect(_toggle_mode)
|
||||
_eraser_button.pressed.connect(_toggle_eraser)
|
||||
_undo_button.pressed.connect(_undo_last_stroke)
|
||||
|
|
@ -52,7 +58,6 @@ func _ready() -> void:
|
|||
_finalize_guide_button.pressed.connect(
|
||||
_arm_guide_action.bind(NetworkSurfaceDrawingService.GuideAction.FINALIZE)
|
||||
)
|
||||
_close_button.pressed.connect(_close_toolbar)
|
||||
_brush_option.item_selected.connect(_select_brush)
|
||||
_grid_option.item_selected.connect(_select_grid)
|
||||
_build_options()
|
||||
|
|
@ -77,7 +82,6 @@ func _action_buttons() -> Array[Button]:
|
|||
_hide_guide_button,
|
||||
_restore_guide_button,
|
||||
_finalize_guide_button,
|
||||
_close_button,
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -146,6 +150,8 @@ func _apply_dock_side() -> void:
|
|||
offset_right = 0.0 if _dock_right else TOOLBAR_WIDTH
|
||||
offset_top = 0.0
|
||||
offset_bottom = TOOLBAR_HEIGHT
|
||||
_top_panel.offset_left = 0.0
|
||||
_top_panel.offset_right = TOOLBAR_WIDTH
|
||||
_color_panel.offset_left = (
|
||||
TOOLBAR_WIDTH - COLOR_RAIL_WIDTH if _dock_right else 0.0
|
||||
)
|
||||
|
|
@ -276,11 +282,6 @@ func _arm_guide_action(action: int) -> void:
|
|||
_service.arm_guide_action(action)
|
||||
|
||||
|
||||
func _close_toolbar() -> void:
|
||||
if _service != null:
|
||||
_service.deactivate()
|
||||
|
||||
|
||||
func _on_unlocks_changed(_unlock_mask: int) -> void:
|
||||
_refresh_unlocks()
|
||||
|
||||
|
|
@ -297,7 +298,14 @@ func _on_service_state_changed(
|
|||
visible = is_active
|
||||
if not is_active:
|
||||
return
|
||||
_mode_button.text = "▦" if mode_name == "place grid" else "●"
|
||||
_mode_button.icon = (
|
||||
GRID_MODE_ICON if mode_name == "place grid" else MARKER_MODE_ICON
|
||||
)
|
||||
_mode_button.accessibility_name = (
|
||||
"switch to marker mode"
|
||||
if mode_name == "place grid"
|
||||
else "switch to grid mode"
|
||||
)
|
||||
_mode_button.tooltip_text = (
|
||||
"Switch to marker mode"
|
||||
if mode_name == "place grid"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
[gd_scene load_steps=8 format=3]
|
||||
[gd_scene load_steps=11 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://ui/surface_drawing_toolbar.gd" id="1_script"]
|
||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/pictograms/undo_light.png" id="3_undo_light"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/pictograms/check_mark_light.png" id="4_check_mark_light"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/pictograms/x_light.png" id="5_x_light"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_eraser.png" id="6_art_kit_eraser"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_eraser.png" id="4_art_kit_eraser"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_marker.png" id="5_art_kit_marker"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_light.png" id="6_grid_light"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_hidden_light.png" id="7_grid_hidden"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_restore_light.png" id="8_grid_restore"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_finish_light.png" id="9_grid_finish"]
|
||||
|
||||
[sub_resource type="ButtonGroup" id="GuideActionGroup"]
|
||||
allow_unpress = true
|
||||
|
|
@ -17,7 +20,7 @@ layout_mode = 0
|
|||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -580.0
|
||||
offset_left = -510.0
|
||||
offset_bottom = 373.0
|
||||
grow_horizontal = 0
|
||||
mouse_filter = 2
|
||||
|
|
@ -27,19 +30,13 @@ script = ExtResource("1_script")
|
|||
[node name="TopPanel" type="PanelContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 580.0
|
||||
offset_right = 510.0
|
||||
offset_bottom = 60.0
|
||||
|
||||
[node name="Top" type="HBoxContainer" parent="TopPanel"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 5
|
||||
|
||||
[node name="ModeButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "switch between grid and marker mode"
|
||||
text = "▦"
|
||||
|
||||
[node name="BrushOption" type="OptionButton" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(80, 48)
|
||||
|
|
@ -59,7 +56,7 @@ texture_filter = 1
|
|||
tooltip_text = "toggle eraser"
|
||||
toggle_mode = true
|
||||
accessibility_name = "toggle eraser"
|
||||
icon = ExtResource("6_art_kit_eraser")
|
||||
icon = ExtResource("4_art_kit_eraser")
|
||||
expand_icon = true
|
||||
|
||||
[node name="UndoButton" type="Button" parent="TopPanel/Top"]
|
||||
|
|
@ -74,18 +71,24 @@ expand_icon = true
|
|||
[node name="HideGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
texture_filter = 1
|
||||
tooltip_text = "toggle hide grid mode"
|
||||
toggle_mode = true
|
||||
button_group = SubResource("GuideActionGroup")
|
||||
text = "◌"
|
||||
accessibility_name = "toggle hide grid mode"
|
||||
icon = ExtResource("7_grid_hidden")
|
||||
expand_icon = true
|
||||
|
||||
[node name="RestoreGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
texture_filter = 1
|
||||
tooltip_text = "toggle show grid mode"
|
||||
toggle_mode = true
|
||||
button_group = SubResource("GuideActionGroup")
|
||||
text = "▤"
|
||||
accessibility_name = "toggle show grid mode"
|
||||
icon = ExtResource("8_grid_restore")
|
||||
expand_icon = true
|
||||
|
||||
[node name="FinalizeGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -95,24 +98,24 @@ tooltip_text = "toggle finalize grid mode"
|
|||
toggle_mode = true
|
||||
button_group = SubResource("GuideActionGroup")
|
||||
accessibility_name = "toggle finalize grid mode"
|
||||
icon = ExtResource("4_check_mark_light")
|
||||
icon = ExtResource("9_grid_finish")
|
||||
expand_icon = true
|
||||
|
||||
[node name="CloseButton" type="Button" parent="TopPanel/Top"]
|
||||
[node name="ModeButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
texture_filter = 1
|
||||
tooltip_text = "close art tools"
|
||||
accessibility_name = "close art tools"
|
||||
icon = ExtResource("5_x_light")
|
||||
tooltip_text = "switch between grid and marker mode"
|
||||
accessibility_name = "switch to grid mode"
|
||||
icon = ExtResource("5_art_kit_marker")
|
||||
expand_icon = true
|
||||
|
||||
[node name="ColorPanel" type="PanelContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 534.0
|
||||
offset_left = 464.0
|
||||
offset_top = 54.0
|
||||
offset_right = 580.0
|
||||
offset_right = 510.0
|
||||
offset_bottom = 373.0
|
||||
|
||||
[node name="ColorList" type="VBoxContainer" parent="ColorPanel"]
|
||||
|
|
|
|||