Compare commits
31 commits
v0.19.0-al
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| eeef99793d | |||
| 41b4f86ddf | |||
| 4fda6e97f6 | |||
| ac82a28f3b | |||
| 76b4f19e4d | |||
| 134ece4a10 | |||
| 6029eb29b8 | |||
| cd00f3c55e | |||
| 4196cda1d5 | |||
| f2239d248a | |||
| 82938d3d57 | |||
| 4d31fd1517 | |||
| 9cf0c8fc9c | |||
| ff78710303 | |||
| 0158b0215f | |||
| d8bf59bca0 | |||
| eed361681a | |||
| 014c064fae | |||
| 3be79fa3fc | |||
| 6578d3e870 | |||
| ee992d9f0c | |||
| 9b96a3bf53 | |||
| 826f62c352 | |||
| b48cb73f3a | |||
| d2dce7f900 | |||
| 983e4d0ec3 | |||
| fe099f47dd | |||
| 81decf2b71 | |||
| 4575830857 | |||
| ae802493a0 | |||
| f910e6bdbb |
|
|
@ -22,9 +22,9 @@ Discord: https://discord.gg/5gP22447kc
|
||||||
|
|
||||||
Matrix: https://matrix.to/#/#straywild:matrix.makearmy.io
|
Matrix: https://matrix.to/#/#straywild:matrix.makearmy.io
|
||||||
|
|
||||||
Repo: https://forge.makearmy.io/woofmeow/netfishing
|
Repo: https://forge.makearmy.io/woofmeow/straywild
|
||||||
|
|
||||||
Releases: https://forge.makearmy.io/woofmeow/netfishing/releases
|
Releases: https://forge.makearmy.io/woofmeow/straywild/releases
|
||||||
|
|
||||||
|
|
||||||
## Installing release builds
|
## Installing release builds
|
||||||
|
|
|
||||||
BIN
art/exported/creatures/2502.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
42
art/exported/creatures/2502.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://busj0feq2dncu"
|
||||||
|
path.s3tc="res://.godot/imported/2502.png-3922e306611b91541a86520cf32cbdbd.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2502.png-3922e306611b91541a86520cf32cbdbd.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2502.png"
|
||||||
|
dest_files=["res://.godot/imported/2502.png-3922e306611b91541a86520cf32cbdbd.s3tc.ctex", "res://.godot/imported/2502.png-3922e306611b91541a86520cf32cbdbd.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=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=0
|
||||||
BIN
art/exported/creatures/2504.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
42
art/exported/creatures/2504.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://4a7c1aat4777"
|
||||||
|
path.s3tc="res://.godot/imported/2504.png-c9f47ab152b933d8158b8c058ec5fcc2.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2504.png-c9f47ab152b933d8158b8c058ec5fcc2.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2504.png"
|
||||||
|
dest_files=["res://.godot/imported/2504.png-c9f47ab152b933d8158b8c058ec5fcc2.s3tc.ctex", "res://.godot/imported/2504.png-c9f47ab152b933d8158b8c058ec5fcc2.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=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=0
|
||||||
BIN
art/exported/creatures/2505.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
42
art/exported/creatures/2505.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b8u3lw242yr3c"
|
||||||
|
path.s3tc="res://.godot/imported/2505.png-fe14d70a6372dbe0cc4a8275d0816cad.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2505.png-fe14d70a6372dbe0cc4a8275d0816cad.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2505.png"
|
||||||
|
dest_files=["res://.godot/imported/2505.png-fe14d70a6372dbe0cc4a8275d0816cad.s3tc.ctex", "res://.godot/imported/2505.png-fe14d70a6372dbe0cc4a8275d0816cad.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=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=0
|
||||||
BIN
art/exported/creatures/2508.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
42
art/exported/creatures/2508.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c2k6ghkng6081"
|
||||||
|
path.s3tc="res://.godot/imported/2508.png-0478df4a4cb2af8e08ada8086efda0c3.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2508.png-0478df4a4cb2af8e08ada8086efda0c3.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2508.png"
|
||||||
|
dest_files=["res://.godot/imported/2508.png-0478df4a4cb2af8e08ada8086efda0c3.s3tc.ctex", "res://.godot/imported/2508.png-0478df4a4cb2af8e08ada8086efda0c3.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=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=0
|
||||||
BIN
art/exported/creatures/2601.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
42
art/exported/creatures/2601.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d14jvhurcfryb"
|
||||||
|
path.s3tc="res://.godot/imported/2601.png-912942ea4c6b2c66982e089ee46fde12.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2601.png-912942ea4c6b2c66982e089ee46fde12.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2601.png"
|
||||||
|
dest_files=["res://.godot/imported/2601.png-912942ea4c6b2c66982e089ee46fde12.s3tc.ctex", "res://.godot/imported/2601.png-912942ea4c6b2c66982e089ee46fde12.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=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=0
|
||||||
BIN
art/exported/creatures/2801.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
42
art/exported/creatures/2801.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cc7el34sfad78"
|
||||||
|
path.s3tc="res://.godot/imported/2801.png-d1c5df9faa2d1eb1cc3453c8e18d4049.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2801.png-d1c5df9faa2d1eb1cc3453c8e18d4049.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2801.png"
|
||||||
|
dest_files=["res://.godot/imported/2801.png-d1c5df9faa2d1eb1cc3453c8e18d4049.s3tc.ctex", "res://.godot/imported/2801.png-d1c5df9faa2d1eb1cc3453c8e18d4049.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=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=0
|
||||||
BIN
art/exported/creatures/2802.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
42
art/exported/creatures/2802.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bawecr4tv52p1"
|
||||||
|
path.s3tc="res://.godot/imported/2802.png-6319ce264fbd950e232fd0b428319265.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2802.png-6319ce264fbd950e232fd0b428319265.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2802.png"
|
||||||
|
dest_files=["res://.godot/imported/2802.png-6319ce264fbd950e232fd0b428319265.s3tc.ctex", "res://.godot/imported/2802.png-6319ce264fbd950e232fd0b428319265.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=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=0
|
||||||
BIN
art/exported/creatures/2803.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
42
art/exported/creatures/2803.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cjwm07240ehr2"
|
||||||
|
path.s3tc="res://.godot/imported/2803.png-c2e31a8adbab3bf9899bc74b3feb4abb.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2803.png-c2e31a8adbab3bf9899bc74b3feb4abb.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2803.png"
|
||||||
|
dest_files=["res://.godot/imported/2803.png-c2e31a8adbab3bf9899bc74b3feb4abb.s3tc.ctex", "res://.godot/imported/2803.png-c2e31a8adbab3bf9899bc74b3feb4abb.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=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=0
|
||||||
BIN
art/exported/creatures/2804.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
42
art/exported/creatures/2804.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dgcrfxo1k4juj"
|
||||||
|
path.s3tc="res://.godot/imported/2804.png-f86c52a01f04302b057cf526a498e87a.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2804.png-f86c52a01f04302b057cf526a498e87a.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2804.png"
|
||||||
|
dest_files=["res://.godot/imported/2804.png-f86c52a01f04302b057cf526a498e87a.s3tc.ctex", "res://.godot/imported/2804.png-f86c52a01f04302b057cf526a498e87a.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=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=0
|
||||||
BIN
art/exported/creatures/2806.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
42
art/exported/creatures/2806.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c5be8db5ppkq4"
|
||||||
|
path.s3tc="res://.godot/imported/2806.png-ed0484fec72605166ddb723c1a1bc7d0.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2806.png-ed0484fec72605166ddb723c1a1bc7d0.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2806.png"
|
||||||
|
dest_files=["res://.godot/imported/2806.png-ed0484fec72605166ddb723c1a1bc7d0.s3tc.ctex", "res://.godot/imported/2806.png-ed0484fec72605166ddb723c1a1bc7d0.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=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=0
|
||||||
BIN
art/exported/creatures/2807.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
42
art/exported/creatures/2807.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bdus4qo0ebs3e"
|
||||||
|
path.s3tc="res://.godot/imported/2807.png-aceaf0f586f975d29e318a9513fc3125.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/2807.png-aceaf0f586f975d29e318a9513fc3125.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/2807.png"
|
||||||
|
dest_files=["res://.godot/imported/2807.png-aceaf0f586f975d29e318a9513fc3125.s3tc.ctex", "res://.godot/imported/2807.png-aceaf0f586f975d29e318a9513fc3125.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=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=0
|
||||||
BIN
art/exported/creatures/3002.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
42
art/exported/creatures/3002.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b68vlgtclvkfg"
|
||||||
|
path.s3tc="res://.godot/imported/3002.png-a87d71158798b43b6bf702a6e1664b4d.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3002.png-a87d71158798b43b6bf702a6e1664b4d.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3002.png"
|
||||||
|
dest_files=["res://.godot/imported/3002.png-a87d71158798b43b6bf702a6e1664b4d.s3tc.ctex", "res://.godot/imported/3002.png-a87d71158798b43b6bf702a6e1664b4d.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=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=0
|
||||||
BIN
art/exported/creatures/3102.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
42
art/exported/creatures/3102.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c4d3f28rf86bb"
|
||||||
|
path.s3tc="res://.godot/imported/3102.png-951ca90331737e3057749e1bdbd88c44.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3102.png-951ca90331737e3057749e1bdbd88c44.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3102.png"
|
||||||
|
dest_files=["res://.godot/imported/3102.png-951ca90331737e3057749e1bdbd88c44.s3tc.ctex", "res://.godot/imported/3102.png-951ca90331737e3057749e1bdbd88c44.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=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=0
|
||||||
BIN
art/exported/creatures/3103.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
42
art/exported/creatures/3103.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cjtncgnb0hcsj"
|
||||||
|
path.s3tc="res://.godot/imported/3103.png-f3b4b5bb43b7611f7c448dbdfff36375.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3103.png-f3b4b5bb43b7611f7c448dbdfff36375.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3103.png"
|
||||||
|
dest_files=["res://.godot/imported/3103.png-f3b4b5bb43b7611f7c448dbdfff36375.s3tc.ctex", "res://.godot/imported/3103.png-f3b4b5bb43b7611f7c448dbdfff36375.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=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=0
|
||||||
BIN
art/exported/creatures/3104.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
42
art/exported/creatures/3104.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dlme86lrrhyg8"
|
||||||
|
path.s3tc="res://.godot/imported/3104.png-fa31dd69bf22b484cf3ac0d99197b886.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3104.png-fa31dd69bf22b484cf3ac0d99197b886.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3104.png"
|
||||||
|
dest_files=["res://.godot/imported/3104.png-fa31dd69bf22b484cf3ac0d99197b886.s3tc.ctex", "res://.godot/imported/3104.png-fa31dd69bf22b484cf3ac0d99197b886.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=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=0
|
||||||
BIN
art/exported/creatures/3107.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
42
art/exported/creatures/3107.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://csv1dsgvifh4l"
|
||||||
|
path.s3tc="res://.godot/imported/3107.png-5b981d56f7094a29a92b2f5035a47b11.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3107.png-5b981d56f7094a29a92b2f5035a47b11.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3107.png"
|
||||||
|
dest_files=["res://.godot/imported/3107.png-5b981d56f7094a29a92b2f5035a47b11.s3tc.ctex", "res://.godot/imported/3107.png-5b981d56f7094a29a92b2f5035a47b11.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=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=0
|
||||||
BIN
art/exported/creatures/3201.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
42
art/exported/creatures/3201.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cd8u0ow8cqsbh"
|
||||||
|
path.s3tc="res://.godot/imported/3201.png-846cb0fbb88950bb70d5b03c50a88457.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3201.png-846cb0fbb88950bb70d5b03c50a88457.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3201.png"
|
||||||
|
dest_files=["res://.godot/imported/3201.png-846cb0fbb88950bb70d5b03c50a88457.s3tc.ctex", "res://.godot/imported/3201.png-846cb0fbb88950bb70d5b03c50a88457.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=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=0
|
||||||
BIN
art/exported/creatures/3401.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
42
art/exported/creatures/3401.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://begsj5tj035e1"
|
||||||
|
path.s3tc="res://.godot/imported/3401.png-cd8c7ec154f8248110ec396b3f8a76c9.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3401.png-cd8c7ec154f8248110ec396b3f8a76c9.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3401.png"
|
||||||
|
dest_files=["res://.godot/imported/3401.png-cd8c7ec154f8248110ec396b3f8a76c9.s3tc.ctex", "res://.godot/imported/3401.png-cd8c7ec154f8248110ec396b3f8a76c9.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=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=0
|
||||||
BIN
art/exported/creatures/3902.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
42
art/exported/creatures/3902.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ddc556gcby50v"
|
||||||
|
path.s3tc="res://.godot/imported/3902.png-485bc4f9f1a505225bdc037111e32499.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/3902.png-485bc4f9f1a505225bdc037111e32499.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/3902.png"
|
||||||
|
dest_files=["res://.godot/imported/3902.png-485bc4f9f1a505225bdc037111e32499.s3tc.ctex", "res://.godot/imported/3902.png-485bc4f9f1a505225bdc037111e32499.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=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=0
|
||||||
BIN
art/exported/creatures/4101.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
42
art/exported/creatures/4101.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bahd6nks2g7ik"
|
||||||
|
path.s3tc="res://.godot/imported/4101.png-163a8880f3559279d2acc129509430bc.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/4101.png-163a8880f3559279d2acc129509430bc.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/4101.png"
|
||||||
|
dest_files=["res://.godot/imported/4101.png-163a8880f3559279d2acc129509430bc.s3tc.ctex", "res://.godot/imported/4101.png-163a8880f3559279d2acc129509430bc.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=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=0
|
||||||
BIN
art/exported/creatures/5001.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
42
art/exported/creatures/5001.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://byil5mr6w3j1q"
|
||||||
|
path.s3tc="res://.godot/imported/5001.png-ebe37fb8bd4263bb83e36bb5890b5641.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/5001.png-ebe37fb8bd4263bb83e36bb5890b5641.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/5001.png"
|
||||||
|
dest_files=["res://.godot/imported/5001.png-ebe37fb8bd4263bb83e36bb5890b5641.s3tc.ctex", "res://.godot/imported/5001.png-ebe37fb8bd4263bb83e36bb5890b5641.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=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=0
|
||||||
BIN
art/exported/creatures/5902.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
42
art/exported/creatures/5902.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://0k4qnt7wusam"
|
||||||
|
path.s3tc="res://.godot/imported/5902.png-e3a13a1e827488fa86f34c2aad883127.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/5902.png-e3a13a1e827488fa86f34c2aad883127.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/5902.png"
|
||||||
|
dest_files=["res://.godot/imported/5902.png-e3a13a1e827488fa86f34c2aad883127.s3tc.ctex", "res://.godot/imported/5902.png-e3a13a1e827488fa86f34c2aad883127.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=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=0
|
||||||
BIN
art/exported/creatures/5903.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
42
art/exported/creatures/5903.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bjb8gqbta2oxw"
|
||||||
|
path.s3tc="res://.godot/imported/5903.png-44743c2e322f48eefaeedcd3defec27d.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/5903.png-44743c2e322f48eefaeedcd3defec27d.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/5903.png"
|
||||||
|
dest_files=["res://.godot/imported/5903.png-44743c2e322f48eefaeedcd3defec27d.s3tc.ctex", "res://.godot/imported/5903.png-44743c2e322f48eefaeedcd3defec27d.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=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=0
|
||||||
BIN
art/exported/creatures/5904.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
42
art/exported/creatures/5904.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dtapwjgdbcgr7"
|
||||||
|
path.s3tc="res://.godot/imported/5904.png-e43ba3245eadac7081a6a23e64ccc940.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/5904.png-e43ba3245eadac7081a6a23e64ccc940.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/5904.png"
|
||||||
|
dest_files=["res://.godot/imported/5904.png-e43ba3245eadac7081a6a23e64ccc940.s3tc.ctex", "res://.godot/imported/5904.png-e43ba3245eadac7081a6a23e64ccc940.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=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=0
|
||||||
BIN
art/exported/creatures/6001.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
42
art/exported/creatures/6001.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c0164i40101lq"
|
||||||
|
path.s3tc="res://.godot/imported/6001.png-6fd8c3ef0885c466baece687cd24d38d.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6001.png-6fd8c3ef0885c466baece687cd24d38d.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6001.png"
|
||||||
|
dest_files=["res://.godot/imported/6001.png-6fd8c3ef0885c466baece687cd24d38d.s3tc.ctex", "res://.godot/imported/6001.png-6fd8c3ef0885c466baece687cd24d38d.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=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=0
|
||||||
BIN
art/exported/creatures/6406.png
Normal file
|
After Width: | Height: | Size: 4 KiB |
42
art/exported/creatures/6406.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://gnlehenln3kp"
|
||||||
|
path.s3tc="res://.godot/imported/6406.png-67ebebdd8d13cd88e0a209b3ed00024c.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6406.png-67ebebdd8d13cd88e0a209b3ed00024c.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6406.png"
|
||||||
|
dest_files=["res://.godot/imported/6406.png-67ebebdd8d13cd88e0a209b3ed00024c.s3tc.ctex", "res://.godot/imported/6406.png-67ebebdd8d13cd88e0a209b3ed00024c.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=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=0
|
||||||
BIN
art/exported/creatures/6601.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
42
art/exported/creatures/6601.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://jauudro8rgay"
|
||||||
|
path.s3tc="res://.godot/imported/6601.png-7d5f9459e449f3aa7ae72a9e069e6a21.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6601.png-7d5f9459e449f3aa7ae72a9e069e6a21.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6601.png"
|
||||||
|
dest_files=["res://.godot/imported/6601.png-7d5f9459e449f3aa7ae72a9e069e6a21.s3tc.ctex", "res://.godot/imported/6601.png-7d5f9459e449f3aa7ae72a9e069e6a21.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=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=0
|
||||||
BIN
art/exported/creatures/6801.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
42
art/exported/creatures/6801.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cuik8y4tqqetk"
|
||||||
|
path.s3tc="res://.godot/imported/6801.png-f771f612f1db1d1b99cb446dfebc4992.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6801.png-f771f612f1db1d1b99cb446dfebc4992.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6801.png"
|
||||||
|
dest_files=["res://.godot/imported/6801.png-f771f612f1db1d1b99cb446dfebc4992.s3tc.ctex", "res://.godot/imported/6801.png-f771f612f1db1d1b99cb446dfebc4992.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=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=0
|
||||||
BIN
art/exported/creatures/6807.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
42
art/exported/creatures/6807.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cu5s2rxrc0dh5"
|
||||||
|
path.s3tc="res://.godot/imported/6807.png-35d499aa8b3f10cc974cc7df8b70f89e.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6807.png-35d499aa8b3f10cc974cc7df8b70f89e.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6807.png"
|
||||||
|
dest_files=["res://.godot/imported/6807.png-35d499aa8b3f10cc974cc7df8b70f89e.s3tc.ctex", "res://.godot/imported/6807.png-35d499aa8b3f10cc974cc7df8b70f89e.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=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=0
|
||||||
BIN
art/exported/creatures/6901.png
Normal file
|
After Width: | Height: | Size: 7 KiB |
42
art/exported/creatures/6901.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://umjy47x208xb"
|
||||||
|
path.s3tc="res://.godot/imported/6901.png-f9ff2d1fc8e00eabd73822b5031f91d8.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6901.png-f9ff2d1fc8e00eabd73822b5031f91d8.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6901.png"
|
||||||
|
dest_files=["res://.godot/imported/6901.png-f9ff2d1fc8e00eabd73822b5031f91d8.s3tc.ctex", "res://.godot/imported/6901.png-f9ff2d1fc8e00eabd73822b5031f91d8.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=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=0
|
||||||
BIN
art/exported/creatures/6902.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
42
art/exported/creatures/6902.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://csdl6u3uvft45"
|
||||||
|
path.s3tc="res://.godot/imported/6902.png-f8899611759244b42c6c786ff118dcba.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6902.png-f8899611759244b42c6c786ff118dcba.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6902.png"
|
||||||
|
dest_files=["res://.godot/imported/6902.png-f8899611759244b42c6c786ff118dcba.s3tc.ctex", "res://.godot/imported/6902.png-f8899611759244b42c6c786ff118dcba.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=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=0
|
||||||
BIN
art/exported/creatures/6904.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
42
art/exported/creatures/6904.png.import
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bqh7d4v8jrbpr"
|
||||||
|
path.s3tc="res://.godot/imported/6904.png-38739e4e48fbb83e3f65074a93d681bb.s3tc.ctex"
|
||||||
|
path.etc2="res://.godot/imported/6904.png-38739e4e48fbb83e3f65074a93d681bb.etc2.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://art/exported/creatures/6904.png"
|
||||||
|
dest_files=["res://.godot/imported/6904.png-38739e4e48fbb83e3f65074a93d681bb.s3tc.ctex", "res://.godot/imported/6904.png-38739e4e48fbb83e3f65074a93d681bb.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=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=0
|
||||||
|
|
@ -142,8 +142,10 @@ environment and UI artwork, item artwork, finished fish and creature artwork,
|
||||||
and character customization pattern and channel-map artwork. Voyager's
|
and character customization pattern and channel-map artwork. Voyager's
|
||||||
incorporated original work includes 3D assets, the provisional fish
|
incorporated original work includes 3D assets, the provisional fish
|
||||||
placeholder artwork, the title and dusk music identified above, and the robot
|
placeholder artwork, the title and dusk music identified above, and the robot
|
||||||
animalese tones. Specific contributor exceptions are recorded below and in the
|
animalese tones. The current starter motorcoach exterior was supplied by a
|
||||||
in-game credits.
|
contributing artist who released its copyright to the project; the original
|
||||||
|
and cleaned source files are retained in the owners' source-work archive.
|
||||||
|
Specific contributor exceptions are recorded below and in the in-game credits.
|
||||||
|
|
||||||
These credits intentionally describe work by creator and contribution family
|
These credits intentionally describe work by creator and contribution family
|
||||||
instead of maintaining a second file-by-file asset catalog. Runtime resources
|
instead of maintaining a second file-by-file asset catalog. Runtime resources
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,15 @@ node names, connect persistent and networked state to that data.
|
||||||
network services validate and replicate bounded domains such as fishing,
|
network services validate and replicate bounded domains such as fishing,
|
||||||
sales, shops, item use, profiles, jobs, mail, chat, drawings, time, and weather.
|
sales, shops, item use, profiles, jobs, mail, chat, drawings, time, and weather.
|
||||||
|
|
||||||
`DiscoveryClient` is an optional directory layer beside `NetworkSession`. An
|
`DiscoveryClient` is an optional directory layer beside `NetworkSession`. A
|
||||||
open host may publish a short-lived room lease, and the shared Join Game page
|
player host cycles its discovery control through `private`, `direct`, and
|
||||||
may browse compatible leases before handing the selected address back to the
|
`relay`. Private leaves the room unlisted, direct discovery discloses the host
|
||||||
existing direct ENet connection flow. The directory does not carry gameplay
|
route only after an explicit Join, and relay discovery allocates a UDP privacy
|
||||||
traffic or become a gameplay authority. Its base URL comes from
|
route without making discovery a gameplay authority. Relay joins fail closed
|
||||||
|
and never silently downgrade to direct. Dedicated servers are always direct:
|
||||||
|
the game forces direct advertisements and discovery independently rejects a
|
||||||
|
dedicated relay request. Public room browsing never receives a host address.
|
||||||
|
The base URL comes from
|
||||||
`network/discovery/base_url`, with `straywild_DISCOVERY_URL` available as a
|
`network/discovery/base_url`, with `straywild_DISCOVERY_URL` available as a
|
||||||
development/deployment override.
|
development/deployment override.
|
||||||
|
|
||||||
|
|
@ -53,8 +57,9 @@ friendship; unblocking does not recreate it. Discovery may publish opt-in,
|
||||||
short-lived friend presence and deliver invitations only while both games are
|
short-lived friend presence and deliver invitations only while both games are
|
||||||
online. It stores hashed capability identifiers rather than identity
|
online. It stores hashed capability identifiers rather than identity
|
||||||
fingerprints or a complete friend graph, keeps no durable social records, and
|
fingerprints or a complete friend graph, keeps no durable social records, and
|
||||||
provides no offline delivery. Direct joins still use the existing verified
|
provides no offline delivery. Public joins still use the existing verified
|
||||||
public-room and ENet connection path.
|
server-identity and ENet connection path. Discovery endpoints remain transient:
|
||||||
|
they are not shown, added to recent servers, or persisted in the trust store.
|
||||||
|
|
||||||
The host is authoritative. Clients submit requests or evidence; the host
|
The host is authoritative. Clients submit requests or evidence; the host
|
||||||
derives trusted context from registered peers, authoritative regions, and
|
derives trusted context from registered peers, authoritative regions, and
|
||||||
|
|
@ -279,6 +284,35 @@ godot --headless --path . --script scripts/normalize_texture_imports.gd \
|
||||||
godot --headless --path . --script tests/texture_sampling_validation.gd
|
godot --headless --path . --script tests/texture_sampling_validation.gd
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Surface artwork runtime
|
||||||
|
|
||||||
|
Art Kit cells are authoritative palette and author planes, not per-cell nodes
|
||||||
|
or dictionaries. Keep `SurfaceDrawingCellBuffer` as the live representation;
|
||||||
|
materialize the legacy cell-array view only for inspection and tests. Finished
|
||||||
|
artwork uses a full-resolution nearest-neighbor texture on a coarse,
|
||||||
|
surface-conforming mesh. It discards guide and brush transforms, receives a
|
||||||
|
distance visibility range, and unloads its render node when far from the local
|
||||||
|
player while retaining compact session state.
|
||||||
|
|
||||||
|
`surface_drawing_v3` snapshots carry packed palette and participant-index
|
||||||
|
planes. The host sends late-join snapshots over multiple frames, prioritizing
|
||||||
|
active and nearby canvases, so adding finished work must not restore a
|
||||||
|
single-frame snapshot burst. Active editing and finalized artwork have
|
||||||
|
separate bounded budgets; finalizing a canvas frees active-grid capacity.
|
||||||
|
|
||||||
|
The finalized budget holds 512 maximum-size (128 x 128) canvases. At the
|
||||||
|
current 0.075-meter cell size, 441 canvases can tile the full 200 x 200-meter
|
||||||
|
generated-world footprint. If the generated world grows, update the finalized
|
||||||
|
canvas and cell budgets together and rerun the artwork performance validation.
|
||||||
|
|
||||||
|
Run both focused validations after changing this path:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path . --script tests/surface_drawing_validation.gd
|
||||||
|
godot --headless --path . \
|
||||||
|
--script tests/surface_drawing_performance_validation.gd
|
||||||
|
```
|
||||||
|
|
||||||
### Importing animalese voice sets
|
### Importing animalese voice sets
|
||||||
|
|
||||||
Animalese clips use one deterministic runtime level and format: -18 dBFS RMS
|
Animalese clips use one deterministic runtime level and format: -18 dBFS RMS
|
||||||
|
|
|
||||||
|
|
@ -67,15 +67,20 @@ are pinned to the same clean `main` commit:
|
||||||
bash scripts/build_portmaster.sh
|
bash scripts/build_portmaster.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The script deletes and regenerates the Linux ARM64 export, stages the package,
|
The script deletes and regenerates a PortMaster-specific ARM64 export in
|
||||||
validates its structure, and writes:
|
`builds/v<project-version>/portmaster-arm64/`, stages the package, validates its
|
||||||
|
structure, and writes:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
builds/v<project-version>/straywild.zip
|
builds/v<project-version>/straywild.zip
|
||||||
```
|
```
|
||||||
|
|
||||||
`--package-only` is reserved for repackaging an already validated ARM64 export.
|
`--package-only` is reserved for repackaging an already validated
|
||||||
It does not rebuild game content.
|
PortMaster-specific ARM64 export. It does not rebuild game content, and verifies
|
||||||
|
the tagged-export marker written by a prior full build so a generic Linux ARM64
|
||||||
|
binary cannot accidentally be repackaged as PortMaster. The standard Linux
|
||||||
|
ARM64 release staging directory remains separate so building PortMaster cannot
|
||||||
|
replace the normal Linux ARM64 payload with reduced assets.
|
||||||
|
|
||||||
For a packaging-only correction to an already published game release, commit
|
For a packaging-only correction to an already published game release, commit
|
||||||
only PortMaster launcher, packaging-script, or PortMaster documentation changes
|
only PortMaster launcher, packaging-script, or PortMaster documentation changes
|
||||||
|
|
@ -214,7 +219,11 @@ The light profile passes these Godot options:
|
||||||
- `--audio-output-latency 40`
|
- `--audio-output-latency 40`
|
||||||
|
|
||||||
It also passes `straywild_PERFORMANCE_PROFILE=light` and
|
It also passes `straywild_PERFORMANCE_PROFILE=light` and
|
||||||
`straywild_LOW_END=1`. The game renders the 3D world at 37.5% linear
|
`straywild_LOW_END=1`. Those selectors are honored only by the dedicated
|
||||||
|
PortMaster export, which carries the immutable `straywild_portmaster` Godot
|
||||||
|
feature tag; desktop, Android, macOS, generic ARM64, and dedicated-server
|
||||||
|
builds always use the full presentation even if those environment variables
|
||||||
|
are present. The game renders the 3D world at 37.5% linear
|
||||||
resolution with nearest-neighbor scaling, reducing 3D pixel work by about 86%
|
resolution with nearest-neighbor scaling, reducing 3D pixel work by about 86%
|
||||||
while the separately rendered UI retains its canonical resolution. The light
|
while the separately rendered UI retains its canonical resolution. The light
|
||||||
profile also:
|
profile also:
|
||||||
|
|
@ -260,10 +269,11 @@ On a typical muOS installation, the full path is:
|
||||||
/mnt/mmc/ports/straywild/conf/performance_profile
|
/mnt/mmc/ports/straywild/conf/performance_profile
|
||||||
```
|
```
|
||||||
|
|
||||||
Set the file to `light`, or remove it, to restore the default. An externally
|
Set the file to `light`, or remove it, to restore the default. Within the
|
||||||
provided `straywild_PERFORMANCE_PROFILE=normal` or `light` environment value
|
PortMaster package, an externally provided
|
||||||
takes precedence over the persistent file. Invalid values safely fall back to
|
`straywild_PERFORMANCE_PROFILE=normal` or `light` environment value takes
|
||||||
the light profile and are reported in `straywild/log.txt`.
|
precedence over the persistent file. Invalid values safely fall back to the
|
||||||
|
light profile and are reported in `straywild/log.txt`.
|
||||||
|
|
||||||
Do not use Godot's low processor mode for the light profile. It reduces idle
|
Do not use Godot's low processor mode for the light profile. It reduces idle
|
||||||
CPU usage by sleeping between updates and is not a game-performance
|
CPU usage by sleeping between updates and is not a game-performance
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
straywild
|
straywild
|
||||||
v0.19.0-alpha
|
v0.20.4-alpha
|
||||||
Alpha 0.19.0
|
Alpha 0.20.4
|
||||||
|
|
||||||
Thank you for trying this early private playtest.
|
Thank you for supporting this private testing release.
|
||||||
|
|
||||||
straywild is an early multiplayer fishing game. This alpha includes local
|
straywild is an early multiplayer fishing game. This alpha includes local
|
||||||
progression, player-hosted and dedicated multiplayer sessions, public room
|
progression, player-hosted and dedicated multiplayer sessions, public room
|
||||||
discovery, and direct UDP connections. Expect rough edges and please keep a
|
discovery, player-selected direct or privacy-relayed hosting, and optional
|
||||||
backup of any save or identity data you care about.
|
direct UDP connections. Player hosts can cycle discovery through private,
|
||||||
|
direct, and relay. Dedicated servers are always direct and cannot use the
|
||||||
|
shared relay. The relay hides peers' addresses from one another but not from
|
||||||
|
the relay operator. Direct connections expose public IP addresses to the
|
||||||
|
remote peer and are clearly labeled in game. Expect rough edges and please
|
||||||
|
keep a backup of any save or identity data you care about.
|
||||||
|
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
|
|
||||||
|
|
@ -83,6 +88,8 @@ FEATURES TO TRY
|
||||||
- Fishing, net gathering, and beach digging
|
- Fishing, net gathering, and beach digging
|
||||||
- Equipment and consumable use from the hotbar
|
- Equipment and consumable use from the hotbar
|
||||||
- Fishing Shop sell tray, wallet updates, and persistent upgrades
|
- Fishing Shop sell tray, wallet updates, and persistent upgrades
|
||||||
|
- Portable RV homes, multiplayer visits, RV storage, and the early decor
|
||||||
|
purchasing and placement prototype
|
||||||
- Seeded generated worlds and the authored starter-island layout
|
- Seeded generated worlds and the authored starter-island layout
|
||||||
- Generated beaches, ponds, lakes, complete rivers, denser forests, varied
|
- Generated beaches, ponds, lakes, complete rivers, denser forests, varied
|
||||||
elevation, and closed coastal cliffs
|
elevation, and closed coastal cliffs
|
||||||
|
|
@ -113,9 +120,11 @@ Please include:
|
||||||
|
|
||||||
KNOWN ALPHA LIMITATIONS
|
KNOWN ALPHA LIMITATIONS
|
||||||
|
|
||||||
- Public sessions remain direct connections; restrictive NAT or carrier-grade
|
- Direct public sessions may fail behind restrictive NAT or carrier-grade
|
||||||
networks may prevent some players from joining.
|
networks. Player-hosted relay sessions add an extra network hop and may have
|
||||||
|
more latency. Dedicated servers are direct-only.
|
||||||
- Multiplayer, dedicated-server deployment, UI, and balance are still alpha.
|
- Multiplayer, dedicated-server deployment, UI, and balance are still alpha.
|
||||||
- Some fish and character artwork remains temporary.
|
- Some fish and character artwork remains temporary.
|
||||||
|
- RV exteriors and decor use temporary prototype geometry and presentation.
|
||||||
- There is no installer or automatic updater.
|
- There is no installer or automatic updater.
|
||||||
- Windows builds are unsigned.
|
- Windows builds are unsigned.
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ for local README files.
|
||||||
|
|
||||||
## Related repositories
|
## Related repositories
|
||||||
|
|
||||||
- [Discovery service API](https://forge.makearmy.io/woofmeow/netfishing-discovery-server/src/branch/main/docs/API.md)
|
- [Discovery service API](https://forge.makearmy.io/woofmeow/straywild-discovery-server/src/branch/main/docs/API.md)
|
||||||
stays with the service implementation and defines its versioned HTTP
|
stays with the service implementation and defines its versioned HTTP
|
||||||
contract.
|
contract.
|
||||||
- [Dedicated-server packaging](https://forge.makearmy.io/woofmeow/netfishing-dedicated-server/src/branch/main/README.md)
|
- [Dedicated-server packaging](https://forge.makearmy.io/woofmeow/straywild-dedicated-server/src/branch/main/README.md)
|
||||||
stays with its installer and update scripts. It consumes this repository's
|
stays with its installer and update scripts. It consumes this repository's
|
||||||
attribution and legal notices from the exact pinned game commit instead of
|
attribution and legal notices from the exact pinned game commit instead of
|
||||||
maintaining copies.
|
maintaining copies.
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ const GUIDED_PIXEL_FILL: float = 0.88
|
||||||
const SURFACE_OFFSET: float = 0.012
|
const SURFACE_OFFSET: float = 0.012
|
||||||
const LAYER_OFFSET_STEP: float = 0.0002
|
const LAYER_OFFSET_STEP: float = 0.0002
|
||||||
const SURFACE_SAMPLE_DEPTH: float = 0.45
|
const SURFACE_SAMPLE_DEPTH: float = 0.45
|
||||||
|
const FINALIZED_VISIBILITY_RANGE: float = 96.0
|
||||||
|
const FINALIZED_VISIBILITY_MARGIN: float = 12.0
|
||||||
|
const FINALIZED_MAX_SUBDIVISIONS: int = 32
|
||||||
|
|
||||||
var canvas_id: String = ""
|
var canvas_id: String = ""
|
||||||
var grid_width: int = 0
|
var grid_width: int = 0
|
||||||
|
|
@ -18,7 +21,7 @@ var _surface_origin: Vector3
|
||||||
var _surface_normal: Vector3
|
var _surface_normal: Vector3
|
||||||
var _surface_tangent: Vector3
|
var _surface_tangent: Vector3
|
||||||
var _surface_bitangent: Vector3
|
var _surface_bitangent: Vector3
|
||||||
var _cells: Dictionary[int, Dictionary] = {}
|
var _cell_buffer: SurfaceDrawingCellBuffer
|
||||||
var _cell_surface_transforms: Array[Transform3D] = []
|
var _cell_surface_transforms: Array[Transform3D] = []
|
||||||
var _pixel_image: Image
|
var _pixel_image: Image
|
||||||
var _pixel_texture: ImageTexture
|
var _pixel_texture: ImageTexture
|
||||||
|
|
@ -36,8 +39,15 @@ func setup(
|
||||||
data: Dictionary,
|
data: Dictionary,
|
||||||
relationships: PlayerRelationshipStore,
|
relationships: PlayerRelationshipStore,
|
||||||
solid_surface_mask: int = 1,
|
solid_surface_mask: int = 1,
|
||||||
|
cell_buffer: SurfaceDrawingCellBuffer = null,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
if not SurfaceDrawingProtocol.validate_canvas_state(data):
|
if (
|
||||||
|
(cell_buffer == null and not SurfaceDrawingProtocol.validate_canvas_state(data))
|
||||||
|
or (
|
||||||
|
cell_buffer != null
|
||||||
|
and not SurfaceDrawingProtocol.validate_canvas_metadata(data)
|
||||||
|
)
|
||||||
|
):
|
||||||
return false
|
return false
|
||||||
canvas_id = str(data["canvas_id"])
|
canvas_id = str(data["canvas_id"])
|
||||||
grid_width = int(data["width"])
|
grid_width = int(data["width"])
|
||||||
|
|
@ -45,7 +55,6 @@ func setup(
|
||||||
cell_size = float(data["cell_size"])
|
cell_size = float(data["cell_size"])
|
||||||
revision = int(data["revision"])
|
revision = int(data["revision"])
|
||||||
creator_fingerprint = str(data["creator_fingerprint"])
|
creator_fingerprint = str(data["creator_fingerprint"])
|
||||||
participant_fingerprints = _participants_from_state(data)
|
|
||||||
_finalized = bool(data.get("finalized", false))
|
_finalized = bool(data.get("finalized", false))
|
||||||
_guide_visible = bool(data.get("guide_visible", true)) and not _finalized
|
_guide_visible = bool(data.get("guide_visible", true)) and not _finalized
|
||||||
_layer = int(data.get("layer", 0))
|
_layer = int(data.get("layer", 0))
|
||||||
|
|
@ -64,12 +73,20 @@ func setup(
|
||||||
_surface_bitangent = _surface_normal.cross(_surface_tangent).normalized()
|
_surface_bitangent = _surface_normal.cross(_surface_tangent).normalized()
|
||||||
_relationships = relationships
|
_relationships = relationships
|
||||||
_solid_surface_mask = solid_surface_mask
|
_solid_surface_mask = solid_surface_mask
|
||||||
_cells.clear()
|
_cell_buffer = cell_buffer
|
||||||
for cell_value: Variant in data["cells"]:
|
if _cell_buffer == null:
|
||||||
var cell: Dictionary = cell_value
|
_cell_buffer = SurfaceDrawingCellBuffer.new()
|
||||||
_cells[_cell_key(int(cell["x"]), int(cell["y"]))] = cell.duplicate(true)
|
if not _cell_buffer.configure_from_state(data, true):
|
||||||
_build_grid()
|
return false
|
||||||
_build_pixel_renderer()
|
elif _cell_buffer.width != grid_width or _cell_buffer.height != grid_height:
|
||||||
|
return false
|
||||||
|
participant_fingerprints = _cell_buffer.get_participants()
|
||||||
|
if _finalized:
|
||||||
|
_build_finalized_pixel_renderer()
|
||||||
|
else:
|
||||||
|
var samples: Dictionary = _sample_grid_vertices()
|
||||||
|
_build_grid(samples)
|
||||||
|
_build_pixel_renderer(samples)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,16 +97,25 @@ func apply_update(data: Dictionary) -> bool:
|
||||||
or int(data["revision"]) <= revision
|
or int(data["revision"]) <= revision
|
||||||
):
|
):
|
||||||
return false
|
return false
|
||||||
for edit_value: Variant in data["edits"]:
|
if _cell_buffer == null or not _cell_buffer.apply_edits(data["edits"]):
|
||||||
var edit: Dictionary = edit_value
|
return false
|
||||||
var key: int = _cell_key(int(edit["x"]), int(edit["y"]))
|
return _finish_buffered_update(data)
|
||||||
if str(edit["color_id"]).is_empty():
|
|
||||||
_cells.erase(key)
|
|
||||||
else:
|
func apply_buffered_update(data: Dictionary) -> bool:
|
||||||
_cells[key] = edit.duplicate(true)
|
if (
|
||||||
participant_fingerprints = _participants_from_update(
|
not SurfaceDrawingProtocol.validate_canvas_update(data)
|
||||||
data, participant_fingerprints
|
or str(data["canvas_id"]) != canvas_id
|
||||||
)
|
or int(data["revision"]) <= revision
|
||||||
|
or _cell_buffer == null
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
return _finish_buffered_update(data)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_buffered_update(data: Dictionary) -> bool:
|
||||||
|
_cell_buffer.ensure_participants(data.get("participant_fingerprints", []))
|
||||||
|
participant_fingerprints = _cell_buffer.get_participants()
|
||||||
revision = int(data["revision"])
|
revision = int(data["revision"])
|
||||||
if is_hidden_by_relationship():
|
if is_hidden_by_relationship():
|
||||||
_rebuild_pixel_image()
|
_rebuild_pixel_image()
|
||||||
|
|
@ -110,12 +136,18 @@ func apply_guide_update(data: Dictionary) -> bool:
|
||||||
participant_fingerprints = _participants_from_update(
|
participant_fingerprints = _participants_from_update(
|
||||||
data, participant_fingerprints
|
data, participant_fingerprints
|
||||||
)
|
)
|
||||||
|
if _cell_buffer != null:
|
||||||
|
_cell_buffer.ensure_participants(participant_fingerprints)
|
||||||
|
participant_fingerprints = _cell_buffer.get_participants()
|
||||||
_finalized = bool(data["finalized"])
|
_finalized = bool(data["finalized"])
|
||||||
_guide_visible = bool(data["guide_visible"]) and not _finalized
|
_guide_visible = bool(data["guide_visible"]) and not _finalized
|
||||||
if _finalized:
|
if _finalized:
|
||||||
_destroy_grid()
|
_destroy_grid()
|
||||||
|
_cell_surface_transforms.clear()
|
||||||
|
_build_finalized_pixel_renderer()
|
||||||
else:
|
else:
|
||||||
_refresh_grid_visibility()
|
_refresh_grid_visibility()
|
||||||
|
_configure_render_distance()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -155,11 +187,7 @@ func get_rendered_pixel_size() -> float:
|
||||||
func get_rendered_pixel_count() -> int:
|
func get_rendered_pixel_count() -> int:
|
||||||
if is_hidden_by_relationship():
|
if is_hidden_by_relationship():
|
||||||
return 0
|
return 0
|
||||||
var count: int = 0
|
return _cell_buffer.get_painted_count() if _cell_buffer != null else 0
|
||||||
for cell: Dictionary in _cells.values():
|
|
||||||
if not _visible_cell_color(cell).is_equal_approx(Color.TRANSPARENT):
|
|
||||||
count += 1
|
|
||||||
return count
|
|
||||||
|
|
||||||
|
|
||||||
func get_export_image() -> Image:
|
func get_export_image() -> Image:
|
||||||
|
|
@ -255,18 +283,10 @@ func get_cell_surface_transform(
|
||||||
|
|
||||||
|
|
||||||
func get_authoritative_cells() -> Array[Dictionary]:
|
func get_authoritative_cells() -> Array[Dictionary]:
|
||||||
var result: Array[Dictionary] = []
|
return _cell_buffer.to_cells() if _cell_buffer != null else []
|
||||||
for value: Dictionary in _cells.values():
|
|
||||||
result.append(value.duplicate(true))
|
|
||||||
result.sort_custom(func(a: Dictionary, b: Dictionary) -> bool:
|
|
||||||
var a_key: int = _cell_key(int(a["x"]), int(a["y"]))
|
|
||||||
var b_key: int = _cell_key(int(b["x"]), int(b["y"]))
|
|
||||||
return a_key < b_key
|
|
||||||
)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
func _build_grid() -> void:
|
func _build_grid(samples: Dictionary) -> void:
|
||||||
if _grid_instance != null:
|
if _grid_instance != null:
|
||||||
_grid_instance.queue_free()
|
_grid_instance.queue_free()
|
||||||
_grid_instance = null
|
_grid_instance = null
|
||||||
|
|
@ -279,50 +299,14 @@ func _build_grid() -> void:
|
||||||
material.albedo_color = Color(0.75, 0.94, 0.96, 0.38)
|
material.albedo_color = Color(0.75, 0.94, 0.96, 0.38)
|
||||||
material.no_depth_test = false
|
material.no_depth_test = false
|
||||||
immediate.surface_begin(Mesh.PRIMITIVE_LINES, material)
|
immediate.surface_begin(Mesh.PRIMITIVE_LINES, material)
|
||||||
var half_width: float = float(grid_width) * cell_size * 0.5
|
|
||||||
var half_height: float = float(grid_height) * cell_size * 0.5
|
|
||||||
var sampled_vertices: Dictionary[Vector2i, Dictionary] = {}
|
|
||||||
for x: int in range(grid_width + 1):
|
for x: int in range(grid_width + 1):
|
||||||
var horizontal: float = -half_width + float(x) * cell_size
|
|
||||||
for y_segment: int in range(grid_height):
|
for y_segment: int in range(grid_height):
|
||||||
var start_vertical: float = (
|
_add_grid_vertex(immediate, x, y_segment, samples)
|
||||||
-half_height + float(y_segment) * cell_size
|
_add_grid_vertex(immediate, x, y_segment + 1, samples)
|
||||||
)
|
|
||||||
_add_grid_vertex(
|
|
||||||
immediate,
|
|
||||||
_surface_origin + _surface_tangent * horizontal
|
|
||||||
+ _surface_bitangent * start_vertical,
|
|
||||||
Vector2i(x, y_segment),
|
|
||||||
sampled_vertices,
|
|
||||||
)
|
|
||||||
_add_grid_vertex(
|
|
||||||
immediate,
|
|
||||||
_surface_origin + _surface_tangent * horizontal
|
|
||||||
+ _surface_bitangent * (start_vertical + cell_size),
|
|
||||||
Vector2i(x, y_segment + 1),
|
|
||||||
sampled_vertices,
|
|
||||||
)
|
|
||||||
for y: int in range(grid_height + 1):
|
for y: int in range(grid_height + 1):
|
||||||
var vertical: float = -half_height + float(y) * cell_size
|
|
||||||
for x_segment: int in range(grid_width):
|
for x_segment: int in range(grid_width):
|
||||||
var start_horizontal: float = (
|
_add_grid_vertex(immediate, x_segment, y, samples)
|
||||||
-half_width + float(x_segment) * cell_size
|
_add_grid_vertex(immediate, x_segment + 1, y, samples)
|
||||||
)
|
|
||||||
_add_grid_vertex(
|
|
||||||
immediate,
|
|
||||||
_surface_origin + _surface_tangent * start_horizontal
|
|
||||||
+ _surface_bitangent * vertical,
|
|
||||||
Vector2i(x_segment, y),
|
|
||||||
sampled_vertices,
|
|
||||||
)
|
|
||||||
_add_grid_vertex(
|
|
||||||
immediate,
|
|
||||||
_surface_origin
|
|
||||||
+ _surface_tangent * (start_horizontal + cell_size)
|
|
||||||
+ _surface_bitangent * vertical,
|
|
||||||
Vector2i(x_segment + 1, y),
|
|
||||||
sampled_vertices,
|
|
||||||
)
|
|
||||||
immediate.surface_end()
|
immediate.surface_end()
|
||||||
_grid_instance = MeshInstance3D.new()
|
_grid_instance = MeshInstance3D.new()
|
||||||
_grid_instance.name = "PixelGrid"
|
_grid_instance.name = "PixelGrid"
|
||||||
|
|
@ -334,63 +318,56 @@ func _build_grid() -> void:
|
||||||
|
|
||||||
func _add_grid_vertex(
|
func _add_grid_vertex(
|
||||||
immediate: ImmediateMesh,
|
immediate: ImmediateMesh,
|
||||||
world_point: Vector3,
|
x: int,
|
||||||
grid_point: Vector2i,
|
y: int,
|
||||||
sampled_vertices: Dictionary[Vector2i, Dictionary],
|
samples: Dictionary,
|
||||||
) -> void:
|
) -> void:
|
||||||
var sampled: Dictionary = sampled_vertices.get(grid_point, {})
|
|
||||||
if sampled.is_empty():
|
|
||||||
sampled = _sample_surface(world_point)
|
|
||||||
sampled_vertices[grid_point] = sampled
|
|
||||||
var point: Vector3 = sampled["position"]
|
|
||||||
var normal: Vector3 = sampled["normal"]
|
|
||||||
immediate.surface_add_vertex(
|
immediate.surface_add_vertex(
|
||||||
to_local(point + normal * (_surface_offset() * 1.5))
|
_sample_position(samples, x, y, _surface_offset() * 1.5)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func _build_pixel_renderer() -> void:
|
func _build_pixel_renderer(samples: Dictionary) -> void:
|
||||||
if _pixel_instance != null:
|
if _pixel_instance != null:
|
||||||
_pixel_instance.queue_free()
|
_pixel_instance.queue_free()
|
||||||
_pixel_instance = null
|
_pixel_instance = null
|
||||||
|
var vertex_width: int = grid_width + 1
|
||||||
|
var vertex_count: int = vertex_width * (grid_height + 1)
|
||||||
var cell_count: int = grid_width * grid_height
|
var cell_count: int = grid_width * grid_height
|
||||||
var vertices := PackedVector3Array()
|
var vertices := PackedVector3Array()
|
||||||
var texture_coordinates := PackedVector2Array()
|
var texture_coordinates := PackedVector2Array()
|
||||||
var indices := PackedInt32Array()
|
var indices := PackedInt32Array()
|
||||||
vertices.resize(cell_count * 4)
|
vertices.resize(vertex_count)
|
||||||
texture_coordinates.resize(cell_count * 4)
|
texture_coordinates.resize(vertex_count)
|
||||||
indices.resize(cell_count * 6)
|
indices.resize(cell_count * 6)
|
||||||
_cell_surface_transforms.clear()
|
_cell_surface_transforms.clear()
|
||||||
|
if not _finalized:
|
||||||
_cell_surface_transforms.resize(cell_count)
|
_cell_surface_transforms.resize(cell_count)
|
||||||
|
for y: int in range(grid_height + 1):
|
||||||
|
for x: int in range(grid_width + 1):
|
||||||
|
var vertex_index: int = y * vertex_width + x
|
||||||
|
vertices[vertex_index] = _sample_position(
|
||||||
|
samples, x, y, _surface_offset()
|
||||||
|
)
|
||||||
|
texture_coordinates[vertex_index] = Vector2(
|
||||||
|
float(x) / float(grid_width),
|
||||||
|
1.0 - float(y) / float(grid_height),
|
||||||
|
)
|
||||||
for y: int in range(grid_height):
|
for y: int in range(grid_height):
|
||||||
for x: int in range(grid_width):
|
for x: int in range(grid_width):
|
||||||
var cell_index: int = _cell_key(x, y)
|
var cell_index: int = _cell_key(x, y)
|
||||||
var surface_transform := _sample_cell_transform(x, y, 1.0)
|
if not _finalized:
|
||||||
_cell_surface_transforms[cell_index] = surface_transform
|
_cell_surface_transforms[cell_index] = _transform_from_samples(
|
||||||
var center: Vector3 = surface_transform.origin
|
samples, x, y
|
||||||
var horizontal: Vector3 = surface_transform.basis.x * 0.5
|
)
|
||||||
var vertical: Vector3 = surface_transform.basis.y * 0.5
|
var vertex_offset: int = y * vertex_width + x
|
||||||
var vertex_offset: int = cell_index * 4
|
|
||||||
vertices[vertex_offset] = center - horizontal - vertical
|
|
||||||
vertices[vertex_offset + 1] = center + horizontal - vertical
|
|
||||||
vertices[vertex_offset + 2] = center + horizontal + vertical
|
|
||||||
vertices[vertex_offset + 3] = center - horizontal + vertical
|
|
||||||
var image_row: int = _image_y(y)
|
|
||||||
var u_min: float = float(x) / float(grid_width)
|
|
||||||
var u_max: float = float(x + 1) / float(grid_width)
|
|
||||||
var v_min: float = float(image_row) / float(grid_height)
|
|
||||||
var v_max: float = float(image_row + 1) / float(grid_height)
|
|
||||||
texture_coordinates[vertex_offset] = Vector2(u_min, v_max)
|
|
||||||
texture_coordinates[vertex_offset + 1] = Vector2(u_max, v_max)
|
|
||||||
texture_coordinates[vertex_offset + 2] = Vector2(u_max, v_min)
|
|
||||||
texture_coordinates[vertex_offset + 3] = Vector2(u_min, v_min)
|
|
||||||
var index_offset: int = cell_index * 6
|
var index_offset: int = cell_index * 6
|
||||||
indices[index_offset] = vertex_offset
|
indices[index_offset] = vertex_offset
|
||||||
indices[index_offset + 1] = vertex_offset + 1
|
indices[index_offset + 1] = vertex_offset + 1
|
||||||
indices[index_offset + 2] = vertex_offset + 2
|
indices[index_offset + 2] = vertex_offset + vertex_width + 1
|
||||||
indices[index_offset + 3] = vertex_offset
|
indices[index_offset + 3] = vertex_offset
|
||||||
indices[index_offset + 4] = vertex_offset + 2
|
indices[index_offset + 4] = vertex_offset + vertex_width + 1
|
||||||
indices[index_offset + 5] = vertex_offset + 3
|
indices[index_offset + 5] = vertex_offset + vertex_width
|
||||||
_rebuild_pixel_image()
|
_rebuild_pixel_image()
|
||||||
var arrays: Array = []
|
var arrays: Array = []
|
||||||
arrays.resize(Mesh.ARRAY_MAX)
|
arrays.resize(Mesh.ARRAY_MAX)
|
||||||
|
|
@ -414,21 +391,103 @@ func _build_pixel_renderer() -> void:
|
||||||
_pixel_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
_pixel_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||||
add_child(_pixel_instance)
|
add_child(_pixel_instance)
|
||||||
_pixel_instance.visible = not is_hidden_by_relationship()
|
_pixel_instance.visible = not is_hidden_by_relationship()
|
||||||
|
_configure_render_distance()
|
||||||
|
|
||||||
|
|
||||||
|
func _build_finalized_pixel_renderer() -> void:
|
||||||
|
if _pixel_instance != null:
|
||||||
|
_pixel_instance.queue_free()
|
||||||
|
_pixel_instance = null
|
||||||
|
var step: int = maxi(
|
||||||
|
1,
|
||||||
|
ceili(float(grid_width) / float(FINALIZED_MAX_SUBDIVISIONS)),
|
||||||
|
)
|
||||||
|
var coordinates := PackedInt32Array()
|
||||||
|
var coordinate: int = 0
|
||||||
|
while coordinate < grid_width:
|
||||||
|
coordinates.append(coordinate)
|
||||||
|
coordinate += step
|
||||||
|
if coordinates.is_empty() or coordinates[-1] != grid_width:
|
||||||
|
coordinates.append(grid_width)
|
||||||
|
var vertex_width: int = coordinates.size()
|
||||||
|
var vertices := PackedVector3Array()
|
||||||
|
var texture_coordinates := PackedVector2Array()
|
||||||
|
var indices := PackedInt32Array()
|
||||||
|
vertices.resize(vertex_width * vertex_width)
|
||||||
|
texture_coordinates.resize(vertex_width * vertex_width)
|
||||||
|
indices.resize((vertex_width - 1) * (vertex_width - 1) * 6)
|
||||||
|
var half_width: float = float(grid_width) * cell_size * 0.5
|
||||||
|
var half_height: float = float(grid_height) * cell_size * 0.5
|
||||||
|
for lattice_y: int in vertex_width:
|
||||||
|
var cell_y: int = coordinates[lattice_y]
|
||||||
|
var vertical: float = -half_height + float(cell_y) * cell_size
|
||||||
|
for lattice_x: int in vertex_width:
|
||||||
|
var cell_x: int = coordinates[lattice_x]
|
||||||
|
var horizontal: float = -half_width + float(cell_x) * cell_size
|
||||||
|
var expected: Vector3 = (
|
||||||
|
_surface_origin
|
||||||
|
+ _surface_tangent * horizontal
|
||||||
|
+ _surface_bitangent * vertical
|
||||||
|
)
|
||||||
|
var sampled: Dictionary = _sample_surface(expected)
|
||||||
|
var vertex_index: int = lattice_y * vertex_width + lattice_x
|
||||||
|
var point: Vector3 = sampled["position"]
|
||||||
|
var normal: Vector3 = sampled["normal"]
|
||||||
|
vertices[vertex_index] = to_local(
|
||||||
|
point + normal * _surface_offset()
|
||||||
|
)
|
||||||
|
texture_coordinates[vertex_index] = Vector2(
|
||||||
|
float(cell_x) / float(grid_width),
|
||||||
|
1.0 - float(cell_y) / float(grid_height),
|
||||||
|
)
|
||||||
|
for lattice_y: int in range(vertex_width - 1):
|
||||||
|
for lattice_x: int in range(vertex_width - 1):
|
||||||
|
var cell_index: int = lattice_y * (vertex_width - 1) + lattice_x
|
||||||
|
var vertex_offset: int = lattice_y * vertex_width + lattice_x
|
||||||
|
var index_offset: int = cell_index * 6
|
||||||
|
indices[index_offset] = vertex_offset
|
||||||
|
indices[index_offset + 1] = vertex_offset + 1
|
||||||
|
indices[index_offset + 2] = vertex_offset + vertex_width + 1
|
||||||
|
indices[index_offset + 3] = vertex_offset
|
||||||
|
indices[index_offset + 4] = vertex_offset + vertex_width + 1
|
||||||
|
indices[index_offset + 5] = vertex_offset + vertex_width
|
||||||
|
if _pixel_image == null or _pixel_texture == null:
|
||||||
|
_rebuild_pixel_image()
|
||||||
|
var arrays: Array = []
|
||||||
|
arrays.resize(Mesh.ARRAY_MAX)
|
||||||
|
arrays[Mesh.ARRAY_VERTEX] = vertices
|
||||||
|
arrays[Mesh.ARRAY_TEX_UV] = texture_coordinates
|
||||||
|
arrays[Mesh.ARRAY_INDEX] = indices
|
||||||
|
var mesh := ArrayMesh.new()
|
||||||
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
|
||||||
|
var material := StandardMaterial3D.new()
|
||||||
|
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||||
|
material.albedo_color = Color.WHITE
|
||||||
|
material.albedo_texture = _pixel_texture
|
||||||
|
material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_NEAREST
|
||||||
|
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR
|
||||||
|
material.alpha_scissor_threshold = 0.5
|
||||||
|
material.cull_mode = BaseMaterial3D.CULL_DISABLED
|
||||||
|
mesh.surface_set_material(0, material)
|
||||||
|
_pixel_instance = MeshInstance3D.new()
|
||||||
|
_pixel_instance.name = "ArtworkTexture"
|
||||||
|
_pixel_instance.mesh = mesh
|
||||||
|
_pixel_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||||
|
add_child(_pixel_instance)
|
||||||
|
_pixel_instance.visible = not is_hidden_by_relationship()
|
||||||
|
_configure_render_distance()
|
||||||
|
|
||||||
|
|
||||||
func _rebuild_pixel_image() -> void:
|
func _rebuild_pixel_image() -> void:
|
||||||
if (
|
if _cell_buffer == null:
|
||||||
_pixel_image == null
|
return
|
||||||
or _pixel_image.get_width() != grid_width
|
_pixel_image = Image.create_from_data(
|
||||||
or _pixel_image.get_height() != grid_height
|
grid_width,
|
||||||
):
|
grid_height,
|
||||||
_pixel_image = Image.create(
|
false,
|
||||||
grid_width, grid_height, false, Image.FORMAT_RGBA8
|
Image.FORMAT_RGBA8,
|
||||||
|
_cell_buffer.to_rgba8_data(is_hidden_by_relationship()),
|
||||||
)
|
)
|
||||||
_pixel_image.fill(Color.TRANSPARENT)
|
|
||||||
if not is_hidden_by_relationship():
|
|
||||||
for cell: Dictionary in _cells.values():
|
|
||||||
_set_image_cell(int(cell["x"]), int(cell["y"]), cell)
|
|
||||||
if _pixel_texture == null:
|
if _pixel_texture == null:
|
||||||
_pixel_texture = ImageTexture.create_from_image(_pixel_image)
|
_pixel_texture = ImageTexture.create_from_image(_pixel_image)
|
||||||
else:
|
else:
|
||||||
|
|
@ -443,7 +502,7 @@ func _apply_pixel_edits(edits: Array) -> void:
|
||||||
var edit: Dictionary = edit_value
|
var edit: Dictionary = edit_value
|
||||||
var x: int = int(edit["x"])
|
var x: int = int(edit["x"])
|
||||||
var y: int = int(edit["y"])
|
var y: int = int(edit["y"])
|
||||||
var cell: Dictionary = _cells.get(_cell_key(x, y), {})
|
var cell: Dictionary = _cell_buffer.get_cell(x, y)
|
||||||
_set_image_cell(x, y, cell)
|
_set_image_cell(x, y, cell)
|
||||||
_pixel_texture.update(_pixel_image)
|
_pixel_texture.update(_pixel_image)
|
||||||
|
|
||||||
|
|
@ -475,6 +534,78 @@ func _image_y(cell_y: int) -> int:
|
||||||
return grid_height - 1 - cell_y
|
return grid_height - 1 - cell_y
|
||||||
|
|
||||||
|
|
||||||
|
func _sample_grid_vertices() -> Dictionary:
|
||||||
|
var vertex_width: int = grid_width + 1
|
||||||
|
var vertex_count: int = vertex_width * (grid_height + 1)
|
||||||
|
var positions := PackedVector3Array()
|
||||||
|
var normals := PackedVector3Array()
|
||||||
|
positions.resize(vertex_count)
|
||||||
|
normals.resize(vertex_count)
|
||||||
|
var half_width: float = float(grid_width) * cell_size * 0.5
|
||||||
|
var half_height: float = float(grid_height) * cell_size * 0.5
|
||||||
|
var inverse_basis: Basis = global_basis.inverse()
|
||||||
|
for y: int in range(grid_height + 1):
|
||||||
|
var vertical: float = -half_height + float(y) * cell_size
|
||||||
|
for x: int in range(grid_width + 1):
|
||||||
|
var horizontal: float = -half_width + float(x) * cell_size
|
||||||
|
var expected: Vector3 = (
|
||||||
|
_surface_origin
|
||||||
|
+ _surface_tangent * horizontal
|
||||||
|
+ _surface_bitangent * vertical
|
||||||
|
)
|
||||||
|
var sampled: Dictionary = _sample_surface(expected)
|
||||||
|
var index: int = y * vertex_width + x
|
||||||
|
positions[index] = to_local(sampled["position"])
|
||||||
|
normals[index] = (
|
||||||
|
inverse_basis * (sampled["normal"] as Vector3)
|
||||||
|
).normalized()
|
||||||
|
return {"positions": positions, "normals": normals}
|
||||||
|
|
||||||
|
|
||||||
|
func _sample_position(
|
||||||
|
samples: Dictionary,
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
offset: float,
|
||||||
|
) -> Vector3:
|
||||||
|
var index: int = y * (grid_width + 1) + x
|
||||||
|
var positions: PackedVector3Array = samples["positions"]
|
||||||
|
var normals: PackedVector3Array = samples["normals"]
|
||||||
|
return positions[index] + normals[index] * offset
|
||||||
|
|
||||||
|
|
||||||
|
func _transform_from_samples(
|
||||||
|
samples: Dictionary,
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
) -> Transform3D:
|
||||||
|
var bottom_left: Vector3 = _sample_position(
|
||||||
|
samples, x, y, _surface_offset()
|
||||||
|
)
|
||||||
|
var bottom_right: Vector3 = _sample_position(
|
||||||
|
samples, x + 1, y, _surface_offset()
|
||||||
|
)
|
||||||
|
var top_left: Vector3 = _sample_position(
|
||||||
|
samples, x, y + 1, _surface_offset()
|
||||||
|
)
|
||||||
|
var top_right: Vector3 = _sample_position(
|
||||||
|
samples, x + 1, y + 1, _surface_offset()
|
||||||
|
)
|
||||||
|
var horizontal: Vector3 = (
|
||||||
|
(bottom_right - bottom_left) + (top_right - top_left)
|
||||||
|
) * 0.5
|
||||||
|
var vertical: Vector3 = (
|
||||||
|
(top_left - bottom_left) + (top_right - bottom_right)
|
||||||
|
) * 0.5
|
||||||
|
var normal: Vector3 = horizontal.cross(vertical).normalized()
|
||||||
|
if horizontal.is_zero_approx() or vertical.is_zero_approx() or normal.is_zero_approx():
|
||||||
|
return _sample_cell_transform(x, y, 1.0)
|
||||||
|
var center: Vector3 = (
|
||||||
|
bottom_left + bottom_right + top_left + top_right
|
||||||
|
) * 0.25
|
||||||
|
return Transform3D(Basis(horizontal, vertical, normal), center)
|
||||||
|
|
||||||
|
|
||||||
func _sample_cell_transform(
|
func _sample_cell_transform(
|
||||||
x: int,
|
x: int,
|
||||||
y: int,
|
y: int,
|
||||||
|
|
@ -549,6 +680,17 @@ func _refresh_grid_visibility() -> void:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _configure_render_distance() -> void:
|
||||||
|
if _pixel_instance == null:
|
||||||
|
return
|
||||||
|
_pixel_instance.visibility_range_end = (
|
||||||
|
FINALIZED_VISIBILITY_RANGE if _finalized else 0.0
|
||||||
|
)
|
||||||
|
_pixel_instance.visibility_range_end_margin = (
|
||||||
|
FINALIZED_VISIBILITY_MARGIN if _finalized else 0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _participants_from_state(data: Dictionary) -> Array[String]:
|
func _participants_from_state(data: Dictionary) -> Array[String]:
|
||||||
var result: Array[String] = []
|
var result: Array[String] = []
|
||||||
_append_participant(result, str(data.get("creator_fingerprint", "")))
|
_append_participant(result, str(data.get("creator_fingerprint", "")))
|
||||||
|
|
|
||||||
284
drawing/surface_drawing_cell_buffer.gd
Normal file
|
|
@ -0,0 +1,284 @@
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
class_name SurfaceDrawingCellBuffer
|
||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
const ENCODING := "palette_author_planes_v1"
|
||||||
|
|
||||||
|
var width: int = 0
|
||||||
|
var height: int = 0
|
||||||
|
|
||||||
|
var _color_indices := PackedByteArray()
|
||||||
|
var _author_indices := PackedInt32Array()
|
||||||
|
var _participants: Array[String] = []
|
||||||
|
var _participant_slots: Dictionary[String, int] = {}
|
||||||
|
var _author_masks: Dictionary[int, PackedByteArray] = {}
|
||||||
|
var _painted_count: int = 0
|
||||||
|
|
||||||
|
|
||||||
|
func configure_from_state(
|
||||||
|
data: Dictionary,
|
||||||
|
already_validated: bool = false,
|
||||||
|
) -> bool:
|
||||||
|
if not already_validated and not SurfaceDrawingProtocol.validate_canvas_state(data):
|
||||||
|
return false
|
||||||
|
width = int(data["width"])
|
||||||
|
height = int(data["height"])
|
||||||
|
_reset_planes()
|
||||||
|
for value: Variant in data.get("participant_fingerprints", []):
|
||||||
|
_add_participant(str(value))
|
||||||
|
_add_participant(str(data.get("creator_fingerprint", "")))
|
||||||
|
if str(data.get("cell_encoding", "")) == ENCODING:
|
||||||
|
return _configure_packed(
|
||||||
|
data.get("cell_colors", PackedByteArray()),
|
||||||
|
data.get("cell_authors", PackedInt32Array()),
|
||||||
|
)
|
||||||
|
for value: Variant in data.get("cells", []):
|
||||||
|
if typeof(value) != TYPE_DICTIONARY or not _apply_edit(value):
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func apply_edits(edits: Array) -> bool:
|
||||||
|
for value: Variant in edits:
|
||||||
|
if typeof(value) != TYPE_DICTIONARY or not _apply_edit(value):
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func ensure_participants(values: Array) -> bool:
|
||||||
|
for value: Variant in values:
|
||||||
|
if _add_participant(str(value)) <= 0:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func get_cell(x: int, y: int) -> Dictionary:
|
||||||
|
var key: int = _key(x, y)
|
||||||
|
if key < 0 or _color_indices[key] == 0:
|
||||||
|
return {}
|
||||||
|
var author_slot: int = _author_indices[key]
|
||||||
|
return {
|
||||||
|
"x": x,
|
||||||
|
"y": y,
|
||||||
|
"color_id": str(
|
||||||
|
SurfaceDrawingPalette.id_for_palette_index(_color_indices[key])
|
||||||
|
),
|
||||||
|
"author_fingerprint": (
|
||||||
|
_participants[author_slot - 1]
|
||||||
|
if author_slot > 0 and author_slot <= _participants.size()
|
||||||
|
else ""
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func get_cell_value(x: int, y: int) -> Dictionary:
|
||||||
|
var cell: Dictionary = get_cell(x, y)
|
||||||
|
if cell.is_empty():
|
||||||
|
return {}
|
||||||
|
return {
|
||||||
|
"color_id": cell["color_id"],
|
||||||
|
"author_fingerprint": cell["author_fingerprint"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func get_painted_count() -> int:
|
||||||
|
return _painted_count
|
||||||
|
|
||||||
|
|
||||||
|
func get_participants() -> Array[String]:
|
||||||
|
return _participants.duplicate()
|
||||||
|
|
||||||
|
|
||||||
|
func get_author_cell_keys(fingerprint: String) -> PackedInt32Array:
|
||||||
|
var slot: int = int(_participant_slots.get(fingerprint, 0))
|
||||||
|
var mask: PackedByteArray = _author_masks.get(slot, PackedByteArray())
|
||||||
|
var result := PackedInt32Array()
|
||||||
|
if slot <= 0 or mask.is_empty():
|
||||||
|
return result
|
||||||
|
for key: int in width * height:
|
||||||
|
if _mask_has(mask, key):
|
||||||
|
result.append(key)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
func to_cells() -> Array[Dictionary]:
|
||||||
|
var result: Array[Dictionary] = []
|
||||||
|
for key: int in width * height:
|
||||||
|
if _color_indices[key] == 0:
|
||||||
|
continue
|
||||||
|
result.append(get_cell(key % width, floori(float(key) / float(width))))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
func to_compact_fields() -> Dictionary:
|
||||||
|
return {
|
||||||
|
"cell_encoding": ENCODING,
|
||||||
|
"cell_colors": _color_indices.duplicate(),
|
||||||
|
"cell_authors": _author_indices.duplicate(),
|
||||||
|
"participant_fingerprints": get_participants(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func to_rgba8_data(hidden: bool = false) -> PackedByteArray:
|
||||||
|
var result := PackedByteArray()
|
||||||
|
result.resize(width * height * 4)
|
||||||
|
# Match Image.fill(Color.TRANSPARENT): transparent texels retain white RGB,
|
||||||
|
# preventing dark fringes if filtering is ever changed by a platform driver.
|
||||||
|
for pixel_index: int in width * height:
|
||||||
|
var offset: int = pixel_index * 4
|
||||||
|
result[offset] = 255
|
||||||
|
result[offset + 1] = 255
|
||||||
|
result[offset + 2] = 255
|
||||||
|
if hidden:
|
||||||
|
return result
|
||||||
|
for key: int in width * height:
|
||||||
|
var palette_index: int = _color_indices[key]
|
||||||
|
if palette_index == 0:
|
||||||
|
continue
|
||||||
|
var x: int = key % width
|
||||||
|
var y: int = floori(float(key) / float(width))
|
||||||
|
var image_key: int = (height - 1 - y) * width + x
|
||||||
|
var offset: int = image_key * 4
|
||||||
|
var color: Color = SurfaceDrawingPalette.color_for_palette_index(
|
||||||
|
palette_index
|
||||||
|
)
|
||||||
|
result[offset] = roundi(color.r * 255.0)
|
||||||
|
result[offset + 1] = roundi(color.g * 255.0)
|
||||||
|
result[offset + 2] = roundi(color.b * 255.0)
|
||||||
|
result[offset + 3] = roundi(color.a * 255.0)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
func estimated_storage_bytes() -> int:
|
||||||
|
var masks_size: int = 0
|
||||||
|
for mask: PackedByteArray in _author_masks.values():
|
||||||
|
masks_size += mask.size()
|
||||||
|
return _color_indices.size() + _author_indices.size() * 4 + masks_size
|
||||||
|
|
||||||
|
|
||||||
|
func _configure_packed(colors: Variant, authors: Variant) -> bool:
|
||||||
|
if (
|
||||||
|
typeof(colors) != TYPE_PACKED_BYTE_ARRAY
|
||||||
|
or typeof(authors) != TYPE_PACKED_INT32_ARRAY
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
var packed_colors: PackedByteArray = colors
|
||||||
|
var packed_authors: PackedInt32Array = authors
|
||||||
|
if (
|
||||||
|
packed_colors.size() != width * height
|
||||||
|
or packed_authors.size() != width * height
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
_color_indices = packed_colors.duplicate()
|
||||||
|
_author_indices = packed_authors.duplicate()
|
||||||
|
_painted_count = 0
|
||||||
|
for key: int in width * height:
|
||||||
|
var color_index: int = _color_indices[key]
|
||||||
|
var author_slot: int = _author_indices[key]
|
||||||
|
if color_index == 0:
|
||||||
|
if author_slot != 0:
|
||||||
|
return false
|
||||||
|
continue
|
||||||
|
if (
|
||||||
|
color_index > SurfaceDrawingPalette.COLORS.size()
|
||||||
|
or author_slot <= 0
|
||||||
|
or author_slot > _participants.size()
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
_painted_count += 1
|
||||||
|
_set_author_mask_bit(author_slot, key, true)
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func _apply_edit(value: Dictionary) -> bool:
|
||||||
|
var x: int = int(value.get("x", -1))
|
||||||
|
var y: int = int(value.get("y", -1))
|
||||||
|
var key: int = _key(x, y)
|
||||||
|
if key < 0:
|
||||||
|
return false
|
||||||
|
var color_id := StringName(str(value.get("color_id", "")))
|
||||||
|
var next_color_index: int = (
|
||||||
|
SurfaceDrawingPalette.palette_index_for_id(color_id)
|
||||||
|
if not color_id.is_empty()
|
||||||
|
else 0
|
||||||
|
)
|
||||||
|
if not color_id.is_empty() and next_color_index <= 0:
|
||||||
|
return false
|
||||||
|
var next_author_slot: int = 0
|
||||||
|
if next_color_index > 0:
|
||||||
|
next_author_slot = _add_participant(
|
||||||
|
str(value.get("author_fingerprint", ""))
|
||||||
|
)
|
||||||
|
if next_author_slot <= 0:
|
||||||
|
return false
|
||||||
|
var previous_color_index: int = _color_indices[key]
|
||||||
|
var previous_author_slot: int = _author_indices[key]
|
||||||
|
if previous_color_index == next_color_index and previous_author_slot == next_author_slot:
|
||||||
|
return true
|
||||||
|
if previous_author_slot > 0:
|
||||||
|
_set_author_mask_bit(previous_author_slot, key, false)
|
||||||
|
if previous_color_index == 0 and next_color_index > 0:
|
||||||
|
_painted_count += 1
|
||||||
|
elif previous_color_index > 0 and next_color_index == 0:
|
||||||
|
_painted_count -= 1
|
||||||
|
_color_indices[key] = next_color_index
|
||||||
|
_author_indices[key] = next_author_slot
|
||||||
|
if next_author_slot > 0:
|
||||||
|
_set_author_mask_bit(next_author_slot, key, true)
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func _reset_planes() -> void:
|
||||||
|
_color_indices.resize(width * height)
|
||||||
|
_color_indices.fill(0)
|
||||||
|
_author_indices.resize(width * height)
|
||||||
|
_author_indices.fill(0)
|
||||||
|
_participants.clear()
|
||||||
|
_participant_slots.clear()
|
||||||
|
_author_masks.clear()
|
||||||
|
_painted_count = 0
|
||||||
|
|
||||||
|
|
||||||
|
func _add_participant(fingerprint: String) -> int:
|
||||||
|
var existing: int = int(_participant_slots.get(fingerprint, 0))
|
||||||
|
if existing > 0:
|
||||||
|
return existing
|
||||||
|
if not NetworkIdentityCrypto.valid_fingerprint(fingerprint):
|
||||||
|
return 0
|
||||||
|
if _participants.size() >= SurfaceDrawingProtocol.MAX_PARTICIPANTS:
|
||||||
|
return 0
|
||||||
|
_participants.append(fingerprint)
|
||||||
|
var slot: int = _participants.size()
|
||||||
|
_participant_slots[fingerprint] = slot
|
||||||
|
return slot
|
||||||
|
|
||||||
|
|
||||||
|
func _set_author_mask_bit(slot: int, key: int, enabled: bool) -> void:
|
||||||
|
if slot <= 0 or key < 0:
|
||||||
|
return
|
||||||
|
var mask: PackedByteArray = _author_masks.get(slot, PackedByteArray())
|
||||||
|
var required_size: int = ceili(float(width * height) / 8.0)
|
||||||
|
if mask.size() != required_size:
|
||||||
|
mask.resize(required_size)
|
||||||
|
var byte_index: int = floori(float(key) / 8.0)
|
||||||
|
var bit: int = 1 << (key % 8)
|
||||||
|
if enabled:
|
||||||
|
mask[byte_index] = mask[byte_index] | bit
|
||||||
|
else:
|
||||||
|
mask[byte_index] = mask[byte_index] & (~bit & 0xff)
|
||||||
|
_author_masks[slot] = mask
|
||||||
|
|
||||||
|
|
||||||
|
func _mask_has(mask: PackedByteArray, key: int) -> bool:
|
||||||
|
var byte_index: int = floori(float(key) / 8.0)
|
||||||
|
return (
|
||||||
|
byte_index >= 0
|
||||||
|
and byte_index < mask.size()
|
||||||
|
and (mask[byte_index] & (1 << (key % 8))) != 0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _key(x: int, y: int) -> int:
|
||||||
|
if x < 0 or x >= width or y < 0 or y >= height:
|
||||||
|
return -1
|
||||||
|
return y * width + x
|
||||||
1
drawing/surface_drawing_cell_buffer.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b4clw478edbnk
|
||||||
|
|
@ -45,6 +45,31 @@ static func get_color_ids() -> Array[StringName]:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
static func palette_index_for_id(color_id: StringName) -> int:
|
||||||
|
for index: int in COLORS.size():
|
||||||
|
if StringName(COLORS[index].get("id", &"")) == color_id:
|
||||||
|
return index + 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
static func id_for_palette_index(palette_index: int) -> StringName:
|
||||||
|
var index: int = palette_index - 1
|
||||||
|
return (
|
||||||
|
StringName(COLORS[index].get("id", &""))
|
||||||
|
if index >= 0 and index < COLORS.size()
|
||||||
|
else StringName()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
static func color_for_palette_index(palette_index: int) -> Color:
|
||||||
|
var index: int = palette_index - 1
|
||||||
|
return (
|
||||||
|
COLORS[index].get("color", Color.TRANSPARENT)
|
||||||
|
if index >= 0 and index < COLORS.size()
|
||||||
|
else Color.TRANSPARENT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
static func filter_unlocked_ids(
|
static func filter_unlocked_ids(
|
||||||
unlocked_ids: Array[StringName],
|
unlocked_ids: Array[StringName],
|
||||||
) -> Array[StringName]:
|
) -> Array[StringName]:
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ static func resolve(
|
||||||
}
|
}
|
||||||
var nearest_distance: float = SNAP_DISTANCE
|
var nearest_distance: float = SNAP_DISTANCE
|
||||||
for state: Dictionary in canvas_states:
|
for state: Dictionary in canvas_states:
|
||||||
if not SurfaceDrawingProtocol.validate_canvas_state(state):
|
if not SurfaceDrawingProtocol.validate_canvas_metadata(state):
|
||||||
continue
|
continue
|
||||||
var anchor_normal: Vector3 = SurfaceDrawingProtocol.array_to_vector(
|
var anchor_normal: Vector3 = SurfaceDrawingProtocol.array_to_vector(
|
||||||
state["normal"]
|
state["normal"]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
class_name SurfaceDrawingProtocol
|
class_name SurfaceDrawingProtocol
|
||||||
extends RefCounted
|
extends RefCounted
|
||||||
|
|
||||||
const CAPABILITY: StringName = &"surface_drawing_v2"
|
const CAPABILITY: StringName = &"surface_drawing_v3"
|
||||||
const RELIABLE_CHANNEL: int = NetworkProtocol.DRAWING_RELIABLE_CHANNEL
|
const RELIABLE_CHANNEL: int = NetworkProtocol.DRAWING_RELIABLE_CHANNEL
|
||||||
const GRID_SIZES: Array[int] = [16, 32, 64, 128]
|
const GRID_SIZES: Array[int] = [16, 32, 64, 128]
|
||||||
const DEFAULT_GRID_SIZE: int = 16
|
const DEFAULT_GRID_SIZE: int = 16
|
||||||
|
|
@ -11,8 +11,12 @@ const GRID_WIDTH: int = DEFAULT_GRID_SIZE
|
||||||
const GRID_HEIGHT: int = DEFAULT_GRID_SIZE
|
const GRID_HEIGHT: int = DEFAULT_GRID_SIZE
|
||||||
const CELL_SIZE: float = 0.075
|
const CELL_SIZE: float = 0.075
|
||||||
const MAX_ACTIVE_CANVASES: int = 24
|
const MAX_ACTIVE_CANVASES: int = 24
|
||||||
const MAX_CANVASES: int = 48
|
const MAX_FINALIZED_CANVASES: int = 512
|
||||||
const MAX_SESSION_GRID_CELLS: int = 49152
|
const MAX_CANVASES: int = MAX_ACTIVE_CANVASES + MAX_FINALIZED_CANVASES
|
||||||
|
const MAX_ACTIVE_GRID_CELLS: int = 49152
|
||||||
|
const MAX_FINALIZED_GRID_CELLS: int = 8 * 1024 * 1024
|
||||||
|
# Compatibility alias for code concerned only with live editing capacity.
|
||||||
|
const MAX_SESSION_GRID_CELLS: int = MAX_ACTIVE_GRID_CELLS
|
||||||
const MAX_EDITS_PER_REQUEST: int = 16
|
const MAX_EDITS_PER_REQUEST: int = 16
|
||||||
const MAX_CANVAS_ID_LENGTH: int = 64
|
const MAX_CANVAS_ID_LENGTH: int = 64
|
||||||
const MAX_REQUEST_ID_LENGTH: int = 64
|
const MAX_REQUEST_ID_LENGTH: int = 64
|
||||||
|
|
@ -22,6 +26,7 @@ const MAX_SESSION_ID_LENGTH: int = 96
|
||||||
# for a complete room turnover while never accepting unattributed edits.
|
# for a complete room turnover while never accepting unattributed edits.
|
||||||
const MAX_PARTICIPANTS: int = 256
|
const MAX_PARTICIPANTS: int = 256
|
||||||
const MAX_COORDINATE: float = 10000.0
|
const MAX_COORDINATE: float = 10000.0
|
||||||
|
const CELL_ENCODING := "palette_author_planes_v1"
|
||||||
|
|
||||||
|
|
||||||
static func validate_canvas_request(data: Variant) -> bool:
|
static func validate_canvas_request(data: Variant) -> bool:
|
||||||
|
|
@ -122,37 +127,12 @@ static func validate_canvas_state(data: Variant) -> bool:
|
||||||
if typeof(data) != TYPE_DICTIONARY:
|
if typeof(data) != TYPE_DICTIONARY:
|
||||||
return false
|
return false
|
||||||
var value: Dictionary = data
|
var value: Dictionary = data
|
||||||
if (
|
if not validate_canvas_metadata(value):
|
||||||
typeof(value.get("session_id")) != TYPE_STRING
|
|
||||||
or str(value["session_id"]).is_empty()
|
|
||||||
or str(value["session_id"]).length() > MAX_SESSION_ID_LENGTH
|
|
||||||
or typeof(value.get("canvas_id")) != TYPE_STRING
|
|
||||||
or str(value["canvas_id"]).is_empty()
|
|
||||||
or str(value["canvas_id"]).length() > MAX_CANVAS_ID_LENGTH
|
|
||||||
or not _valid_vector(value.get("origin"))
|
|
||||||
or not _valid_vector(value.get("normal"))
|
|
||||||
or not _valid_vector(value.get("tangent"))
|
|
||||||
or typeof(value.get("width")) != TYPE_INT
|
|
||||||
or int(value["width"]) not in GRID_SIZES
|
|
||||||
or typeof(value.get("height")) != TYPE_INT
|
|
||||||
or int(value["height"]) != int(value["width"])
|
|
||||||
or typeof(value.get("cell_size")) not in [TYPE_FLOAT, TYPE_INT]
|
|
||||||
or not is_equal_approx(float(value["cell_size"]), CELL_SIZE)
|
|
||||||
or typeof(value.get("revision")) != TYPE_INT
|
|
||||||
or int(value["revision"]) < 0
|
|
||||||
or typeof(value.get("guide_visible", true)) != TYPE_BOOL
|
|
||||||
or typeof(value.get("finalized", false)) != TYPE_BOOL
|
|
||||||
or typeof(value.get("layer", 0)) != TYPE_INT
|
|
||||||
or int(value.get("layer", 0)) < 0
|
|
||||||
or not NetworkIdentityCrypto.valid_fingerprint(
|
|
||||||
value.get("creator_fingerprint")
|
|
||||||
)
|
|
||||||
or not _valid_participant_fingerprints(
|
|
||||||
value.get("participant_fingerprints", [])
|
|
||||||
)
|
|
||||||
or typeof(value.get("cells")) != TYPE_ARRAY
|
|
||||||
):
|
|
||||||
return false
|
return false
|
||||||
|
var participants: Array = value.get("participant_fingerprints", [])
|
||||||
|
if not participants.is_empty() and str(value["creator_fingerprint"]) not in participants:
|
||||||
|
return false
|
||||||
|
if typeof(value.get("cells")) == TYPE_ARRAY:
|
||||||
var cells: Array = value["cells"]
|
var cells: Array = value["cells"]
|
||||||
var grid_width: int = int(value["width"])
|
var grid_width: int = int(value["width"])
|
||||||
var grid_height: int = int(value["height"])
|
var grid_height: int = int(value["height"])
|
||||||
|
|
@ -165,14 +145,73 @@ static func validate_canvas_state(data: Variant) -> bool:
|
||||||
or int((cell_value as Dictionary)["y"]) >= grid_height
|
or int((cell_value as Dictionary)["y"]) >= grid_height
|
||||||
):
|
):
|
||||||
return false
|
return false
|
||||||
var participants: Array = value.get("participant_fingerprints", [])
|
if (
|
||||||
if not participants.is_empty():
|
not participants.is_empty()
|
||||||
if str(value["creator_fingerprint"]) not in participants:
|
and str((cell_value as Dictionary)["author_fingerprint"])
|
||||||
return false
|
not in participants
|
||||||
for cell_value: Variant in cells:
|
):
|
||||||
if str((cell_value as Dictionary)["author_fingerprint"]) not in participants:
|
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
if (
|
||||||
|
str(value.get("cell_encoding", "")) != CELL_ENCODING
|
||||||
|
or typeof(value.get("cell_colors")) != TYPE_PACKED_BYTE_ARRAY
|
||||||
|
or typeof(value.get("cell_authors")) != TYPE_PACKED_INT32_ARRAY
|
||||||
|
or participants.is_empty()
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
var colors: PackedByteArray = value["cell_colors"]
|
||||||
|
var authors: PackedInt32Array = value["cell_authors"]
|
||||||
|
var expected_size: int = int(value["width"]) * int(value["height"])
|
||||||
|
if colors.size() != expected_size or authors.size() != expected_size:
|
||||||
|
return false
|
||||||
|
for index: int in expected_size:
|
||||||
|
var color_index: int = colors[index]
|
||||||
|
var author_slot: int = authors[index]
|
||||||
|
if color_index == 0:
|
||||||
|
if author_slot != 0:
|
||||||
|
return false
|
||||||
|
elif (
|
||||||
|
color_index > SurfaceDrawingPalette.COLORS.size()
|
||||||
|
or author_slot <= 0
|
||||||
|
or author_slot > participants.size()
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
static func validate_canvas_metadata(data: Variant) -> bool:
|
||||||
|
if typeof(data) != TYPE_DICTIONARY:
|
||||||
|
return false
|
||||||
|
var value: Dictionary = data
|
||||||
|
return (
|
||||||
|
typeof(value.get("session_id")) == TYPE_STRING
|
||||||
|
and not str(value["session_id"]).is_empty()
|
||||||
|
and str(value["session_id"]).length() <= MAX_SESSION_ID_LENGTH
|
||||||
|
and typeof(value.get("canvas_id")) == TYPE_STRING
|
||||||
|
and not str(value["canvas_id"]).is_empty()
|
||||||
|
and str(value["canvas_id"]).length() <= MAX_CANVAS_ID_LENGTH
|
||||||
|
and _valid_vector(value.get("origin"))
|
||||||
|
and _valid_vector(value.get("normal"))
|
||||||
|
and _valid_vector(value.get("tangent"))
|
||||||
|
and typeof(value.get("width")) == TYPE_INT
|
||||||
|
and int(value["width"]) in GRID_SIZES
|
||||||
|
and typeof(value.get("height")) == TYPE_INT
|
||||||
|
and int(value["height"]) == int(value["width"])
|
||||||
|
and typeof(value.get("cell_size")) in [TYPE_FLOAT, TYPE_INT]
|
||||||
|
and is_equal_approx(float(value["cell_size"]), CELL_SIZE)
|
||||||
|
and typeof(value.get("revision")) == TYPE_INT
|
||||||
|
and int(value["revision"]) >= 0
|
||||||
|
and typeof(value.get("guide_visible", true)) == TYPE_BOOL
|
||||||
|
and typeof(value.get("finalized", false)) == TYPE_BOOL
|
||||||
|
and typeof(value.get("layer", 0)) == TYPE_INT
|
||||||
|
and int(value.get("layer", 0)) >= 0
|
||||||
|
and NetworkIdentityCrypto.valid_fingerprint(
|
||||||
|
value.get("creator_fingerprint")
|
||||||
|
)
|
||||||
|
and _valid_participant_fingerprints(
|
||||||
|
value.get("participant_fingerprints", [])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
static func validate_guide_update(data: Variant) -> bool:
|
static func validate_guide_update(data: Variant) -> bool:
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,4 @@ static func get_unit_value(item: ItemDataType) -> int:
|
||||||
if not is_sellable(item):
|
if not is_sellable(item):
|
||||||
return -1
|
return -1
|
||||||
var purchase_price := FishingShopStockType.get_price(item.item_id)
|
var purchase_price := FishingShopStockType.get_price(item.item_id)
|
||||||
return purchase_price / 2 if purchase_price >= 0 else -1
|
return int(float(purchase_price) / 2.0) if purchase_price >= 0 else -1
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||||
exclude_filter="builds/*,scripts/*"
|
exclude_filter="builds/*,scripts/*"
|
||||||
export_path="builds/v0.19.0-alpha/windows-x86_64/straywild.exe"
|
export_path="builds/v0.20.4-alpha/windows-x86_64/straywild.exe"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
|
|
@ -35,11 +35,11 @@ application/modify_resources=true
|
||||||
application/icon="res://art/exported/system_icons/straywild.ico"
|
application/icon="res://art/exported/system_icons/straywild.ico"
|
||||||
application/console_wrapper_icon=""
|
application/console_wrapper_icon=""
|
||||||
application/icon_interpolation=0
|
application/icon_interpolation=0
|
||||||
application/file_version="0.19.0.0"
|
application/file_version="0.20.4.0"
|
||||||
application/product_version="0.19.0.0"
|
application/product_version="0.20.4.0"
|
||||||
application/company_name="Woofmeow"
|
application/company_name="Woofmeow"
|
||||||
application/product_name="straywild"
|
application/product_name="straywild"
|
||||||
application/file_description="straywild v0.19.0-alpha"
|
application/file_description="straywild v0.20.4-alpha"
|
||||||
application/copyright="Copyright © 2026 Woofmeow"
|
application/copyright="Copyright © 2026 Woofmeow"
|
||||||
application/trademarks="straywild and Woofmeow branding is reserved; see TRADEMARKS.md"
|
application/trademarks="straywild and Woofmeow branding is reserved; see TRADEMARKS.md"
|
||||||
application/export_angle=0
|
application/export_angle=0
|
||||||
|
|
@ -62,7 +62,7 @@ custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||||
exclude_filter="builds/*,scripts/*"
|
exclude_filter="builds/*,scripts/*"
|
||||||
export_path="builds/v0.19.0-alpha/linux-arm64/straywild.arm64"
|
export_path="builds/v0.20.4-alpha/linux-arm64/straywild.arm64"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
|
|
@ -92,7 +92,7 @@ custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||||
exclude_filter="builds/*,scripts/*"
|
exclude_filter="builds/*,scripts/*"
|
||||||
export_path="builds/v0.19.0-alpha/macos/straywild.zip"
|
export_path="builds/v0.20.4-alpha/macos/straywild.zip"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
|
|
@ -108,8 +108,8 @@ custom_template/release=""
|
||||||
application/bundle_identifier="io.woofmeow.netfishing"
|
application/bundle_identifier="io.woofmeow.netfishing"
|
||||||
application/icon="res://art/exported/system_icons/straywild_1024.png"
|
application/icon="res://art/exported/system_icons/straywild_1024.png"
|
||||||
application/icon_interpolation=0
|
application/icon_interpolation=0
|
||||||
application/short_version="0.19.0"
|
application/short_version="0.20.4"
|
||||||
application/version="0.19.0"
|
application/version="0.20.4"
|
||||||
application/architecture="universal"
|
application/architecture="universal"
|
||||||
codesign/enable=false
|
codesign/enable=false
|
||||||
notarization/enable=false
|
notarization/enable=false
|
||||||
|
|
@ -125,7 +125,7 @@ custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||||
exclude_filter="builds/*,scripts/*,tests/*"
|
exclude_filter="builds/*,scripts/*,tests/*"
|
||||||
export_path="builds/v0.19.0-alpha/server-linux-x86_64/straywildServer.x86_64"
|
export_path="builds/v0.20.4-alpha/server-linux-x86_64/straywildServer.x86_64"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
|
|
@ -155,7 +155,7 @@ custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||||
exclude_filter="builds/*,scripts/*"
|
exclude_filter="builds/*,scripts/*"
|
||||||
export_path="builds/v0.19.0-alpha/android/straywild.apk"
|
export_path="builds/v0.20.4-alpha/android/straywild.apk"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
|
|
@ -176,8 +176,8 @@ architectures/armeabi-v7a=false
|
||||||
architectures/arm64-v8a=true
|
architectures/arm64-v8a=true
|
||||||
architectures/x86=false
|
architectures/x86=false
|
||||||
architectures/x86_64=false
|
architectures/x86_64=false
|
||||||
version/code=190000
|
version/code=200400
|
||||||
version/name="v0.19.0-alpha"
|
version/name="v0.20.4-alpha"
|
||||||
package/unique_name="io.woofmeow.netfishing"
|
package/unique_name="io.woofmeow.netfishing"
|
||||||
package/name="straywild"
|
package/name="straywild"
|
||||||
package/signed=true
|
package/signed=true
|
||||||
|
|
@ -214,7 +214,7 @@ custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||||
exclude_filter="builds/*,scripts/*"
|
exclude_filter="builds/*,scripts/*"
|
||||||
export_path="builds/v0.19.0-alpha/linux-x86_64/straywild.x86_64"
|
export_path="builds/v0.20.4-alpha/linux-x86_64/straywild.x86_64"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
|
|
@ -239,3 +239,33 @@ ssh_remote_deploy/extra_args_ssh=""
|
||||||
ssh_remote_deploy/extra_args_scp=""
|
ssh_remote_deploy/extra_args_scp=""
|
||||||
ssh_remote_deploy/run_script="#!/usr/bin/env bash\nexport DISPLAY=:0\nunzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"\nchmod +x \"{temp_dir}/{exe_name}\"\n\"{temp_dir}/{exe_name}\" {cmd_args}"
|
ssh_remote_deploy/run_script="#!/usr/bin/env bash\nexport DISPLAY=:0\nunzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"\nchmod +x \"{temp_dir}/{exe_name}\"\n\"{temp_dir}/{exe_name}\" {cmd_args}"
|
||||||
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash\nkill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")\nrm -rf \"{temp_dir}\""
|
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash\nkill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")\nrm -rf \"{temp_dir}\""
|
||||||
|
|
||||||
|
[preset.6]
|
||||||
|
|
||||||
|
name="PortMaster ARM64"
|
||||||
|
platform="Linux"
|
||||||
|
runnable=false
|
||||||
|
advanced_options=false
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features="straywild_portmaster"
|
||||||
|
export_filter="all_resources"
|
||||||
|
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||||
|
exclude_filter="builds/*,scripts/*"
|
||||||
|
export_path="builds/v0.20.4-alpha/portmaster-arm64/straywild.arm64"
|
||||||
|
patches=PackedStringArray()
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
seed=0
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
script_export_mode=2
|
||||||
|
|
||||||
|
[preset.6.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_wrapper=0
|
||||||
|
binary_format/embed_pck=false
|
||||||
|
binary_format/architecture="arm64"
|
||||||
|
texture_format/s3tc_bptc=false
|
||||||
|
texture_format/etc2_astc=true
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Resource" path="res://fish/day_availability.tres" id="3_availability"]
|
[ext_resource type="Resource" path="res://fish/day_availability.tres" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="4_texture"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/3102.png" id="4_texture"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_fish_data")
|
script = ExtResource("1_fish_data")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/2502.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/2802.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="4_texture"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/2505.png" id="4_texture"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="ChubEuropeanAvailability"]
|
[sub_resource type="Resource" id="ChubEuropeanAvailability"]
|
||||||
script = ExtResource("3_availability_script")
|
script = ExtResource("3_availability_script")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="4_texture"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/2807.png" id="4_texture"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="ChubLakeAvailability"]
|
[sub_resource type="Resource" id="ChubLakeAvailability"]
|
||||||
script = ExtResource("3_availability_script")
|
script = ExtResource("3_availability_script")
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Texture2D" path="res://fish/species/clam_manila/clam_manila.png" id="3_texture"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/6406.png" id="3_texture"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_fish_data")
|
script = ExtResource("1_fish_data")
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
[gd_resource type="Resource" script_class="FishData" load_steps=4 format=3]
|
[gd_resource type="Resource" script_class="FishData" load_steps=5 format=3]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/3902.png" id="99_creature_texture"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
allow_night = false
|
allow_night = false
|
||||||
|
|
@ -12,7 +14,7 @@ allow_night = false
|
||||||
script = ExtResource("1_fish_data")
|
script = ExtResource("1_fish_data")
|
||||||
id = &"crab_blue"
|
id = &"crab_blue"
|
||||||
display_name = "blue crab"
|
display_name = "blue crab"
|
||||||
active = false
|
active = true
|
||||||
catalog_number = 3902
|
catalog_number = 3902
|
||||||
collection_group = &"Marine crabs"
|
collection_group = &"Marine crabs"
|
||||||
logbook_fact = "blue crabs swim with flattened rear legs shaped like paddles. bright blue claws and an olive shell conceal a quick, defensive temperament."
|
logbook_fact = "blue crabs swim with flattened rear legs shaped like paddles. bright blue claws and an olive shell conceal a quick, defensive temperament."
|
||||||
|
|
@ -30,3 +32,5 @@ weight_max_lb = 1.1
|
||||||
sell_value_min = 3
|
sell_value_min = 3
|
||||||
sell_value_max = 8
|
sell_value_max = 8
|
||||||
sell_value_curve = 0.95
|
sell_value_curve = 0.95
|
||||||
|
|
||||||
|
display_texture = ExtResource("99_creature_texture")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/3107.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/2601.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/6801.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/6807.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/5904.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="4_texture"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/3401.png" id="4_texture"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="RoundGobyAvailability"]
|
[sub_resource type="Resource" id="RoundGobyAvailability"]
|
||||||
script = ExtResource("3_availability_script")
|
script = ExtResource("3_availability_script")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="4_texture"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/3002.png" id="4_texture"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="GoldfishAvailability"]
|
[sub_resource type="Resource" id="GoldfishAvailability"]
|
||||||
script = ExtResource("3_availability_script")
|
script = ExtResource("3_availability_script")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/3103.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/5902.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/5903.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/6601.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/2804.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/6904.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/3104.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability"]
|
||||||
[ext_resource type="Texture2D" path="res://art/exported/creatures/fish_placeholder.png" id="99_fish_placeholder"]
|
[ext_resource type="Texture2D" path="res://art/exported/creatures/2504.png" id="99_fish_placeholder"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Availability"]
|
[sub_resource type="Resource" id="Availability"]
|
||||||
script = ExtResource("3_availability")
|
script = ExtResource("3_availability")
|
||||||
|
|
|
||||||