diff --git a/art/exported/characters/base/netfishing_base_character.glb b/art/exported/characters/base/netfishing_base_character.glb index a0ef899..1d37709 100644 Binary files a/art/exported/characters/base/netfishing_base_character.glb and b/art/exported/characters/base/netfishing_base_character.glb differ diff --git a/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png b/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png new file mode 100644 index 0000000..36e6859 Binary files /dev/null and b/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png differ diff --git a/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png.import b/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png.import new file mode 100644 index 0000000..42a1604 --- /dev/null +++ b/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png.import @@ -0,0 +1,45 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dyjwgkgw0syo8" +path.s3tc="res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.s3tc.ctex" +path.etc2="res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={ +"md5": "c2f7c29aaaa95809e140eb308d9bb132" +} + +[deps] + +source_file="res://art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png" +dest_files=["res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.s3tc.ctex", "res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.etc2.ctex"] + +[params] + +compress/mode=2 +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=true +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=0 diff --git a/art/exported/characters/base/netfishing_base_character_mouth_three.png b/art/exported/characters/base/netfishing_base_character_mouth_three.png new file mode 100644 index 0000000..527f300 Binary files /dev/null and b/art/exported/characters/base/netfishing_base_character_mouth_three.png differ diff --git a/art/exported/characters/base/netfishing_base_character_mouth_three.png.import b/art/exported/characters/base/netfishing_base_character_mouth_three.png.import new file mode 100644 index 0000000..5c94ab7 --- /dev/null +++ b/art/exported/characters/base/netfishing_base_character_mouth_three.png.import @@ -0,0 +1,45 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dt5gitdtjdvcd" +path.s3tc="res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.s3tc.ctex" +path.etc2="res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={ +"md5": "f8bf25a1006c5cc2ab5323f4a758eec7" +} + +[deps] + +source_file="res://art/exported/characters/base/netfishing_base_character_mouth_three.png" +dest_files=["res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.s3tc.ctex", "res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.etc2.ctex"] + +[params] + +compress/mode=2 +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=true +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=0 diff --git a/art/exported/characters/base/netfishing_base_character_nose_dog_round.png b/art/exported/characters/base/netfishing_base_character_nose_dog_round.png new file mode 100644 index 0000000..18a4590 Binary files /dev/null and b/art/exported/characters/base/netfishing_base_character_nose_dog_round.png differ diff --git a/art/exported/characters/base/netfishing_base_character_nose_dog_round.png.import b/art/exported/characters/base/netfishing_base_character_nose_dog_round.png.import new file mode 100644 index 0000000..68c6e25 --- /dev/null +++ b/art/exported/characters/base/netfishing_base_character_nose_dog_round.png.import @@ -0,0 +1,45 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bmho1ryst3smt" +path.s3tc="res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.s3tc.ctex" +path.etc2="res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={ +"md5": "3134f170152f9fa1512b41b61ecb01fc" +} + +[deps] + +source_file="res://art/exported/characters/base/netfishing_base_character_nose_dog_round.png" +dest_files=["res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.s3tc.ctex", "res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.etc2.ctex"] + +[params] + +compress/mode=2 +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=true +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=0 diff --git a/art/exported/characters/faces/eyes/eyes_simple_shine.png b/art/exported/characters/faces/eyes/eyes_simple_shine.png new file mode 100644 index 0000000..36e6859 Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_simple_shine.png differ diff --git a/art/exported/characters/faces/eyes/eyes_simple_shine.png.import b/art/exported/characters/faces/eyes/eyes_simple_shine.png.import new file mode 100644 index 0000000..8cc687f --- /dev/null +++ b/art/exported/characters/faces/eyes/eyes_simple_shine.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b345yhfv8w1j5" +path="res://.godot/imported/eyes_simple_shine.png-33edcf4bb163d7f2bde9a662105cf788.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/exported/characters/faces/eyes/eyes_simple_shine.png" +dest_files=["res://.godot/imported/eyes_simple_shine.png-33edcf4bb163d7f2bde9a662105cf788.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 diff --git a/art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png b/art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png new file mode 100644 index 0000000..d143b91 Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png differ diff --git a/art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png.import b/art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png.import new file mode 100644 index 0000000..94c26e2 --- /dev/null +++ b/art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://8wg4k4us4baa" +path="res://.godot/imported/eyes_simple_shine_eyebrows.png-d2147df0247f280b8f63b23d590204ab.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png" +dest_files=["res://.godot/imported/eyes_simple_shine_eyebrows.png-d2147df0247f280b8f63b23d590204ab.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 diff --git a/art/exported/characters/faces/mouth/mouth_three.png b/art/exported/characters/faces/mouth/mouth_three.png new file mode 100644 index 0000000..527f300 Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_three.png differ diff --git a/art/exported/characters/faces/mouth/mouth_three.png.import b/art/exported/characters/faces/mouth/mouth_three.png.import new file mode 100644 index 0000000..914fcf4 --- /dev/null +++ b/art/exported/characters/faces/mouth/mouth_three.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://crrw5vvop2gj7" +path="res://.godot/imported/mouth_three.png-b0b3775e32dfd17b6cfcac16b5c64d58.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/exported/characters/faces/mouth/mouth_three.png" +dest_files=["res://.godot/imported/mouth_three.png-b0b3775e32dfd17b6cfcac16b5c64d58.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 diff --git a/art/exported/characters/faces/noses/nose_dog_round.png b/art/exported/characters/faces/noses/nose_dog_round.png new file mode 100644 index 0000000..18a4590 Binary files /dev/null and b/art/exported/characters/faces/noses/nose_dog_round.png differ diff --git a/art/exported/characters/faces/noses/nose_dog_round.png.import b/art/exported/characters/faces/noses/nose_dog_round.png.import new file mode 100644 index 0000000..6fb7b7d --- /dev/null +++ b/art/exported/characters/faces/noses/nose_dog_round.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bbx0ywjiwymrm" +path="res://.godot/imported/nose_dog_round.png-e1d92a8a7b661901752b05898a3f7c8b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/exported/characters/faces/noses/nose_dog_round.png" +dest_files=["res://.godot/imported/nose_dog_round.png-e1d92a8a7b661901752b05898a3f7c8b.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 diff --git a/art/source/characters/base/netfishing_character_source.blend b/art/source/characters/base/netfishing_character_source.blend index 10cc911..0be2331 100644 Binary files a/art/source/characters/base/netfishing_character_source.blend and b/art/source/characters/base/netfishing_character_source.blend differ diff --git a/art/source/characters/base/netfishing_character_source.blend1 b/art/source/characters/base/netfishing_character_source.blend1 index 85fdee4..811ade5 100644 Binary files a/art/source/characters/base/netfishing_character_source.blend1 and b/art/source/characters/base/netfishing_character_source.blend1 differ diff --git a/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png b/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png new file mode 100644 index 0000000..36e6859 Binary files /dev/null and b/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png differ diff --git a/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png.import b/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png.import new file mode 100644 index 0000000..e3894c9 --- /dev/null +++ b/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png.import @@ -0,0 +1,45 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://du4u6meapay05" +path.s3tc="res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.s3tc.ctex" +path.etc2="res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={ +"md5": "c2f7c29aaaa95809e140eb308d9bb132" +} + +[deps] + +source_file="res://art/source/characters/base/netfishing_character_source_eyes_simple_shine.png" +dest_files=["res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.s3tc.ctex", "res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.etc2.ctex"] + +[params] + +compress/mode=2 +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=true +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=0 diff --git a/art/source/characters/base/netfishing_character_source_mouth_three.png b/art/source/characters/base/netfishing_character_source_mouth_three.png new file mode 100644 index 0000000..527f300 Binary files /dev/null and b/art/source/characters/base/netfishing_character_source_mouth_three.png differ diff --git a/art/source/characters/base/netfishing_character_source_mouth_three.png.import b/art/source/characters/base/netfishing_character_source_mouth_three.png.import new file mode 100644 index 0000000..4445b17 --- /dev/null +++ b/art/source/characters/base/netfishing_character_source_mouth_three.png.import @@ -0,0 +1,45 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://di20c1x8vksi1" +path.s3tc="res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.s3tc.ctex" +path.etc2="res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={ +"md5": "f8bf25a1006c5cc2ab5323f4a758eec7" +} + +[deps] + +source_file="res://art/source/characters/base/netfishing_character_source_mouth_three.png" +dest_files=["res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.s3tc.ctex", "res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.etc2.ctex"] + +[params] + +compress/mode=2 +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=true +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=0 diff --git a/art/source/characters/base/netfishing_character_source_nose_dog_round.png b/art/source/characters/base/netfishing_character_source_nose_dog_round.png new file mode 100644 index 0000000..18a4590 Binary files /dev/null and b/art/source/characters/base/netfishing_character_source_nose_dog_round.png differ diff --git a/art/source/characters/base/netfishing_character_source_nose_dog_round.png.import b/art/source/characters/base/netfishing_character_source_nose_dog_round.png.import new file mode 100644 index 0000000..9a8da06 --- /dev/null +++ b/art/source/characters/base/netfishing_character_source_nose_dog_round.png.import @@ -0,0 +1,45 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0p55hwdry2cr" +path.s3tc="res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.s3tc.ctex" +path.etc2="res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} +generator_parameters={ +"md5": "3134f170152f9fa1512b41b61ecb01fc" +} + +[deps] + +source_file="res://art/source/characters/base/netfishing_character_source_nose_dog_round.png" +dest_files=["res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.s3tc.ctex", "res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.etc2.ctex"] + +[params] + +compress/mode=2 +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=true +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=0 diff --git a/main/main.gd b/main/main.gd index 9acff94..bfdc498 100644 --- a/main/main.gd +++ b/main/main.gd @@ -533,6 +533,8 @@ func _initialize_after_data_root() -> void: _world_time, _world_weather, _player_jobs, + _test_world.get_world_environment(), + _test_world.get_sun(), ) _game_ui.setup_data_and_identity( _data_root, diff --git a/main/main.tscn b/main/main.tscn index 64247ca..7fb4e1b 100644 --- a/main/main.tscn +++ b/main/main.tscn @@ -44,18 +44,18 @@ [ext_resource type="Shader" uid="uid://byw3iub66qvog" path="res://ui/player_menu_pattern.gdshader" id="42_menu_pattern"] [ext_resource type="Texture2D" uid="uid://b6xws1d2dnbnn" path="res://art/patterns/pattern_moneyfish.png" id="43_shop_pattern"] [ext_resource type="PackedScene" uid="uid://w7n4gjqq1juc" path="res://art/exported/characters/base/netfishing_base_character.glb" id="44_4pcu1"] -[ext_resource type="Script" path="res://network/network_fish_showcase_service.gd" id="45_fish_showcase"] -[ext_resource type="Script" path="res://network/network_surface_drawing_service.gd" id="46_surface_drawing"] -[ext_resource type="Script" path="res://world/world_time_service.gd" id="47_world_time"] -[ext_resource type="Script" path="res://world/world_time_visual_controller.gd" id="48_world_time_visuals"] -[ext_resource type="Script" path="res://network/network_world_time_service.gd" id="49_network_world_time"] -[ext_resource type="Script" path="res://world/world_weather_service.gd" id="50_world_weather"] -[ext_resource type="Script" path="res://network/network_world_weather_service.gd" id="51_network_world_weather"] -[ext_resource type="Script" path="res://jobs/player_job_service.gd" id="52_player_jobs"] -[ext_resource type="Script" path="res://network/network_job_service.gd" id="53_network_jobs"] -[ext_resource type="Script" path="res://world/shoreline_ambience.gd" id="54_shoreline_ambience"] -[ext_resource type="AudioStream" path="res://audio/ambience/waves.wav" id="55_waves"] -[ext_resource type="Script" path="res://settings/controller_mapping_manager.gd" id="56_controller_mapping"] +[ext_resource type="Script" uid="uid://m4n0bn38f34i" path="res://network/network_fish_showcase_service.gd" id="45_fish_showcase"] +[ext_resource type="Script" uid="uid://bkiepgu8j5r6t" path="res://network/network_surface_drawing_service.gd" id="46_surface_drawing"] +[ext_resource type="Script" uid="uid://5lceyulaglpf" path="res://world/world_time_service.gd" id="47_world_time"] +[ext_resource type="Script" uid="uid://svirs8vbypad" path="res://world/world_time_visual_controller.gd" id="48_world_time_visuals"] +[ext_resource type="Script" uid="uid://blig76aes25j" path="res://network/network_world_time_service.gd" id="49_network_world_time"] +[ext_resource type="Script" uid="uid://v4c54isq6w74" path="res://world/world_weather_service.gd" id="50_world_weather"] +[ext_resource type="Script" uid="uid://llj46fx0oco7" path="res://network/network_world_weather_service.gd" id="51_network_world_weather"] +[ext_resource type="Script" uid="uid://daqtje84gqgu0" path="res://jobs/player_job_service.gd" id="52_player_jobs"] +[ext_resource type="Script" uid="uid://drlyytr2o3uw8" path="res://network/network_job_service.gd" id="53_network_jobs"] +[ext_resource type="Script" uid="uid://b0c3o2vy76fg3" path="res://world/shoreline_ambience.gd" id="54_shoreline_ambience"] +[ext_resource type="AudioStream" uid="uid://dck3tf8qkadea" path="res://audio/ambience/waves.wav" id="55_waves"] +[ext_resource type="Script" uid="uid://c80x8jkdnx0xy" path="res://settings/controller_mapping_manager.gd" id="56_controller_mapping"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_title_water_native"] shader = ExtResource("40_title_water") @@ -123,31 +123,31 @@ mouse_filter = 2 unique_name_in_owner = true script = ExtResource("39_fonts") -[node name="WorldTimeService" type="Node" parent="."] +[node name="WorldTimeService" type="Node" parent="." unique_id=1774610576] unique_name_in_owner = true script = ExtResource("47_world_time") -[node name="WorldTimeVisualController" type="Node" parent="."] +[node name="WorldTimeVisualController" type="Node" parent="." unique_id=1861087008] unique_name_in_owner = true script = ExtResource("48_world_time_visuals") -[node name="NetworkWorldTimeService" type="Node" parent="."] +[node name="NetworkWorldTimeService" type="Node" parent="." unique_id=1136962511] unique_name_in_owner = true script = ExtResource("49_network_world_time") -[node name="WorldWeatherService" type="Node" parent="."] +[node name="WorldWeatherService" type="Node" parent="." unique_id=1812156280] unique_name_in_owner = true script = ExtResource("50_world_weather") -[node name="NetworkWorldWeatherService" type="Node" parent="."] +[node name="NetworkWorldWeatherService" type="Node" parent="." unique_id=266238117] unique_name_in_owner = true script = ExtResource("51_network_world_weather") -[node name="PlayerJobService" type="Node" parent="."] +[node name="PlayerJobService" type="Node" parent="." unique_id=2062127535] unique_name_in_owner = true script = ExtResource("52_player_jobs") -[node name="NetworkJobService" type="Node" parent="."] +[node name="NetworkJobService" type="Node" parent="." unique_id=556458360] unique_name_in_owner = true script = ExtResource("53_network_jobs") @@ -223,11 +223,11 @@ script = ExtResource("23_network_shop") unique_name_in_owner = true script = ExtResource("24_network_item") -[node name="NetworkFishShowcaseService" type="Node" parent="."] +[node name="NetworkFishShowcaseService" type="Node" parent="." unique_id=148288598] unique_name_in_owner = true script = ExtResource("45_fish_showcase") -[node name="NetworkSurfaceDrawingService" type="Node" parent="."] +[node name="NetworkSurfaceDrawingService" type="Node" parent="." unique_id=80122665] unique_name_in_owner = true script = ExtResource("46_surface_drawing") @@ -252,11 +252,11 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0024132729, 0, -0.00093126 [node name="Players" type="Node3D" parent="." unique_id=550630144] -[node name="SurfaceDrawings" type="Node3D" parent="."] - [node name="Player" parent="Players" unique_id=485429332 instance=ExtResource("2_player")] unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 16) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.3999481, 12.07081) + +[node name="SurfaceDrawings" type="Node3D" parent="." unique_id=234671307] [node name="FishingSpot" parent="." unique_id=1461328864 instance=ExtResource("4_spot")] unique_name_in_owner = true @@ -274,7 +274,7 @@ script = ExtResource("9_save") unique_name_in_owner = true script = ExtResource("10_settings") -[node name="ControllerMappingManager" type="Node" parent="."] +[node name="ControllerMappingManager" type="Node" parent="." unique_id=1198390067] unique_name_in_owner = true script = ExtResource("56_controller_mapping") @@ -284,11 +284,11 @@ stream = ExtResource("13_title_music") volume_db = -80.0 bus = &"Music" -[node name="ShorelineAmbience" type="Node" parent="."] +[node name="ShorelineAmbience" type="Node" parent="." unique_id=1948037177] unique_name_in_owner = true script = ExtResource("54_shoreline_ambience") -[node name="WavesAudio" type="AudioStreamPlayer" parent="ShorelineAmbience"] +[node name="WavesAudio" type="AudioStreamPlayer" parent="ShorelineAmbience" unique_id=193530658] unique_name_in_owner = true stream = ExtResource("55_waves") bus = &"SFX" diff --git a/player/fishing_rod_attachment.tscn b/player/fishing_rod_attachment.tscn index 4771285..af895f5 100644 --- a/player/fishing_rod_attachment.tscn +++ b/player/fishing_rod_attachment.tscn @@ -13,7 +13,7 @@ roughness = 0.8 bone_name = "hand.R" [node name="FishingRod" type="Node3D" parent="."] -rotation = Vector3(-0.785398, -0.007863, 3.141593) +rotation_degrees = Vector3(322.6, -31.2, 248.9) [node name="RodMesh" type="MeshInstance3D" parent="FishingRod"] position = Vector3(0, 0.42, 0) diff --git a/player/player.gd b/player/player.gd index 3bf0f67..ad10369 100644 --- a/player/player.gd +++ b/player/player.gd @@ -171,6 +171,7 @@ var _controller_mapping_manager: ControllerMappingManagerType func _ready() -> void: + PlayerVisualPresenter.apply_appearance(_visuals, appearance_snapshot) _initialize_fishing_rod() _target_zoom = clampf(_spring_arm.spring_length, minimum_zoom, maximum_zoom) _spring_arm.spring_length = _target_zoom diff --git a/player/player_visual_presenter.gd b/player/player_visual_presenter.gd index e75f791..a6bdbee 100644 --- a/player/player_visual_presenter.gd +++ b/player/player_visual_presenter.gd @@ -2,6 +2,25 @@ class_name PlayerVisualPresenter extends RefCounted const PlayerScene: PackedScene = preload("res://player/player.tscn") +const EYE_TEXTURES: Dictionary = { + "simple_shine": preload( + "res://art/exported/characters/faces/eyes/eyes_simple_shine.png" + ), + "simple_shine_eyebrows": preload( + "res://art/exported/characters/faces/eyes/eyes_simple_shine_eyebrows.png" + ), +} +const MOUTH_TEXTURES: Dictionary = { + "three": preload( + "res://art/exported/characters/faces/mouth/mouth_three.png" + ), +} +const NOSE_TEXTURES: Dictionary = { + "dog_round": preload( + "res://art/exported/characters/faces/noses/nose_dog_round.png" + ), +} +const RUNTIME_MATERIAL_META: StringName = &"netfishing_runtime_material" static func instantiate_visuals() -> Node3D: @@ -32,10 +51,115 @@ static func instantiate_visuals() -> Node3D: static func apply_appearance( - _visuals: Node3D, + visuals: Node3D, snapshot: Dictionary, ) -> void: - # Gameplay and preview deliberately share this presentation seam. Modular - # visual parts can be applied here without coupling Profile to Player. if not CharacterCustomizationCatalog.validate_snapshot(snapshot): return + # Gameplay and preview deliberately share this presentation seam. Keep all + # mesh selection here so profile previews and network avatars stay identical. + var skeleton: Skeleton3D = visuals.find_child("Skeleton3D", true, false) as Skeleton3D + if skeleton == null: + return + + var species_id: String = CharacterCustomizationCatalog.canonical_option_id( + "species", str(snapshot.get("species", "round")) + ) + var head_id: String = "head_pointy" if species_id == "pointy" else "head_round" + var head_ids: Array[String] = ["head_pointy", "head_round"] + for head_name: String in head_ids: + var head: Node3D = skeleton.get_node_or_null(head_name) as Node3D + if head != null: + head.visible = head_name == head_id + for feature: String in ["eyes", "mouth", "nose"]: + var decal: Node3D = skeleton.get_node_or_null( + "%s_%s" % [head_name, feature] + ) as Node3D + if decal != null: + decal.visible = head_name == head_id + + var selected_ears: String = CharacterCustomizationCatalog.canonical_option_id( + "ears", str(snapshot.get("ears", "none")) + ) + var ear_names: Array[String] = [ + "ears_pointy_long", + "ears_pointy_short", + "ears_pointy_wide", + ] + for ear_name: String in ear_names: + var ears: Node3D = skeleton.get_node_or_null(ear_name) as Node3D + if ears != null: + ears.visible = selected_ears == ear_name.trim_prefix("ears_") + + var fur_color: Color = CharacterCustomizationCatalog.option_color( + "fur_pattern", str(snapshot.get("fur_pattern", "white")) + ) + _set_mesh_color(skeleton, "body_arms", fur_color) + _set_mesh_color(skeleton, "body_main", fur_color) + _set_mesh_color(skeleton, "head_pointy", fur_color) + _set_mesh_color(skeleton, "head_round", fur_color) + for ear_name: String in ear_names: + _set_mesh_color(skeleton, ear_name, fur_color) + + var eye_id: String = CharacterCustomizationCatalog.canonical_option_id( + "eyes", str(snapshot.get("eyes", "simple_shine")) + ) + var mouth_id: String = CharacterCustomizationCatalog.canonical_option_id( + "mouth", str(snapshot.get("mouth", "three")) + ) + var nose_id: String = CharacterCustomizationCatalog.canonical_option_id( + "nose", str(snapshot.get("nose", "dog_round")) + ) + _set_feature_texture(skeleton, "eyes", EYE_TEXTURES.get(eye_id) as Texture2D) + _set_feature_texture( + skeleton, "mouth", MOUTH_TEXTURES.get(mouth_id) as Texture2D + ) + _set_feature_texture(skeleton, "nose", NOSE_TEXTURES.get(nose_id) as Texture2D) + + +static func _set_feature_texture( + skeleton: Skeleton3D, + feature_name: String, + texture: Texture2D, +) -> void: + if texture == null: + return + for head_name: String in ["head_pointy", "head_round"]: + var mesh_instance: MeshInstance3D = skeleton.get_node_or_null( + "%s_%s" % [head_name, feature_name] + ) as MeshInstance3D + var material: StandardMaterial3D = _runtime_material(mesh_instance) + if material != null: + material.albedo_color = Color.WHITE + material.albedo_texture = texture + + +static func _set_mesh_color( + skeleton: Skeleton3D, + mesh_name: String, + color: Color, +) -> void: + var mesh_instance: MeshInstance3D = skeleton.get_node_or_null( + mesh_name + ) as MeshInstance3D + var material: StandardMaterial3D = _runtime_material(mesh_instance) + if material != null: + material.albedo_color = color + + +static func _runtime_material( + mesh_instance: MeshInstance3D, +) -> StandardMaterial3D: + if mesh_instance == null or mesh_instance.mesh == null: + return null + if mesh_instance.has_meta(RUNTIME_MATERIAL_META): + return mesh_instance.material_override as StandardMaterial3D + var source: StandardMaterial3D = mesh_instance.mesh.surface_get_material( + 0 + ) as StandardMaterial3D + if source == null: + return null + var material: StandardMaterial3D = source.duplicate() as StandardMaterial3D + mesh_instance.material_override = material + mesh_instance.set_meta(RUNTIME_MATERIAL_META, true) + return material diff --git a/progression/character_customization_catalog.gd b/progression/character_customization_catalog.gd index fc34417..09a6bad 100644 --- a/progression/character_customization_catalog.gd +++ b/progression/character_customization_catalog.gd @@ -12,8 +12,8 @@ const CATEGORY_IDS: PackedStringArray = [ ] const CATEGORY_LABELS: Dictionary = { - "species": "species", - "fur_pattern": "fur pattern", + "species": "head", + "fur_pattern": "fur color", "ears": "ears", "eyes": "eyes", "nose": "nose", @@ -22,24 +22,59 @@ const CATEGORY_LABELS: Dictionary = { } const OPTIONS: Dictionary = { - "species": [{"id": "default", "label": "default"}], - "fur_pattern": [{"id": "solid", "label": "solid"}], - "ears": [{"id": "default", "label": "default"}], - "eyes": [{"id": "default", "label": "default"}], - "nose": [{"id": "default", "label": "default"}], - "mouth": [{"id": "default", "label": "default"}], + "species": [ + {"id": "round", "label": "round"}, + {"id": "pointy", "label": "pointy"}, + ], + # The serialized field remains `fur_pattern` for save and network + # compatibility. It holds the initial solid fur-color selection until the + # authored pattern layer is ready. + "fur_pattern": [ + {"id": "white", "label": "white", "color": Color("f2f0e8")}, + {"id": "gray", "label": "gray", "color": Color("819398")}, + {"id": "charcoal", "label": "charcoal", "color": Color("34444a")}, + {"id": "brown", "label": "brown", "color": Color("7b4a32")}, + {"id": "orange", "label": "orange", "color": Color("c86c36")}, + {"id": "yellow", "label": "yellow", "color": Color("d8c545")}, + {"id": "green", "label": "green", "color": Color("6f913c")}, + {"id": "teal", "label": "teal", "color": Color("3a8790")}, + ], + "ears": [ + {"id": "none", "label": "none"}, + {"id": "pointy_long", "label": "long"}, + {"id": "pointy_short", "label": "short"}, + {"id": "pointy_wide", "label": "wide"}, + ], + "eyes": [ + {"id": "simple_shine", "label": "simple shine"}, + { + "id": "simple_shine_eyebrows", + "label": "simple shine + eyebrows", + }, + ], + "nose": [{"id": "dog_round", "label": "round"}], + "mouth": [{"id": "three", "label": "three"}], "tail": [{"id": "none", "label": "none"}], } +const LEGACY_OPTION_ALIASES: Dictionary = { + "species": {"default": "round"}, + "fur_pattern": {"solid": "white"}, + "ears": {"default": "none"}, + "eyes": {"default": "simple_shine"}, + "nose": {"default": "dog_round"}, + "mouth": {"default": "three"}, +} + static func default_snapshot() -> Dictionary: return { - "species": "default", - "fur_pattern": "solid", - "ears": "default", - "eyes": "default", - "nose": "default", - "mouth": "default", + "species": "round", + "fur_pattern": "white", + "ears": "none", + "eyes": "simple_shine", + "nose": "dog_round", + "mouth": "three", "tail": "none", } @@ -53,12 +88,26 @@ static func category_label(category_id: String) -> String: static func is_valid_option(category_id: String, option_id: String) -> bool: + option_id = canonical_option_id(category_id, option_id) for option: Dictionary in options_for(category_id): if str(option.get("id", "")) == option_id: return true return false +static func canonical_option_id(category_id: String, option_id: String) -> String: + var aliases: Dictionary = LEGACY_OPTION_ALIASES.get(category_id, {}) + return str(aliases.get(option_id, option_id)) + + +static func option_color(category_id: String, option_id: String) -> Color: + var canonical_id: String = canonical_option_id(category_id, option_id) + for option: Dictionary in options_for(category_id): + if str(option.get("id", "")) == canonical_id: + return option.get("color", Color.WHITE) as Color + return Color.WHITE + + static func validate_snapshot(value: Variant) -> bool: if typeof(value) != TYPE_DICTIONARY: return false @@ -80,7 +129,9 @@ static func sanitized_snapshot(value: Variant) -> Dictionary: return result var snapshot: Dictionary = value for category_id: String in CATEGORY_IDS: - var option_id := str(snapshot.get(category_id, "")) + var option_id: String = canonical_option_id( + category_id, str(snapshot.get(category_id, "")) + ) if is_valid_option(category_id, option_id): result[category_id] = option_id return result diff --git a/ui/game_ui.gd b/ui/game_ui.gd index 2683d95..63e5663 100644 --- a/ui/game_ui.gd +++ b/ui/game_ui.gd @@ -227,6 +227,8 @@ func setup( world_time: WorldTimeServiceType, world_weather: WorldWeatherServiceType, player_jobs: PlayerJobService, + world_environment: WorldEnvironment, + world_sun: DirectionalLight3D, ) -> void: _player = player _fishing_spot = fishing_spot @@ -285,6 +287,8 @@ func setup( network_player_list, player_jobs, world_time, + world_environment, + world_sun, ) _hotbar_ui.setup(hotbar, bag, item_catalog, fishing_spot, inventory) _fishing_shop.setup( diff --git a/ui/player_menu.gd b/ui/player_menu.gd index 09f768d..5644a68 100644 --- a/ui/player_menu.gd +++ b/ui/player_menu.gd @@ -508,6 +508,8 @@ func setup( network_player_list: NetworkPlayerListService, player_jobs: PlayerJobService, world_time: WorldTimeService, + world_environment: WorldEnvironment, + world_sun: DirectionalLight3D, ) -> void: _player = player _inventory = inventory @@ -530,7 +532,12 @@ func setup( _mail_page.setup( network_mail_service, reservations, inventory, wallet, bag, item_catalog ) - _profile_page.setup(network_profile_service, experience) + _profile_page.setup( + network_profile_service, + experience, + world_environment, + world_sun, + ) _players_page.setup(network_player_list) _catalog_logbook.setup(collection_log, inventory, catalog) _the_net_page.setup(player_jobs, world_time) diff --git a/ui/profile_page.gd b/ui/profile_page.gd index f7cc710..9442fce 100644 --- a/ui/profile_page.gd +++ b/ui/profile_page.gd @@ -27,6 +27,7 @@ var _revert_button: Button var _discard_confirmation: PanelContainer var _confirmation_label: Label var _confirmation_confirm: Button +var _keep_editing_button: Button var _confirmation_action: String = "" var _debounce: Timer var _experience_level: Label @@ -47,6 +48,8 @@ func _ready() -> void: func setup( service: NetworkProfileService, experience: PlayerExperience, + world_environment: WorldEnvironment, + world_sun: DirectionalLight3D, ) -> void: _service = service _experience = experience @@ -62,6 +65,7 @@ func setup( _experience.experience_changed.connect(_on_experience_changed) _load_persisted() _refresh_experience() + _preview.setup_world_lighting(world_environment, world_sun) var identity_value := find_child("IdentityFingerprint", true, false) as Label if identity_value != null: var fingerprint := _service.get_identity_fingerprint() @@ -344,16 +348,14 @@ func _build_ui() -> void: _confirmation_confirm.pressed.connect(_confirm_pending_action) UtilityPageStyle.apply_ocean_button(_confirmation_confirm) confirm_buttons.add_child(_confirmation_confirm) - var keep := Button.new() - keep.name = "KeepEditing" - keep.unique_name_in_owner = true - keep.text = "keep editing" - keep.pressed.connect(func() -> void: + _keep_editing_button = Button.new() + _keep_editing_button.text = "keep editing" + _keep_editing_button.pressed.connect(func() -> void: _discard_confirmation.visible = false _name_edit.grab_focus() ) - UtilityPageStyle.apply_ocean_button(keep) - confirm_buttons.add_child(keep) + UtilityPageStyle.apply_ocean_button(_keep_editing_button) + confirm_buttons.add_child(_keep_editing_button) _build_categories() @@ -394,13 +396,16 @@ func _refresh_options() -> void: "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY ) _option_list.add_child(title) - var options := CharacterCustomizationCatalog.options_for(_category_id) + var options: Array = CharacterCustomizationCatalog.options_for(_category_id) if options.is_empty(): var empty := Label.new() empty.text = "More options coming later." empty.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART _option_list.add_child(empty) return + if _category_id == "fur_pattern": + _build_fur_color_options(options) + return for option: Dictionary in options: var option_id := str(option["id"]) var button := Button.new() @@ -413,6 +418,49 @@ func _refresh_options() -> void: _option_list.add_child(button) +func _build_fur_color_options(options: Array) -> void: + var grid := GridContainer.new() + grid.columns = 4 + grid.add_theme_constant_override("h_separation", 10) + grid.add_theme_constant_override("v_separation", 10) + _option_list.add_child(grid) + var selected_id: String = CharacterCustomizationCatalog.canonical_option_id( + "fur_pattern", str(_draft_appearance.get("fur_pattern", "white")) + ) + for option: Dictionary in options: + var option_id: String = str(option.get("id", "")) + var color: Color = CharacterCustomizationCatalog.option_color( + "fur_pattern", option_id + ) + var button := Button.new() + button.text = "" + button.tooltip_text = str(option.get("label", option_id)) + button.toggle_mode = true + button.custom_minimum_size = Vector2(44.0, 44.0) + button.button_pressed = selected_id == option_id + button.pressed.connect(_select_option.bind("fur_pattern", option_id)) + _apply_fur_swatch_style(button, color, button.button_pressed) + grid.add_child(button) + + +func _apply_fur_swatch_style( + button: Button, + color: Color, + selected: bool, +) -> void: + var normal: StyleBoxFlat = UtilityPageStyle.rounded_style(color, 999) + var hover: StyleBoxFlat = UtilityPageStyle.rounded_style( + color.lightened(0.12), 999 + ) + var selected_style: StyleBoxFlat = UtilityPageStyle.rounded_style(color, 999) + selected_style.border_color = UtilityPageStyle.OCEAN_TEXT_PRIMARY + selected_style.set_border_width_all(3 if selected else 2) + button.add_theme_stylebox_override("normal", normal) + button.add_theme_stylebox_override("hover", hover) + button.add_theme_stylebox_override("pressed", selected_style) + button.add_theme_stylebox_override("focus", selected_style) + + func _select_option(category_id: String, option_id: String) -> void: _draft_appearance[category_id] = option_id _preview.apply_appearance_profile(_draft_appearance) @@ -546,7 +594,7 @@ func _show_confirmation(action: String) -> void: else: _confirmation_label.text = "Discard unsaved profile changes?" _confirmation_confirm.text = "discard changes" - _discard_confirmation.get_node("%KeepEditing").grab_focus() + _keep_editing_button.grab_focus() func _confirm_pending_action() -> void: diff --git a/ui/profile_preview.gd b/ui/profile_preview.gd index 38779f2..f75ea22 100644 --- a/ui/profile_preview.gd +++ b/ui/profile_preview.gd @@ -4,15 +4,20 @@ extends SubViewportContainer const ControllerMappingManagerType = preload( "res://settings/controller_mapping_manager.gd" ) +const FRONT_FACING_YAW: float = PI @export_range(0.1, 2.0, 0.05) var drag_sensitivity: float = 0.012 @export_range(0.1, 4.0, 0.1) var keyboard_speed: float = 1.8 @onready var _preview_root: Node3D = %PreviewRoot +@onready var _preview_environment: WorldEnvironment = %WorldEnvironment +@onready var _preview_sun: DirectionalLight3D = %KeyLight var _dragging: bool = false var _visuals: Node3D var _controller_mapping_manager: ControllerMappingManagerType +var _source_environment: WorldEnvironment +var _source_sun: DirectionalLight3D func setup_controller_mapping( @@ -21,9 +26,19 @@ func setup_controller_mapping( _controller_mapping_manager = mapping_manager +func setup_world_lighting( + world_environment: WorldEnvironment, + world_sun: DirectionalLight3D, +) -> void: + _source_environment = world_environment + _source_sun = world_sun + _sync_world_lighting() + + func _ready() -> void: focus_mode = Control.FOCUS_ALL gui_input.connect(_on_gui_input) + reset_view() _visuals = PlayerVisualPresenter.instantiate_visuals() _preview_root.add_child(_visuals) var rod := _visuals.find_child("FishingRod", true, false) as Node3D @@ -40,10 +55,11 @@ func apply_appearance_profile(profile: Dictionary) -> void: func reset_view() -> void: - _preview_root.rotation.y = 0.0 + _preview_root.rotation.y = FRONT_FACING_YAW func _process(delta: float) -> void: + _sync_world_lighting() if not has_focus(): return var axis := Input.get_axis("ui_left", "ui_right") @@ -78,3 +94,19 @@ func _notification(what: int) -> void: func _rotate(amount: float) -> void: _preview_root.rotation.y = fposmod(_preview_root.rotation.y + amount, TAU) + + +func _sync_world_lighting() -> void: + if ( + _preview_environment == null + or _preview_sun == null + or _source_environment == null + or _source_sun == null + ): + return + _preview_environment.environment = _source_environment.environment + _preview_sun.rotation = _source_sun.global_rotation + _preview_sun.light_color = _source_sun.light_color + _preview_sun.light_energy = _source_sun.light_energy + _preview_sun.light_indirect_energy = _source_sun.light_indirect_energy + _preview_sun.shadow_enabled = _source_sun.shadow_enabled diff --git a/ui/profile_preview.tscn b/ui/profile_preview.tscn index 79cd8fe..78d47cc 100644 --- a/ui/profile_preview.tscn +++ b/ui/profile_preview.tscn @@ -1,16 +1,8 @@ -[gd_scene load_steps=4 format=3] +[gd_scene load_steps=3 format=3] [ext_resource type="Script" path="res://ui/profile_preview.gd" id="1"] -[sub_resource type="Environment" id="Environment"] -background_mode = 1 -background_color = Color(0.075, 0.13, 0.16, 1) -ambient_light_source = 3 -ambient_light_color = Color(0.72, 0.82, 0.86, 1) -ambient_light_energy = 0.65 - [sub_resource type="World3D" id="PreviewWorld"] -environment = SubResource("Environment") [node name="ProfilePreview" type="SubViewportContainer"] custom_minimum_size = Vector2(300, 220) @@ -24,18 +16,12 @@ render_target_update_mode = 4 world_3d = SubResource("PreviewWorld") [node name="WorldEnvironment" type="WorldEnvironment" parent="Viewport"] -environment = SubResource("Environment") +unique_name_in_owner = true [node name="KeyLight" type="DirectionalLight3D" parent="Viewport"] -rotation_degrees = Vector3(-38, -32, 0) -light_energy = 1.15 -shadow_enabled = true - -[node name="FillLight" type="OmniLight3D" parent="Viewport"] -position = Vector3(-1.8, 1.6, 2.2) -light_color = Color(0.72, 0.84, 1, 1) -omni_range = 5.0 -light_energy = 1.3 +unique_name_in_owner = true +light_energy = 0.1 +shadow_enabled = false [node name="PreviewRoot" type="Node3D" parent="Viewport"] unique_name_in_owner = true