diff --git a/.cargo/config b/.cargo/config index 5dbe6321db..e78c87c91f 100644 --- a/.cargo/config +++ b/.cargo/config @@ -25,10 +25,10 @@ tracy-server-debuginfo = "run --bin veloren-server-cli --features tracy,simd --p tracy-server-releasedebuginfo = "run --bin veloren-server-cli --features tracy,simd --profile releasedebuginfo" tracy-test-server = "run --bin veloren-server-cli --no-default-features --features tracy,simd --profile no_overflow" # voxygen -test-voxygen = "run --bin veloren-voxygen --no-default-features --features simd,egui-ui,shaderc-from-source" +test-voxygen = "run --bin veloren-voxygen --no-default-features --features simd,egui-ui,shaderc-from-source,hot-reloading" tracy-voxygen = "run --bin veloren-voxygen --no-default-features --features tracy,simd,egui-ui,shaderc-from-source --profile no_overflow" dbg-voxygen = "run --bin veloren-voxygen --profile debuginfo" # misc swarm = "run --bin swarm --features client/bin_bot,client/tick_network --" ci-clippy = "clippy --all-targets --locked --features=bin_cmd_doc_gen,bin_compression,bin_csv,bin_graphviz,bin_bot,bin_asset_migrate,asset_tweak,bin,stat" -ci-clippy2 = "clippy -p veloren-voxygen --locked --no-default-features --features=default-publish" \ No newline at end of file +ci-clippy2 = "clippy -p veloren-voxygen --locked --no-default-features --features=default-publish" diff --git a/CHANGELOG.md b/CHANGELOG.md index 68eea077e3..8e975696b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added Autumn Forests, Cherry Blossom Forests, and Maple Trees. - Added reworked dungeon: Haniwa Catacombs - Added dungeon: Terracotta Ruins +- Sand and crystal cave biome ### Changed @@ -92,6 +93,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Sword Changes; Pommel Strike has been nerfed -> increased energy cost, increased _durations, and decreased poise damage. Heavy Sweep has been nerfed -> decreased poise damage and stun vulnerability damage. Pillar Thrust has been altered -> decreased maximum base damage with an increase in stun vulnerability damage. - Weapons block are based on poise - Wooden Shield recipe +- Overhauled the visuals of several cave biomes ### Removed - Medium and large potions from all loot tables diff --git a/Cargo.lock b/Cargo.lock index f7cf4d7688..158b62b4f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7401,7 +7401,6 @@ dependencies = [ "fxhash", "hashbrown 0.13.2", "image", - "inline_tweak", "itertools 0.10.5", "kiddo", "lazy_static", diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 1eb5b25819..9cd475eae1 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -96,6 +96,7 @@ const int PHOENIX_BEAM = 56; const int PHOENIX_BUILD_UP_AIM = 57; const int CLAY_SHRAPNEL = 58; const int AIRFLOW = 59; +const int SPORE = 60; // meters per second squared (acceleration) const float earth_gravity = 9.807; @@ -1016,6 +1017,18 @@ void main() { spin_in_axis(perp_axis, asin(inst_dir.z / length(inst_dir)) + PI / 2.0) ); break; + case SPORE: + f_reflect = 0.0; + attr = Attr( + linear_motion( + vec3(0), + vec3(0, 0, -1.1) + ) + vec3(sin((lifetime + rand9 * 0.1) * 0.5) * 3.0, sin((lifetime+ rand8 * 0.1) * 0.5) * 3.0, sin(lifetime * 0.5) * 1.5), + vec3(0.4 + 0.4 * abs(sin(lifetime))), + vec4(vec3(0.8, 6.0 + rand6 * 1.75, 7.5 + (1.75 + rand5 * 0.5)), 1), + spin_in_axis(vec3(rand1, rand2, rand3), rand4 * 1.5 + lifetime) + ); + break; default: attr = Attr( linear_motion( diff --git a/assets/voxygen/voxel/sprite/cave/cave_flower-0.vox b/assets/voxygen/voxel/sprite/cave/cave_flower-0.vox new file mode 100644 index 0000000000..bb6e51aa78 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_flower-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21ff5a60c0de91a802974a2d108f75aaf867ae131cf6f0fb83d7fbbff1a6f26b +size 1692 diff --git a/assets/voxygen/voxel/sprite/cave/cave_flower-1.vox b/assets/voxygen/voxel/sprite/cave/cave_flower-1.vox new file mode 100644 index 0000000000..3c81954969 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_flower-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b02a74066dba97ed9fc0be8f41a4dbfea8789d89cf7bb66b69fccb9b138266f +size 1692 diff --git a/assets/voxygen/voxel/sprite/cave/cave_flower-2.vox b/assets/voxygen/voxel/sprite/cave/cave_flower-2.vox new file mode 100644 index 0000000000..8a6b8371c8 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_flower-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbb1de9a0121e651eddaf1173e399d0b935987e6369184b7db4a132f45999b06 +size 1476 diff --git a/assets/voxygen/voxel/sprite/cave/cave_flower-3.vox b/assets/voxygen/voxel/sprite/cave/cave_flower-3.vox new file mode 100644 index 0000000000..825e09453d --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_flower-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e39792dd2ae936dc3b77bd97d11432cd2754bcc405d7437f5ce517ab0914240c +size 1468 diff --git a/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-0.vox b/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-0.vox new file mode 100644 index 0000000000..77b0341276 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a6d8454c26ac51af3b5ad1ab32b3f5dbe1793b116214fe2d62b2fe6d4602be5 +size 2616 diff --git a/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-1.vox b/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-1.vox new file mode 100644 index 0000000000..104f6d401e --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08dcd4e0d3675f13584d6be67e567c021ac8284406d5f136a70b145c7f5e6724 +size 4092 diff --git a/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-2.vox b/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-2.vox new file mode 100644 index 0000000000..8dd74a6124 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_lantern_flower-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:059048f6a2fc9873817b7990baddaadd5ea5f4af522ab484657238d359798a98 +size 2080 diff --git a/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-0.vox b/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-0.vox new file mode 100644 index 0000000000..4240d8f408 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85e6a614536b62f034adc3fa05f28fbe4b2d41a111fd8947f373017a40d1bf4f +size 2212 diff --git a/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-1.vox b/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-1.vox new file mode 100644 index 0000000000..0512c9f088 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ce0a40c247311e02f0f3c547fd0d3c0d6d0b6a502500e0d9fec67ed483779ce +size 2116 diff --git a/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-2.vox b/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-2.vox new file mode 100644 index 0000000000..eef86a3165 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/cave_lantern_plant-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99db3fadfaa5f7a6202225aa543a8a35ee1a9fd5514828af7549daff49880cfa +size 1932 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-0.vox b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-0.vox new file mode 100644 index 0000000000..2706aaa80e --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67e2193410f9cc0687e4ee62b9fdd02cdfdc41c6c21e7fa22fa0fe083434d0e4 +size 2616 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-1.vox b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-1.vox new file mode 100644 index 0000000000..7b72b2e4eb --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a904f1945610b0f69717acc9ad0f44a8aa315caad3d732b185901328846537e2 +size 4092 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-2.vox b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-2.vox new file mode 100644 index 0000000000..4e3bf99edb --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_flower-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f5228452cc894fb375708ca34c2d06ff13be205eae352880a69428a32271e6b +size 2080 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_plant-0.vox b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_plant-0.vox new file mode 100644 index 0000000000..e36bcfef97 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_plant-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a2c8cc9cde6ac6605dc99140a25d71bf7b0f3e9c2922c2d14aaa7f851d64e7d +size 1932 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_plant-1.vox b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_plant-1.vox new file mode 100644 index 0000000000..56c319971a --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/cave_lantern_plant-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6192326c37ca9e3faac1130a10e0206506af0e21faf4c3d2ca2c68e9b8977d4 +size 1884 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/mold-4.vox b/assets/voxygen/voxel/sprite/cave/ceiling/mold-4.vox index 3e27f7226e..759db915e7 100644 --- a/assets/voxygen/voxel/sprite/cave/ceiling/mold-4.vox +++ b/assets/voxygen/voxel/sprite/cave/ceiling/mold-4.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80117ff139a0b28ddc8b00e26f3005abe25444abd8e61fe2179941d2dd060abe -size 2140 +oid sha256:ff62aa84976fe527082c55088a5230e9f401a557c3e99d54e41cead27a6b6f2b +size 1880 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/mold-5.vox b/assets/voxygen/voxel/sprite/cave/ceiling/mold-5.vox index bd1f28ddf7..b8360b1aee 100644 --- a/assets/voxygen/voxel/sprite/cave/ceiling/mold-5.vox +++ b/assets/voxygen/voxel/sprite/cave/ceiling/mold-5.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:549d7ddb44c1a935fb72e9cdc089b381d8420b7e8635fe95d5dacc05f47d27e4 -size 2792 +oid sha256:60f1aa88e010a545c6aaa59da852b4bc9cbba3f66d9c0434a8691a166a620b22 +size 2244 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/mold-6.vox b/assets/voxygen/voxel/sprite/cave/ceiling/mold-6.vox index 8bab3a127b..f536bdd9db 100644 --- a/assets/voxygen/voxel/sprite/cave/ceiling/mold-6.vox +++ b/assets/voxygen/voxel/sprite/cave/ceiling/mold-6.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:174071a1a2492ec08915df237cf6e02abe3f298485f772441133792d5ab49732 -size 2784 +oid sha256:c4e2e834176cd258169f499cb1a7b6046aa6fa3741e02ae16b04c8ab748d969d +size 2340 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/mycel-0.vox b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-0.vox new file mode 100644 index 0000000000..dd3469a4b3 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fed02ca946f0a3fc4113b10f940f160a84dcf852f2d0550c10b07138ef53f701 +size 1400 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/mycel-1.vox b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-1.vox new file mode 100644 index 0000000000..194be26809 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f38e1f4330ce5cf35d6d56ec118953bf266e5c9e9b98183a768e2639f591054 +size 1592 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/mycel-2.vox b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-2.vox new file mode 100644 index 0000000000..68f19ac0fc --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75862c5f9c5833683ea608e167315020b9cdae1793dfc01b2f713e2cdaabd322 +size 1476 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/mycel-3.vox b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-3.vox new file mode 100644 index 0000000000..9c19329bba --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/mycel-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc720540b281bc1e87ed506099b39a9c47b9ee2ea6d5df555135282eddaf090c +size 1652 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/root-0.vox b/assets/voxygen/voxel/sprite/cave/ceiling/root-0.vox new file mode 100644 index 0000000000..a233547634 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/root-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d499ec70026859f713267c8e79d2c5998a595ddf8e8f87791ba5366a65f7c41 +size 1692 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/root-1.vox b/assets/voxygen/voxel/sprite/cave/ceiling/root-1.vox new file mode 100644 index 0000000000..0271a5cb6a --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/root-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:691b155b58faaaf67abc0a13351b5496665679a38440a1d951778cacd3e67c32 +size 1864 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/root-2.vox b/assets/voxygen/voxel/sprite/cave/ceiling/root-2.vox new file mode 100644 index 0000000000..0bbe18efea --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/root-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d48ae8e182d4693bf2c5a3999d95b3adabb7543c43b3f1a2a72d172ba377b7ef +size 1792 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/root-3.vox b/assets/voxygen/voxel/sprite/cave/ceiling/root-3.vox new file mode 100644 index 0000000000..dbdd10dcaf --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/root-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5bad7db3a4b4ec642f8a1ecda4d8539d6ffd1cfc0a13887a9f1662566dbe161 +size 1712 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/root-4.vox b/assets/voxygen/voxel/sprite/cave/ceiling/root-4.vox new file mode 100644 index 0000000000..4bc04c93ae --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/root-4.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e73fec9396657bd52e53c1a472b849a892dbf9eb2114109a215214d458129afa +size 1632 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/root-5.vox b/assets/voxygen/voxel/sprite/cave/ceiling/root-5.vox new file mode 100644 index 0000000000..df216ee49b --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/root-5.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcc819c8c72db8da498cf30aa4774500ffe3d5ca1b0e83456a451752164ad6ac +size 1604 diff --git a/assets/voxygen/voxel/sprite/cave/ceiling/root-6.vox b/assets/voxygen/voxel/sprite/cave/ceiling/root-6.vox new file mode 100644 index 0000000000..3d6a00da78 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/ceiling/root-6.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eda7ec75b5a8c52d042cf933ad2fba8da806348f3ae3ff00f2882ad0645a86b9 +size 1808 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-0.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-0.vox new file mode 100644 index 0000000000..278b96b50f --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b76e8ca3d721f1cb45bcbf764937749d38d5526e79082ab3b1ab85a8ba842836 +size 1428 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-1.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-1.vox new file mode 100644 index 0000000000..c3d52b0290 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77f196647a7f74391d1f9957acf7cb559850618a27239ca64344a2eefbdc06f1 +size 1396 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-2.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-2.vox new file mode 100644 index 0000000000..d88f9951e7 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e99f856f05ce788529d5566a4ecf56c83433841a47bdbee6dc717bc3dda8d713 +size 1444 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-3.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-3.vox new file mode 100644 index 0000000000..8ef2f47d3e --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f9419e6fb25313c7fec015305d18f209396f4e41527debbdf306b8c6c76c90b +size 1264 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-4.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-4.vox new file mode 100644 index 0000000000..8ffeb583d2 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-4.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e46639e32343a803de848030772ab9489defc4e77f2b3f776fb79ac43af902aa +size 1404 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-5.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-5.vox new file mode 100644 index 0000000000..ee35457b26 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-5.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:806f6b8887d9f7240d7dc82b135f7609d99d252d740e15a7da0f6150bea31149 +size 1432 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-6.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-6.vox new file mode 100644 index 0000000000..049a6b4da5 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-6.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4498b70c987f525a2b2feeb3a4974b86c940e5a9b9cfa8d9997f7d9501dbc05 +size 1428 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_long-7.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_long-7.vox new file mode 100644 index 0000000000..256dfaa07f --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_long-7.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:870d8b948b8c21704781825bb750b45477580562ee1d0088d9f1ab008c8e6e9c +size 1380 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_med-0.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_med-0.vox new file mode 100644 index 0000000000..a4184d8e90 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_med-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:941e19009fa39aae441c7fc03a12d0143de51d09c823fad0b8184c48f2263200 +size 1244 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_med-1.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_med-1.vox new file mode 100644 index 0000000000..e077f4f473 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_med-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6427235b7aa34db357e403e05ee54ed1ddba9d21a01abaa4d3a97aa1e22e685b +size 1248 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_med-2.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_med-2.vox new file mode 100644 index 0000000000..8a36087716 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_med-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f3fd71c567f456357c87216832ff606d8b123bcbe0732d36d119f1b9683be56 +size 1288 diff --git a/assets/voxygen/voxel/sprite/cave/grass_blue_med-3.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_med-3.vox new file mode 100644 index 0000000000..63e1bbd708 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/grass_blue_med-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0dfee4fc2ed0776a0ce8eb241392cef2c2f34bf972dfbfc7660dedffe7253808 +size 1232 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_short-0.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_short-0.vox similarity index 100% rename from assets/voxygen/voxel/sprite/cavern/grass_short-0.vox rename to assets/voxygen/voxel/sprite/cave/grass_blue_short-0.vox diff --git a/assets/voxygen/voxel/sprite/cavern/grass_short-1.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_short-1.vox similarity index 100% rename from assets/voxygen/voxel/sprite/cavern/grass_short-1.vox rename to assets/voxygen/voxel/sprite/cave/grass_blue_short-1.vox diff --git a/assets/voxygen/voxel/sprite/cavern/grass_short-2.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_short-2.vox similarity index 100% rename from assets/voxygen/voxel/sprite/cavern/grass_short-2.vox rename to assets/voxygen/voxel/sprite/cave/grass_blue_short-2.vox diff --git a/assets/voxygen/voxel/sprite/cavern/grass_short-3.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_short-3.vox similarity index 100% rename from assets/voxygen/voxel/sprite/cavern/grass_short-3.vox rename to assets/voxygen/voxel/sprite/cave/grass_blue_short-3.vox diff --git a/assets/voxygen/voxel/sprite/cavern/grass_short-4.vox b/assets/voxygen/voxel/sprite/cave/grass_blue_short-4.vox similarity index 100% rename from assets/voxygen/voxel/sprite/cavern/grass_short-4.vox rename to assets/voxygen/voxel/sprite/cave/grass_blue_short-4.vox diff --git a/assets/voxygen/voxel/sprite/cave/mushroom-10.vox b/assets/voxygen/voxel/sprite/cave/mushroom-10.vox new file mode 100644 index 0000000000..5b3f40c82e --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/mushroom-10.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e7911ad1366527d4b9f602f5c5b2edfa15258a7b562de1798c5bf8efb70df5a +size 1452 diff --git a/assets/voxygen/voxel/sprite/cave/mushroom-11.vox b/assets/voxygen/voxel/sprite/cave/mushroom-11.vox new file mode 100644 index 0000000000..7a9cc2328a --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/mushroom-11.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff20e12796992321a7d853ddad4dee3033dbf6eea010003879e3ba0854314be1 +size 1636 diff --git a/assets/voxygen/voxel/sprite/cave/mushroom-9.vox b/assets/voxygen/voxel/sprite/cave/mushroom-9.vox new file mode 100644 index 0000000000..27a871aef5 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/mushroom-9.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2330b55ec3cbf670db47c467006437a2dbc3b797ebdc017aef4aa341a93709be +size 1884 diff --git a/assets/voxygen/voxel/sprite/cave/spore_reed-0.vox b/assets/voxygen/voxel/sprite/cave/spore_reed-0.vox new file mode 100644 index 0000000000..3da0eec5f0 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/spore_reed-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d658194f30de7e43c0ac007c0f2751bd2cb11e4bf5701af8e7dad98e6af0d7e7 +size 1956 diff --git a/assets/voxygen/voxel/sprite/cave/spore_reed-1.vox b/assets/voxygen/voxel/sprite/cave/spore_reed-1.vox new file mode 100644 index 0000000000..f394a4b4c8 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/spore_reed-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6eacd8ee24218c4b3b62f5bdbf9465a464cbca9375c303926797c10e34810f6a +size 1740 diff --git a/assets/voxygen/voxel/sprite/cave/spore_reed-2.vox b/assets/voxygen/voxel/sprite/cave/spore_reed-2.vox new file mode 100644 index 0000000000..3b39f49588 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/spore_reed-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a087ceb292004756842c404465c36d0a192fa9a9ab4593b87db1c8a77b4e2fac +size 1648 diff --git a/assets/voxygen/voxel/sprite/cave/spore_reed-3.vox b/assets/voxygen/voxel/sprite/cave/spore_reed-3.vox new file mode 100644 index 0000000000..bd2135d722 --- /dev/null +++ b/assets/voxygen/voxel/sprite/cave/spore_reed-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aecb94ae2810841d0a99fd72bbd9de1b0a23fa6d1f667d31c8412a2dc077287d +size 1372 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-0.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-0.vox deleted file mode 100644 index 02a7af7f8c..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-0.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:144bb2be7627de61e951085c96038284ae28eed216c6b2c04eb0db596df2f738 -size 1428 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-1.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-1.vox deleted file mode 100644 index 772cfe132a..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-1.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c76794542d91c94960373966c2b0232f57801d0a862a117090ba00a7ae934034 -size 1396 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-2.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-2.vox deleted file mode 100644 index e53115ea2a..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-2.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44d27165b605d477f769123ef5d93de7ad357f0b937263ad37ebb8c1480c4324 -size 1444 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-3.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-3.vox deleted file mode 100644 index 6157a2843f..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-3.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44745ce1fef2c4cc1834e82abde5ef6ea3af113b3d3a4cf7df223b833ec07207 -size 1264 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-4.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-4.vox deleted file mode 100644 index d1b9ac74e1..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-4.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9439482e006100f8219d27095e1929e15e4cfcd6303b8911a9ce638c30b76966 -size 1404 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-5.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-5.vox deleted file mode 100644 index 3e0c01f98a..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-5.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7261c47bb5683e0a0cb1461dc84c5980e7cc1b25f8063b667fef86657e145a68 -size 1432 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-6.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-6.vox deleted file mode 100644 index b8e51f934e..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-6.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3bfe9db4fc6e624aa477b04dc6c681e390df65d8c488bf0eb61a86e7d8b7430d -size 1428 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_long-7.vox b/assets/voxygen/voxel/sprite/cavern/grass_long-7.vox deleted file mode 100644 index 5d7ffe064c..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_long-7.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:eec0a1b111d12f022e973e14afaf2e8f81fd7c6e4676a29cbc2f698f75a13e95 -size 1380 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_med-0.vox b/assets/voxygen/voxel/sprite/cavern/grass_med-0.vox deleted file mode 100644 index 452bd9f440..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_med-0.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7496e27724e51a4129955a304cc10a15447845687e817140464da7f69be92386 -size 1244 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_med-1.vox b/assets/voxygen/voxel/sprite/cavern/grass_med-1.vox deleted file mode 100644 index 6f79383e6a..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_med-1.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7decc0743714a30208440e9437caaa77de79d730a9d7e060a4625c621ab30feb -size 1248 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_med-2.vox b/assets/voxygen/voxel/sprite/cavern/grass_med-2.vox deleted file mode 100644 index 2f2f65d819..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_med-2.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:05c12e2e4d82b186c422f0da4617e17dd72f45b48071a3a7567fb186b581d4d2 -size 1288 diff --git a/assets/voxygen/voxel/sprite/cavern/grass_med-3.vox b/assets/voxygen/voxel/sprite/cavern/grass_med-3.vox deleted file mode 100644 index 4e657e7fe8..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/grass_med-3.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:92fbd926d0e40ae777286c85d1cd56547717a0fc74f6d34611394113d063c74b -size 1232 diff --git a/assets/voxygen/voxel/sprite/cavern/mycel-0.vox b/assets/voxygen/voxel/sprite/cavern/mycel-0.vox deleted file mode 100644 index 4f3d86f73b..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/mycel-0.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3d7180c8469565f8836b1e795c94faecab5fb97c1d3d9b3c1d50fd202bb23d6f -size 1180 diff --git a/assets/voxygen/voxel/sprite/cavern/mycel-1.vox b/assets/voxygen/voxel/sprite/cavern/mycel-1.vox deleted file mode 100644 index 44ff474b6e..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/mycel-1.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:10c3aa05a02e9431d2bf25fa473218c4c91ad62252ee3d8383e82a57cbcff1bb -size 1220 diff --git a/assets/voxygen/voxel/sprite/cavern/mycel-2.vox b/assets/voxygen/voxel/sprite/cavern/mycel-2.vox deleted file mode 100644 index a63c1a67af..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/mycel-2.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0516877cbf4caa6370c2dbf3c957b294c12a93db8e805dd858e43c91d17ee36c -size 1152 diff --git a/assets/voxygen/voxel/sprite/cavern/mycel-3.vox b/assets/voxygen/voxel/sprite/cavern/mycel-3.vox deleted file mode 100644 index 764d35b66e..0000000000 --- a/assets/voxygen/voxel/sprite/cavern/mycel-3.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d3ceb2b40579d0b885280d80e8e52179d6696fe99ff4612ee2c9931ec0543bc -size 1256 diff --git a/assets/voxygen/voxel/sprite/dead_plant/dead_plant-0.vox b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-0.vox new file mode 100644 index 0000000000..82b695dcdb --- /dev/null +++ b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:325906029c1c3d0ae79f282677817e2b6e4634c40c665a9b413dfe23deb5b87e +size 1308 diff --git a/assets/voxygen/voxel/sprite/dead_plant/dead_plant-1.vox b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-1.vox new file mode 100644 index 0000000000..237fb7bc9c --- /dev/null +++ b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c59380ff24f6ddde29a2d2018ae5eee996dd6af7ea6b820974929677a74a35d +size 1280 diff --git a/assets/voxygen/voxel/sprite/dead_plant/dead_plant-2.vox b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-2.vox new file mode 100644 index 0000000000..d76b5745bb --- /dev/null +++ b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:891583126c09f134eda53b675a3c18bdfd299a84939e73dc276a5689d05de2f0 +size 1192 diff --git a/assets/voxygen/voxel/sprite/dead_plant/dead_plant-3.vox b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-3.vox new file mode 100644 index 0000000000..63e3970ac0 --- /dev/null +++ b/assets/voxygen/voxel/sprite/dead_plant/dead_plant-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0afa6f113b4f161f33f40d2dea097cb2ecc38eaf164478850190aa5ddccd7ebc +size 1236 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/1.vox b/assets/voxygen/voxel/sprite/leafy_plant/1.vox index 13258089d6..f4c6ee9973 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/1.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/1.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f7230dc9d14f13b7bad03fcc2cda7922e6898745c18791916d8fa59c5709bcb -size 1892 +oid sha256:9525a447698343edd41376d17ee9d3bbf994d09df56b79883e5f9dd78298c3e6 +size 1876 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/10.vox b/assets/voxygen/voxel/sprite/leafy_plant/10.vox index 73d3b3901d..f73c307a28 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/10.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/10.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63accce104181146bbe0e02f7c1f22f3d849387c4da7975c23e6d9aa0174f8fa -size 1160 +oid sha256:20d22e75a55607b46ad49f53f5bd24db8d9f08ed602e71bfee8b00fc0267e1ec +size 1236 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/2.vox b/assets/voxygen/voxel/sprite/leafy_plant/2.vox index daddc2cd70..0ee6c528e1 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/2.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/2.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56fff236d95573b242fa086eb7c9d0ea88199d1b1c4509d072a84ff389c43618 -size 1340 +oid sha256:52f494a4636c7fcc11a2d229a13c8ebc7b8f608807bcd29891b8d25a4e63bdb5 +size 1372 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/3.vox b/assets/voxygen/voxel/sprite/leafy_plant/3.vox index a4cb1b017d..803acab16e 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/3.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/3.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b376fd6ae77ee6b70b840ae836c3f45f9a534982793b6399b1e75e80f340ce40 -size 1432 +oid sha256:2ab99313cb91c8118067cfe1275affe766658da941d73a83a0e400f5c6e8c8a9 +size 2044 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/4.vox b/assets/voxygen/voxel/sprite/leafy_plant/4.vox index 21506dc484..2cb7810214 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/4.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/4.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b486ba258a8e9b780ce48a660814762593306520b901e058b5f803e50b4ed7f9 -size 1308 +oid sha256:1506b5b2e15404b1e17812c78bac8711c6def87fd61a0882a74341c67f6f5ab2 +size 1484 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/5.vox b/assets/voxygen/voxel/sprite/leafy_plant/5.vox index 6dca485f98..6b12574fb1 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/5.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/5.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96113dd1de793a91c1b4eda784f89cc65396c41aa930274c748ee7afce666de0 -size 1284 +oid sha256:db158665c455aacba759303c6fd3a0c95ddfbaac19a48aa3a1fc99a2246468b4 +size 1804 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/6.vox b/assets/voxygen/voxel/sprite/leafy_plant/6.vox index 1ea45c7fe1..453199fe24 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/6.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/6.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2546700413ad30593ca2f51c22f1b51dc9b94b43c9cbaa38ffecf18a7addbd07 -size 1292 +oid sha256:ad4413aa053b09002b355d509a45538ae2546e69f81eccd34499566626cb1827 +size 1580 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/7.vox b/assets/voxygen/voxel/sprite/leafy_plant/7.vox index 57d2ee507f..2cb0bdf5e1 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/7.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/7.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c50625eb6a07a0a3eb04975fa769b6301ad0f4f05f433adb1e3cb5b6b85b712d -size 1252 +oid sha256:45e171e6ce24371bbab7dc2a54023ef279a89a53af96c30577c1d9659bd3087f +size 1820 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/8.vox b/assets/voxygen/voxel/sprite/leafy_plant/8.vox index f75a876043..e940ba77cb 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/8.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/8.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d37384289721949cfeb63c6429454d0356470c52a0d682a1147be46e801fa4d -size 1340 +oid sha256:55c8036250c374478f37da3a3a09f18183a2af88daedf324cf8e846f1563c1fd +size 1608 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/9.vox b/assets/voxygen/voxel/sprite/leafy_plant/9.vox index b4996a9d93..9d480bba6a 100644 --- a/assets/voxygen/voxel/sprite/leafy_plant/9.vox +++ b/assets/voxygen/voxel/sprite/leafy_plant/9.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:74ffee6cdbda6bfed82453eb285a8d6f3d4bbc01abed21d73a96caf1ef075188 -size 1188 +oid sha256:91d5a6cb6ec9b74cab5a57f5e480f7cbd0472f063fbb37e4449b817cbb032bc3 +size 1320 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-0.vox b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-0.vox new file mode 100644 index 0000000000..481987e1f1 --- /dev/null +++ b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:203199ae6be0e8c086262dac995e54dab02651b6de5238c3ae54625adc32b09d +size 1336 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-1.vox b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-1.vox new file mode 100644 index 0000000000..7890ecb1d9 --- /dev/null +++ b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd3386610963273712d388b8c580163ffa4a602bd82352e6ad7e4f158568ce9d +size 1472 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-2.vox b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-2.vox new file mode 100644 index 0000000000..dc20aee456 --- /dev/null +++ b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:277484b32c9ad55804b32ad9e960c1a1bf38729e7a92c134272b3f27ae69ca6c +size 1460 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-3.vox b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-3.vox new file mode 100644 index 0000000000..c9f4523644 --- /dev/null +++ b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6de8c164400d98aee06ef992add76601f41ad970305f2456cd542768d8bd2841 +size 1540 diff --git a/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-4.vox b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-4.vox new file mode 100644 index 0000000000..bba1499c91 --- /dev/null +++ b/assets/voxygen/voxel/sprite/leafy_plant/jungle_plant_ceiling-4.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e55f3b7dd4ab6825f670c739e91a29a454ee871b7556f68eb05043af833634c +size 1752 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-0.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-0.vox index a2824a0262..a8d38710b2 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-0.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-0.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65ed706fdb0b4ac5e66f22d2edcfc78dea308a51f3616e35cadac11ce8c22656 -size 1160 +oid sha256:b8e4af46fbeb52e2defd77354c5c4f0f3c5b6e0b61a56f0bda4de94ae746a3c4 +size 1460 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-1.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-1.vox index bd29d728cc..1d4dad4f95 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-1.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-1.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83ca8cf16bbac82da89a0102513e7c54edd75f3b772cdb5aa0981c117045db33 -size 1204 +oid sha256:d12bd2ec8a2b172acd40a7b85571a213dfe6cb426446eb0ca2fb7bc2bfae5f1a +size 1440 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-10.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-10.vox index f293502f1b..33662b1423 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-10.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-10.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1bd2decf66c5b2c4712e7f2ae77ae4c530e79373a0ceed111f7254e98dbced6c -size 1448 +oid sha256:ad534b54ce5c7456e0e5b6365fe4ec2c7f3f8d7c7182899261e30bbb0ab29f59 +size 1748 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-2.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-2.vox index 5f2378a8d7..eb71303649 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-2.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-2.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b67de880999ab46de70e8579ed5054f3838c354a7a74ed382c4e2abc1ea16f27 -size 1160 +oid sha256:d51975bcb9e5bc73cf5edaf510cb76314457bc83ddebeaf3cb18668f76ab011f +size 1328 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-3.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-3.vox index fac5b3ca1f..5a736133fe 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-3.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-3.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d262dc556c2c28fbba8d964aa7c2c42d78bec410e3aa1ee71eb353a7701a8b0e -size 1244 +oid sha256:5e83595d72a91a33b298fdb350be172ec167cf3823d719d74eade52a32ea5246 +size 1368 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-4.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-4.vox index b7e0dba6dc..b993fb3141 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-4.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-4.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:192b8f2baddda973d5b9e55e2aaf0fe8dcb3ddc5be5d242cd6bab319b6f8a763 -size 1448 +oid sha256:7be406856dc790d50b73ff194a3cba8033751f2d819524a5759ef6d6d60fc5c1 +size 1648 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-5.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-5.vox index f32e812b5d..529935cb69 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-5.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-5.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5811aaf9f24505b2d089c9adc176ec906b746b506ae7e64434bc10638b3efd00 -size 1512 +oid sha256:c7d93cfbf41755b4fd14b2562de6f4b41a50032907d740ee70fd3c17eb7c1207 +size 2004 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-6.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-6.vox index a3af68eb4a..dc822fdadf 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-6.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-6.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:588d579a9c4dc18c5795459eb27b89082ace9ffabc2034815a0cff750464c9be -size 1340 +oid sha256:a505d307d4bc865bde485215a1d4eeaae48ed4b1284bfec90c9349e159f02b21 +size 1708 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-7.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-7.vox index 0a5fa93168..c853b7946d 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-7.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-7.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0c01c8e11e19b510b7762389782721d55737857ed49230b557a59f10c5e932c -size 1224 +oid sha256:deb044efce4e3012a5f3ba3164499dc8f08bdd80c82af4d09702518f0c9c468d +size 1372 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-8.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-8.vox index 9ce82ae5a2..4113f2ef47 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-8.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-8.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ba9246881224580ae0b3df4a4ed7da8119744c48c62f2ab68eec3bb988a9513 -size 1252 +oid sha256:61c68b179303f378fc018ec12f6e99d26a709970d14000df21f484a5528633b1 +size 1596 diff --git a/assets/voxygen/voxel/sprite/mushrooms/mushroom-9.vox b/assets/voxygen/voxel/sprite/mushrooms/mushroom-9.vox index a081aa830e..c8ca537dfd 100644 --- a/assets/voxygen/voxel/sprite/mushrooms/mushroom-9.vox +++ b/assets/voxygen/voxel/sprite/mushrooms/mushroom-9.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:845460d4711a46dfd8666ed99591d50e846d3c35cc78e1a8fb2db62eba459d93 -size 1432 +oid sha256:46986e4b3c3e9a84cc6e43656140e206a22c08fee63b02dacf61b116806b9869 +size 2116 diff --git a/assets/voxygen/voxel/sprite_manifest.ron b/assets/voxygen/voxel/sprite_manifest.ron index f96cfae70f..1c8e64bb12 100644 --- a/assets/voxygen/voxel/sprite_manifest.ron +++ b/assets/voxygen/voxel/sprite_manifest.ron @@ -610,6 +610,139 @@ SewerMushroom: Some(( ], wind_sway: 0.0, )), +// Lush cave biome mushrooms +LushMushroom: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-0", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-1", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-2", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-4", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-5", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-6", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-9", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-1", + offset: (-5.0, -5.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +// Rocky cave biome mushrooms +RockyMushroom: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.mushroom-0", + offset: (-8.0, -8.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-2", + offset: (-5.5, -5.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-9", + offset: (-8.0, -8.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-10", + offset: (-8.0, -8.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-11", + offset: (-8.0, -8.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +// Mushroom cave biome mushrooms +GlowMushroom: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.mushroom-3", + offset: (-2.5, -2.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-4", + offset: (-1.5, -1.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-5", + offset: (-5.5, -5.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-6", + offset: (-8.5, -8.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-7", + offset: (-11.5, -11.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.mushroom-8", + offset: (-12.5, -15.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-3", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-7", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-8", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mushrooms.mushroom-10", + offset: (-6.0, -6.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), // Cave Mushrooms CaveMushroom: Some(( variations: [ @@ -679,6 +812,11 @@ CeilingMushroom: Some(( offset: (-11.5, -11.5, -17.0), lod_axes: (1.0, 1.0, 1.0), ), + ], + wind_sway: 0.0, +)), +Mold: Some(( + variations: [ ( model: "voxygen.voxel.sprite.cave.ceiling.mold-0", offset: (-5.5, -5.5, 0.0), @@ -696,22 +834,217 @@ CeilingMushroom: Some(( ), ( model: "voxygen.voxel.sprite.cave.ceiling.mold-3", - offset: (-5.5, -5.5, 2.0), + offset: (-5.5, -5.5, -2.0), lod_axes: (1.0, 1.0, 1.0), ), ( model: "voxygen.voxel.sprite.cave.ceiling.mold-4", - offset: (-2.0, -2.0, -49.0), + offset: (-5.5, -5.5, -13.0), lod_axes: (1.0, 1.0, 1.0), ), ( model: "voxygen.voxel.sprite.cave.ceiling.mold-5", - offset: (-2.0, -2.0, -79.0), + offset: (-5.5, -5.5, -19.0), lod_axes: (1.0, 1.0, 1.0), ), ( model: "voxygen.voxel.sprite.cave.ceiling.mold-6", - offset: (-2.0, -2.0, -79.0), + offset: (-5.5, -5.5, -24.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +Root: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.ceiling.root-0", + offset: (-3.0, -2.5, -22.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.root-1", + offset: (-2.5, -2.5, -34.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.root-2", + offset: (-2.5, -2.5, -31.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.root-3", + offset: (-2.5, -2.5, -24.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.root-4", + offset: (-2.5, -2.5, -16.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.root-5", + offset: (-2.5, -2.5, -16.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.root-6", + offset: (-2.5, -2.5, -33.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +CeilingLanternPlant: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.ceiling.cave_lantern_plant-0", + offset: (-7.5, -5.5, -23.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.cave_lantern_plant-1", + offset: (-7.5, -5.5, -16.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +CeilingLanternFlower: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.ceiling.cave_lantern_flower-0", + offset: (-7.5, -7.5, 3.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.cave_lantern_flower-1", + offset: (-6.5, -6.5, 1.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.ceiling.cave_lantern_flower-2", + offset: (-7.5, -7.5, 4.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +CeilingJungleLeafyPlant: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.leafy_plant.jungle_plant_ceiling-0", + offset: (-5.5, -1.5, -1.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.leafy_plant.jungle_plant_ceiling-1", + offset: (-6.5, -2.5, -3.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.leafy_plant.jungle_plant_ceiling-2", + offset: (-6.5, -2.5, -5.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.leafy_plant.jungle_plant_ceiling-3", + offset: (-7.5, -2.5, -5.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.leafy_plant.jungle_plant_ceiling-4", + offset: (-7.5, -5.5, -11.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.4, +)), +LushFlower: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.cave_flower-0", + offset: (-5.0, -5.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.cave_flower-1", + offset: (-5.5, -5.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.cave_flower-2", + offset: (-4.5, -4.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.cave_flower-3", + offset: (-5.5, -3.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +LanternFlower: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.cave_lantern_flower-0", + offset: (-7.5, -7.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.cave_lantern_flower-1", + offset: (-11.5, -11.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.cave_lantern_flower-2", + offset: (-7.5, -7.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +LanternPlant: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.cave_lantern_plant-0", + offset: (-7.5, -7.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.cave_lantern_plant-1", + offset: (-11.5, -11.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.cave_lantern_plant-2", + offset: (-7.5, -7.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, +)), +SporeReed: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.cave.spore_reed-0", + offset: (-5.5, -5.5, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.spore_reed-1", + offset: (-4.0, -5.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.spore_reed-2", + offset: (-4.5, -5.0, 0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.cave.spore_reed-3", + offset: (-3.0, -2.5, 0.0), lod_axes: (1.0, 1.0, 1.0), ), ], @@ -1594,6 +1927,32 @@ DeadBush: Some(( ], wind_sway: 0.2, )), +// Dead Plant +DeadPlant: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.dead_plant.dead_plant-0", + offset: (-6.0, -6.0, -0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.dead_plant.dead_plant-1", + offset: (-6.0, -6.0, -0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.dead_plant.dead_plant-2", + offset: (-6.0, -6.0, -0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.dead_plant.dead_plant-3", + offset: (-6.0, -6.0, -0.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.2, +)), // Blueberries // NOTE: Why are these commented out? Blueberry: None/* ( @@ -3580,9 +3939,44 @@ CrystalHigh: Some(( model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.green-2", offset: (-11.5, -12.5, -9.0), lod_axes: (1.0, 1.0, 1.0), - ) -], -wind_sway: 0.0, + ), + ( + model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.blue-0", + offset: (-8.5, -9.0, -7.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.blue-1", + offset: (-8.0, -8.0, -10.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.blue-2", + offset: (-11.5, -12.5, -9.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.purple-0", + offset: (-8.5, -9.0, -7.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.purple-1", + offset: (-8.0, -8.0, -10.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.purple-2", + offset: (-11.5, -12.5, -9.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ( + model: "voxygen.voxel.sprite.mineral.deposit.crystal.ceiling.purple-3", + offset: (-11.0, -12.5, -49.0), + lod_axes: (1.0, 1.0, 1.0), + ), + ], + wind_sway: 0.0, )), CrystalLow: Some(( variations: [ @@ -3631,8 +4025,8 @@ CrystalLow: Some(( offset: (-11.5, -12.5, 0.0), lod_axes: (1.0, 1.0, 1.0), ) -], -wind_sway: 0.0, + ], + wind_sway: 0.0, )), Cotton: Some(( variations: [ @@ -4113,103 +4507,103 @@ Bones: Some(( ], wind_sway: 0.0, )), -// Short Cavern Grass Blue -CavernGrassBlueShort: Some(( +// Short Grass Blue +GrassBlueShort: Some(( variations: [ ( - model: "voxygen.voxel.sprite.cavern.grass_short-0", + model: "voxygen.voxel.sprite.cave.grass_blue_short-0", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_short-1", + model: "voxygen.voxel.sprite.cave.grass_blue_short-1", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_short-2", + model: "voxygen.voxel.sprite.cave.grass_blue_short-2", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_short-3", + model: "voxygen.voxel.sprite.cave.grass_blue_short-3", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_short-4", + model: "voxygen.voxel.sprite.cave.grass_blue_short-4", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ], wind_sway: 0.0, )), -// Medium Cavern Grass Blue -CavernGrassBlueMedium: Some(( +// Medium Grass Blue +GrassBlueMedium: Some(( variations: [ ( - model: "voxygen.voxel.sprite.cavern.grass_med-0", + model: "voxygen.voxel.sprite.cave.grass_blue_med-0", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_med-1", + model: "voxygen.voxel.sprite.cave.grass_blue_med-1", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_med-2", + model: "voxygen.voxel.sprite.cave.grass_blue_med-2", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_med-3", + model: "voxygen.voxel.sprite.cave.grass_blue_med-3", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ], wind_sway: 0.0, )), -// Long Cavern Grass Blue -CavernGrassBlueLong: Some(( +// Long Grass Blue +GrassBlueLong: Some(( variations: [ ( - model: "voxygen.voxel.sprite.cavern.grass_long-0", + model: "voxygen.voxel.sprite.cave.grass_blue_long-0", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_long-1", + model: "voxygen.voxel.sprite.cave.grass_blue_long-1", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_long-2", + model: "voxygen.voxel.sprite.cave.grass_blue_long-2", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_long-3", + model: "voxygen.voxel.sprite.cave.grass_blue_long-3", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_long-4", + model: "voxygen.voxel.sprite.cave.grass_blue_long-4", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_long-5", + model: "voxygen.voxel.sprite.cave.grass_blue_long-5", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_long-6", + model: "voxygen.voxel.sprite.cave.grass_blue_long-6", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.grass_long-7", + model: "voxygen.voxel.sprite.cave.grass_blue_long-7", offset: (-5.5, -5.5, 0.0), lod_axes: (0.0, 0.0, 1.0), ), @@ -4247,27 +4641,27 @@ CavernLillypadBlue: Some(( ], wind_sway: 0.0, )), -// Cavern Hanging Mycel Blue -CavernMycelBlue: Some(( +// Cave Hanging Mycel Blue +MycelBlue: Some(( variations: [ ( - model: "voxygen.voxel.sprite.cavern.mycel-0", - offset: (-0.5, -0.5, -21.0), + model: "voxygen.voxel.sprite.cave.ceiling.mycel-0", + offset: (-1.0, -1.0, -12.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.mycel-1", - offset: (-0.5, -0.5, -31.0), + model: "voxygen.voxel.sprite.cave.ceiling.mycel-1", + offset: (-1.0, -1.0, -25.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.mycel-2", - offset: (-0.5, -0.5, -14.0), + model: "voxygen.voxel.sprite.cave.ceiling.mycel-2", + offset: (-1.0, -1.0, -18.0), lod_axes: (0.0, 0.0, 1.0), ), ( - model: "voxygen.voxel.sprite.cavern.mycel-3", - offset: (-0.5, -0.5, -40.0), + model: "voxygen.voxel.sprite.cave.ceiling.mycel-3", + offset: (-1.0, -1.0, -29.0), lod_axes: (0.0, 0.0, 1.0), ), ], diff --git a/common/net/src/msg/compression.rs b/common/net/src/msg/compression.rs index 8428ca416c..beed5715a0 100644 --- a/common/net/src/msg/compression.rs +++ b/common/net/src/msg/compression.rs @@ -671,6 +671,11 @@ impl VoxelImageDecoding for TriPngEncoding Rgb { + r: 93, + g: 206, + b: 64, + }, GlowingMushroom => Rgb { r: 50, g: 250, diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index a026152fab..6fc0824ac0 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -1118,7 +1118,10 @@ impl Body { | object::Body::Flamethrower | object::Body::TerracottaStatue ), - Body::QuadrupedLow(q) => matches!(q.species, quadruped_low::Species::Lavadrake), + Body::QuadrupedLow(q) => matches!( + q.species, + quadruped_low::Species::Lavadrake | quadruped_low::Species::Salamander + ), Body::BirdLarge(b) => matches!( b.species, bird_large::Species::Phoenix diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index bd2a4bc06a..d89cad8c6b 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -55,6 +55,7 @@ make_case_elim!( Leaves = 0x41, GlowingMushroom = 0x42, Ice = 0x43, + ArtLeaves = 0x44, // 0x43 <= x < 0x50 is reserved for future tree parts // Covers all other cases (we sometimes have bizarrely coloured misc blocks, and also we // often want to experiment with new kinds of block without allocating them a @@ -354,7 +355,10 @@ impl Block { | SpriteKind::Turnip => Some(rtsim::ChunkResource::Vegetable), SpriteKind::Mushroom | SpriteKind::CaveMushroom - | SpriteKind::CeilingMushroom => Some(rtsim::ChunkResource::Mushroom), + | SpriteKind::CeilingMushroom + | SpriteKind::RockyMushroom + | SpriteKind::LushMushroom + | SpriteKind::GlowMushroom => Some(rtsim::ChunkResource::Mushroom), SpriteKind::Chest | SpriteKind::ChestBuried @@ -393,15 +397,21 @@ impl Block { SpriteKind::DiamondLight => 30, SpriteKind::Velorite | SpriteKind::VeloriteFrag - | SpriteKind::CavernGrassBlueShort - | SpriteKind::CavernGrassBlueMedium - | SpriteKind::CavernGrassBlueLong + | SpriteKind::GrassBlueShort + | SpriteKind::GrassBlueMedium + | SpriteKind::GrassBlueLong | SpriteKind::CavernLillypadBlue - | SpriteKind::CavernMycelBlue + | SpriteKind::MycelBlue + | SpriteKind::Mold | SpriteKind::CeilingMushroom => 6, SpriteKind::CaveMushroom + | SpriteKind::GlowMushroom | SpriteKind::CookingPot | SpriteKind::CrystalHigh + | SpriteKind::LanternFlower + | SpriteKind::CeilingLanternFlower + | SpriteKind::LanternPlant + | SpriteKind::CeilingLanternPlant | SpriteKind::CrystalLow => 10, SpriteKind::SewerMushroom => 16, SpriteKind::Amethyst @@ -442,6 +452,7 @@ impl Block { match self.kind() { BlockKind::Water => (0, 0.4), BlockKind::Leaves => (9, 255.0), + BlockKind::ArtLeaves => (9, 255.0), BlockKind::Wood => (6, 2.0), BlockKind::Snow => (6, 2.0), BlockKind::ArtSnow => (6, 2.0), @@ -479,6 +490,7 @@ impl Block { // so all is good for empty fluids. match self.kind() { BlockKind::Leaves => Some(0.25), + BlockKind::ArtLeaves => Some(0.25), BlockKind::Grass => Some(0.5), BlockKind::WeakRock => Some(0.75), BlockKind::Snow => Some(0.1), diff --git a/common/src/terrain/sprite.rs b/common/src/terrain/sprite.rs index a5773b7da8..9eafd13111 100644 --- a/common/src/terrain/sprite.rs +++ b/common/src/terrain/sprite.rs @@ -160,41 +160,46 @@ sprites! { LargeCactus = 0x05, TallCactus = 0x06, // Flowers - BlueFlower = 0x10, - PinkFlower = 0x11, - PurpleFlower = 0x12, - RedFlower = 0x13, - WhiteFlower = 0x14, - YellowFlower = 0x15, - Sunflower = 0x16, - Moonbell = 0x17, - Pyrebloom = 0x18, + BlueFlower = 0x10, + PinkFlower = 0x11, + PurpleFlower = 0x12, + RedFlower = 0x13, + WhiteFlower = 0x14, + YellowFlower = 0x15, + Sunflower = 0x16, + Moonbell = 0x17, + Pyrebloom = 0x18, + LushFlower = 0x19, + LanternFlower = 0x1A, // Grasses, ferns, and other 'wild' plants/fungi // TODO: remove sizes, make part of the `Growth` attribute - LongGrass = 0x20, - MediumGrass = 0x21, - ShortGrass = 0x22, - Fern = 0x23, - LargeGrass = 0x24, - GrassSnow = 0x25, - Reed = 0x26, - GrassBlue = 0x27, - SavannaGrass = 0x28, - TallSavannaGrass = 0x29, - RedSavannaGrass = 0x2A, - SavannaBush = 0x2B, - Welwitch = 0x2C, - LeafyPlant = 0x2D, - DeadBush = 0x2E, - JungleFern = 0x2F, - CavernGrassBlueShort = 0x30, - CavernGrassBlueMedium = 0x31, - CavernGrassBlueLong = 0x32, - CavernLillypadBlue = 0x33, - EnsnaringVines = 0x34, - LillyPads = 0x35, - JungleLeafyPlant = 0x36, - JungleRedGrass = 0x37, + LongGrass = 0x20, + MediumGrass = 0x21, + ShortGrass = 0x22, + Fern = 0x23, + LargeGrass = 0x24, + GrassSnow = 0x25, + Reed = 0x26, + GrassBlue = 0x27, + SavannaGrass = 0x28, + TallSavannaGrass = 0x29, + RedSavannaGrass = 0x2A, + SavannaBush = 0x2B, + Welwitch = 0x2C, + LeafyPlant = 0x2D, + DeadBush = 0x2E, + JungleFern = 0x2F, + GrassBlueShort = 0x30, + GrassBlueMedium = 0x31, + GrassBlueLong = 0x32, + CavernLillypadBlue = 0x33, + EnsnaringVines = 0x34, + LillyPads = 0x35, + JungleLeafyPlant = 0x36, + JungleRedGrass = 0x37, + LanternPlant = 0x38, + SporeReed = 0x39, + DeadPlant = 0x3A, // Crops, berries, and fungi Corn = 0x40, WheatYellow = 0x41, @@ -213,6 +218,9 @@ sprites! { Cotton = 0x4E, WildFlax = 0x4F, SewerMushroom = 0x50, + LushMushroom = 0x51, + RockyMushroom = 0x52, + GlowMushroom = 0x53, // Seaweeds, corals, and other underwater plants StonyCoral = 0x60, SoftCoral = 0x61, @@ -227,9 +235,14 @@ sprites! { Seagrass = 0x6A, RedAlgae = 0x6B, // Danglying ceiling plants/fungi - Liana = 0x70, - CavernMycelBlue = 0x71, - CeilingMushroom = 0x72, + Liana = 0x70, + MycelBlue = 0x71, + CeilingMushroom = 0x72, + Mold = 0x73, + Root = 0x74, + CeilingLanternPlant = 0x75, + CeilingLanternFlower = 0x76, + CeilingJungleLeafyPlant = 0x77, }, // Solid resources // TODO: Remove small variants, make deposit size be an attribute diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 32b101145d..2b300b01c1 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -137,7 +137,11 @@ impl VoxelMinimap { // since otherwise trees would cause ceiling removal to trigger // when running under a branch. let is_filled = block.map_or(true, |b| { - b.is_filled() && !matches!(b.kind(), BlockKind::Leaves | BlockKind::Wood) + b.is_filled() + && !matches!( + b.kind(), + BlockKind::Leaves | BlockKind::ArtLeaves | BlockKind::Wood + ) }); let rgba = rgba.unwrap_or_else(|| Rgba::new(0, 0, 0, 255)); (rgba, is_filled) diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs index 9fd14f365f..cecd1fe823 100644 --- a/voxygen/src/render/pipelines/particle.rs +++ b/voxygen/src/render/pipelines/particle.rs @@ -111,6 +111,7 @@ pub enum ParticleMode { PhoenixBuildUpAim = 57, ClayShrapnel = 58, Airflow = 59, + Spore = 60, } impl ParticleMode { diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 498f9cc1bd..f24f7b76f9 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -2186,6 +2186,14 @@ impl ParticleMgr { mode: ParticleMode::PortalFizz, cond: |_| true, }, + BlockParticles { + blocks: |boi| BlockParticleSlice::Positions(&boi.spores), + range: 4, + rate: 0.055, + lifetime: 20.0, + mode: ParticleMode::Spore, + cond: |_| true, + }, ]; let ecs = scene_data.state.ecs(); diff --git a/voxygen/src/scene/terrain/watcher.rs b/voxygen/src/scene/terrain/watcher.rs index 9c0ba54f01..1dcd37a369 100644 --- a/voxygen/src/scene/terrain/watcher.rs +++ b/voxygen/src/scene/terrain/watcher.rs @@ -49,6 +49,7 @@ pub struct BlocksOfInterest { pub flowers: Vec>, pub fire_bowls: Vec>, pub snow: Vec>, + pub spores: Vec>, //This is so crickets stay in place and don't randomly change sounds pub cricket1: Vec>, pub cricket2: Vec>, @@ -97,6 +98,7 @@ impl BlocksOfInterest { let mut cricket3 = Vec::new(); let mut frogs = Vec::new(); let mut one_way_walls = Vec::new(); + let mut spores = Vec::new(); let mut rng = ChaCha8Rng::from_seed(thread_rng().gen()); @@ -138,6 +140,7 @@ impl BlocksOfInterest { lavapool.push(pos) } }, + BlockKind::GlowingMushroom if rng.gen_range(0..8) == 0 => spores.push(pos), BlockKind::Snow | BlockKind::Ice if rng.gen_range(0..16) == 0 => snow.push(pos), _ => { if let Some(sprite) = block.get_sprite() { @@ -163,7 +166,6 @@ impl BlocksOfInterest { SpriteKind::StreetLampTall => fire_bowls.push(pos + Vec3::unit_z() * 4), SpriteKind::WallSconce => fire_bowls.push(pos + Vec3::unit_z()), SpriteKind::Beehive => beehives.push(pos), - SpriteKind::CrystalHigh => fireflies.push(pos), SpriteKind::Reed => { reeds.push(pos); fireflies.push(pos); @@ -226,6 +228,8 @@ impl BlocksOfInterest { SpriteKind::Sign | SpriteKind::HangingSign => { interactables.push((pos, Interaction::Read)) }, + SpriteKind::MycelBlue => spores.push(pos), + SpriteKind::Mold => spores.push(pos), _ => {}, } } @@ -269,6 +273,7 @@ impl BlocksOfInterest { flowers, fire_bowls, snow, + spores, cricket1, cricket2, cricket3, diff --git a/world/Cargo.toml b/world/Cargo.toml index 2b13bb50cd..fadad33856 100644 --- a/world/Cargo.toml +++ b/world/Cargo.toml @@ -39,7 +39,7 @@ packed_simd = { version = "0.3.9", optional = true } rayon = { workspace = true } serde = { workspace = true } ron = { workspace = true } -inline_tweak = { workspace = true } +# inline_tweak = { workspace = true, features = ["derive"] } kiddo = "0.2" strum = { workspace = true } diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index d7705dd6de..233f83d8a6 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -34,7 +34,7 @@ impl<'a> BlockGen<'a> { pub fn sample_column<'b>( column_gen: &ColumnGen<'a>, - cache: &'b mut SmallCache>>, + cache: &'b mut SmallCache, Option>>, wpos: Vec2, index: IndexRef<'a>, calendar: Option<&'a Calendar>, diff --git a/world/src/index.rs b/world/src/index.rs index 5fdaa6bff9..8f50d9b87c 100644 --- a/world/src/index.rs +++ b/world/src/index.rs @@ -9,7 +9,7 @@ use common::{ trade::{SiteId, SitePrices}, }; use core::ops::Deref; -use noise::{Fbm, Seedable, SuperSimplex}; +use noise::{Fbm, MultiFractal, Seedable, SuperSimplex}; use std::sync::Arc; const WORLD_COLORS_MANIFEST: &str = "world.style.colors"; @@ -144,7 +144,7 @@ impl Noise { Self { cave_nz: SuperSimplex::new().set_seed(seed + 0), scatter_nz: SuperSimplex::new().set_seed(seed + 1), - cave_fbm_nz: Fbm::new().set_seed(seed + 2), + cave_fbm_nz: Fbm::new().set_seed(seed + 2).set_octaves(5), } } } diff --git a/world/src/layer/cave.rs b/world/src/layer/cave.rs index c8521f4749..a7ce750ff9 100644 --- a/world/src/layer/cave.rs +++ b/world/src/layer/cave.rs @@ -1,21 +1,24 @@ -use super::scatter::close; - use crate::{ - util::{sampler::Sampler, FastNoise, RandomField, RandomPerm, StructureGen2d, LOCALITY}, + site::SiteKind, + util::{ + close_fast as close, sampler::Sampler, FastNoise2d, RandomField, RandomPerm, SmallCache, + StructureGen2d, LOCALITY, SQUARE_4, + }, Canvas, CanvasInfo, ColumnSample, Land, }; use common::{ generation::EntityInfo, terrain::{ quadratic_nearest_point, river_spline_coeffs, Block, BlockKind, CoordinateConversions, - SpriteKind, + SpriteKind, TerrainChunkSize, }, + vol::RectVolSize, }; +use itertools::Itertools; use noise::NoiseFn; use rand::prelude::*; use std::{ cmp::Ordering, - collections::HashMap, f64::consts::PI, ops::{Add, Mul, Range, Sub}, }; @@ -38,6 +41,8 @@ fn to_wpos(cell: Vec2, level: u32) -> Vec2 { const AVG_LEVEL_DEPTH: i32 = 120; const LAYERS: u32 = 4; +const MIN_RADIUS: f32 = 8.0; +const MAX_RADIUS: f32 = 64.0; fn node_at(cell: Vec2, level: u32, land: &Land) -> Option { let rand = RandomField::new(37 + level); @@ -75,6 +80,7 @@ pub fn surface_entrances<'a>(land: &'a Land) -> impl Iterator> .filter_map(|cell| Some(tunnel_below_from_cell(cell, 0, land)?.a.wpos)) } +#[derive(Copy, Clone)] pub struct Tunnel { a: Node, b: Node, @@ -90,53 +96,76 @@ impl Tunnel { .map(|e| e as f32) } - fn z_range_at(&self, wposf: Vec2, info: CanvasInfo) -> Option<(Range, f64)> { + fn possibly_near(&self, wposf: Vec2, threshold: f64) -> Option<(f64, Vec2, f64)> { let start = self.a.wpos.map(|e| e as f64 + 0.5); let end = self.b.wpos.map(|e| e as f64 + 0.5); - if let Some((t, closest, _)) = quadratic_nearest_point( &river_spline_coeffs(start, self.ctrl_offset(), end), wposf, Vec2::new(start, end), ) { - let dist = closest.distance(wposf); - let radius = 8.0..64.0; - if dist < radius.end + 1.0 { - let radius = Lerp::lerp( - radius.start, - radius.end, - (info.index().noise.cave_fbm_nz.get( - (wposf.with_z(info.land().get_alt_approx(self.a.wpos) as f64) / 200.0) - .into_array(), - ) * 2.0 - * 0.5 - + 0.5) - .clamped(0.0, 1.0) - .powf(3.0), - ); - let height_here = (1.0 - dist / radius).max(0.0).powf(0.3) * radius; - if height_here > 0.0 { - let z_offs = info - .index() - .noise - .cave_fbm_nz - .get((wposf / 512.0).into_array()) - * 96.0 - * ((1.0 - (t - 0.5).abs() * 2.0) * 8.0).min(1.0); - let alt_here = info.land().get_alt_approx(closest.map(|e| e as i32)); - let base = (Lerp::lerp( - alt_here as f64 - self.a.depth as f64, - alt_here as f64 - self.b.depth as f64, - t, - ) + z_offs) - .min(alt_here as f64); - Some(( - (base - height_here * 0.3) as i32..(base + height_here * 1.35) as i32, - radius, - )) - } else { - None - } + let dist2 = closest.distance_squared(wposf); + if dist2 < (MAX_RADIUS as f64 + threshold).powi(2) { + Some((t, closest, dist2.sqrt())) + } else { + None + } + } else { + None + } + } + + fn z_range_at( + &self, + wposf: Vec2, + info: CanvasInfo, + ) -> Option<(Range, f32, f32, f32)> { + let _start = self.a.wpos.map(|e| e as f64 + 0.5); + let _end = self.b.wpos.map(|e| e as f64 + 0.5); + if let Some((t, closest, dist)) = self.possibly_near(wposf, 1.0) { + let horizontal = Lerp::lerp_unclamped( + MIN_RADIUS as f64, + MAX_RADIUS as f64, + (info.index().noise.cave_fbm_nz.get( + (closest.with_z(info.land().get_alt_approx(self.a.wpos) as f64) / 256.0) + .into_array(), + ) + 0.5) + .clamped(0.0, 1.0) + .powf(3.0), + ); + let vertical = Lerp::lerp_unclamped( + MIN_RADIUS as f64, + MAX_RADIUS as f64, + (info.index().noise.cave_fbm_nz.get( + (closest.with_z(info.land().get_alt_approx(self.b.wpos) as f64) / 256.0) + .into_array(), + ) + 0.5) + .clamped(0.0, 1.0) + .powf(3.0), + ); + let height_here = (1.0 - dist / horizontal).max(0.0).powf(0.3) * vertical; + + if height_here > 0.0 { + let z_offs = info + .index() + .noise + .cave_fbm_nz + .get((wposf / 512.0).into_array()) + * 96.0 + * ((1.0 - (t - 0.5).abs() * 2.0) * 8.0).min(1.0); + let alt_here = info.land().get_alt_approx(closest.map(|e| e as i32)); + let base = (Lerp::lerp_unclamped( + alt_here as f64 - self.a.depth as f64, + alt_here as f64 - self.b.depth as f64, + t, + ) + z_offs) + .min(alt_here as f64); + Some(( + (base - height_here * 0.3) as i32..(base + height_here * 1.35) as i32, + horizontal as f32, + vertical as f32, + dist as f32, + )) } else { None } @@ -151,54 +180,95 @@ impl Tunnel { }; // Below the ground - let below = ((col.alt - wpos.z as f32) / 120.0).clamped(0.0, 1.0); + let below = ((col.alt - wpos.z as f32) / (AVG_LEVEL_DEPTH as f32 * 2.0)).clamped(0.0, 1.0); let depth = (col.alt - wpos.z as f32) / (AVG_LEVEL_DEPTH as f32 * LAYERS as f32); + let underground = ((col.alt - wpos.z as f32) / 80.0 - 1.0).clamped(0.0, 1.0); - let humidity = Lerp::lerp( + // TODO think about making rate of change of humidity and temp noise higher to + // effectively increase biome size + let humidity = Lerp::lerp_unclamped( col.humidity, - info.index() - .noise - .cave_nz - .get(wpos.xy().map(|e| e as f64 / 1024.0).into_array()) as f32, + FastNoise2d::new(41) + .get(wpos.xy().map(|e| e as f64 / 768.0)) + .mul(1.2), below, ); - let temp = Lerp::lerp( + + let temp = Lerp::lerp_unclamped( col.temp, - info.index() - .noise - .cave_nz - .get(wpos.xy().map(|e| e as f64 / 2048.0).into_array()) + FastNoise2d::new(42) + .get(wpos.xy().map(|e| e as f64 / 1536.0)) + .mul(1.15) .mul(2.0) .sub(1.0) .add( - ((col.alt as f64 - wpos.z as f64) - / (AVG_LEVEL_DEPTH as f64 * LAYERS as f64 * 0.5)) + ((col.alt - wpos.z as f32) / (AVG_LEVEL_DEPTH as f32 * LAYERS as f32 * 0.75)) .clamped(0.0, 2.5), - ) as f32, + ), below, ); - let mineral = info - .index() - .noise - .cave_nz - .get(wpos.xy().map(|e| e as f64 / 256.0).into_array()) + + let mineral = FastNoise2d::new(43) + .get(wpos.xy().map(|e| e as f64 / 256.0)) + .mul(1.15) .mul(0.5) - .add(0.5) as f32; + .add( + ((col.alt - wpos.z as f32) / (AVG_LEVEL_DEPTH as f32 * LAYERS as f32)) + .clamped(0.0, 1.5), + ); - let underground = ((col.alt - wpos.z as f32) / 80.0 - 1.0).clamped(0.0, 1.0); - - let [barren, mushroom, fire, leafy, dusty, icy] = { + let [ + barren, + mushroom, + fire, + leafy, + dusty, + icy, + snowy, + crystal, + sandy, + ] = { + // Default biome, no other conditions apply let barren = 0.01; - let mushroom = underground * close(humidity, 1.0, 0.75) * close(temp, 0.0, 0.9); + // Mushrooms grow underground and thrive in a humid environment with moderate + // temperatures + let mushroom = underground + * close(humidity, 1.0, 0.7, 3) + * close(temp, 1.5, 0.9, 3) + * close(depth, 1.0, 0.6, 3); + // Extremely hot and dry areas deep underground let fire = underground - * close(humidity, 0.0, 0.9) - * close(temp, 2.0, 1.0) - * close(depth, 1.0, 0.65); - let leafy = underground * close(humidity, 1.0, 0.85) * close(temp, 0.45, 0.8); - let dusty = close(humidity, 0.0, 0.5) * close(temp, -0.3, 0.5); - let icy = close(temp, -1.0, 0.3); + * close(humidity, 0.0, 0.6, 3) + * close(temp, 2.0, 1.3, 3) + * close(depth, 1.0, 0.55, 3); + // Overgrown with plants that need a moderate climate to survive + let leafy = underground + * close(humidity, 0.8, 0.8, 3) + * close(temp, 0.95, 0.85, 3) + * close(depth, 0.0, 0.6, 3); + // Cool temperature, dry and devoid of value + let dusty = close(humidity, 0.0, 0.5, 3) * close(temp, -0.1, 0.6, 3); + // Deep underground and freezing cold + let icy = underground + * close(temp, -1.5, 1.3, 3) + * close(depth, 1.0, 0.65, 3) + * close(humidity, 1.0, 0.7, 3); + // Rocky cold cave that appear near the surface + let snowy = close(temp, -0.6, 0.5, 3) * close(depth, 0.0, 0.45, 3); + // Crystals grow deep underground in areas rich with minerals. They are present + // in areas with colder temperatures and low humidity + let crystal = underground + * close(humidity, 0.0, 0.5, 3) + * close(temp, -0.6, 0.75, 3) + * close(depth, 1.0, 0.55, 3) + * close(mineral, 2.0, 1.25, 3); + // Hot, dry and shallow + let sandy = + close(humidity, 0.0, 0.3, 3) * close(temp, 0.7, 0.9, 3) * close(depth, 0.0, 0.6, 3); - let biomes = [barren, mushroom, fire, leafy, dusty, icy]; + let biomes = [ + barren, mushroom, fire, leafy, dusty, icy, snowy, crystal, sandy, + ]; let max = biomes .into_iter() .max_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)) @@ -215,6 +285,9 @@ impl Tunnel { leafy, dusty, icy, + snowy, + crystal, + sandy, depth, } } @@ -287,70 +360,127 @@ fn tunnels_down_from<'a>( .filter_map(move |rpos| tunnel_below_from_cell(col_cell + rpos, level, land)) } +fn all_tunnels_at<'a>( + wpos2d: Vec2, + _info: &'a CanvasInfo, + land: &'a Land, +) -> impl Iterator + 'a { + (1..LAYERS + 1).flat_map(move |level| { + tunnels_at(wpos2d, level, land) + .chain(tunnels_down_from(wpos2d, level - 1, land)) + .map(move |tunnel| (level, tunnel)) + }) +} + +fn tunnel_bounds_at_from<'a>( + wpos2d: Vec2, + info: &'a CanvasInfo, + _land: &'a Land, + tunnels: impl Iterator + 'a, +) -> impl Iterator, f32, f32, f32, Tunnel)> + 'a { + let wposf = wpos2d.map(|e| e as f64 + 0.5); + info.col_or_gen(wpos2d) + .map(move |col| { + let col_alt = col.alt; + let col_water_dist = col.water_dist; + tunnels.filter_map(move |(level, tunnel)| { + let (z_range, horizontal, vertical, dist) = tunnel.z_range_at(wposf, *info)?; + // Avoid cave entrances intersecting water + let z_range = Lerp::lerp_unclamped( + z_range.end, + z_range.start, + 1.0 - (1.0 + - ((col_water_dist.unwrap_or(1000.0) - 4.0).max(0.0) / 32.0) + .clamped(0.0, 1.0)) + * (1.0 - ((col_alt - z_range.end as f32 - 4.0) / 8.0).clamped(0.0, 1.0)), + )..z_range.end; + if z_range.end - z_range.start > 0 { + Some((level, z_range, horizontal, vertical, dist, tunnel)) + } else { + None + } + }) + }) + .into_iter() + .flatten() +} + pub fn tunnel_bounds_at<'a>( wpos2d: Vec2, info: &'a CanvasInfo, land: &'a Land, -) -> impl Iterator, f64, Tunnel)> + 'a { - let wposf = wpos2d.map(|e| e as f64 + 0.5); - info.col_or_gen(wpos2d).into_iter().flat_map(move |col| { - let col_alt = col.alt; - let col_water_dist = col.water_dist; - (1..LAYERS + 1).flat_map(move |level| { - tunnels_at(wpos2d, level, land) - .chain(tunnels_down_from(wpos2d, level - 1, land)) - .filter_map(move |tunnel| { - let (z_range, radius) = tunnel.z_range_at(wposf, *info)?; - // Avoid cave entrances intersecting water - let z_range = Lerp::lerp( - z_range.end, - z_range.start, - 1.0 - (1.0 - - ((col_water_dist.unwrap_or(1000.0) - 4.0).max(0.0) / 32.0) - .clamped(0.0, 1.0)) - * (1.0 - - ((col_alt - z_range.end as f32 - 4.0) / 8.0).clamped(0.0, 1.0)), - )..z_range.end; - if z_range.end - z_range.start > 0 { - Some((level, z_range, radius, tunnel)) - } else { - None - } - }) - }) - }) +) -> impl Iterator, f32, f32, f32, Tunnel)> + 'a { + tunnel_bounds_at_from(wpos2d, info, land, all_tunnels_at(wpos2d, info, land)) } pub fn apply_caves_to(canvas: &mut Canvas, rng: &mut impl Rng) { let info = canvas.info(); - let mut mushroom_cache = HashMap::new(); - canvas.foreach_col(|canvas, wpos2d, col| { - let land = info.land(); + let land = info.land(); - let tunnel_bounds = tunnel_bounds_at(wpos2d, &info, &land).collect::>(); + let diagonal = (TerrainChunkSize::RECT_SIZE.map(|e| e * e).sum() as f32).sqrt() as f64; + let tunnels = all_tunnels_at( + info.wpos() + TerrainChunkSize::RECT_SIZE.map(|e| e as i32) / 2, + &info, + &land, + ) + .filter(|(_, tunnel)| { + SQUARE_4 + .into_iter() + .map(|rpos| info.wpos() + rpos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32)) + .any(|wpos| { + tunnel + .possibly_near(wpos.map(|e| e as f64), diagonal + 1.0) + .is_some() + }) + }) + .collect::>(); + if !tunnels.is_empty() { + let giant_tree_dist = info + .chunk + .sites + .iter() + .filter_map(|site| { + if let SiteKind::GiantTree(t) = &info.index.sites.get(*site).kind { + Some(t.origin.distance_squared(info.wpos) as f32 / t.radius().powi(2)) + } else { + None + } + }) + .max_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)) + .unwrap_or(0.0) + .clamp(0.0, 1.0); + let mut structure_cache = SmallCache::default(); + canvas.foreach_col(|canvas, wpos2d, col| { + let tunnel_bounds = + tunnel_bounds_at_from(wpos2d, &info, &land, tunnels.iter().copied()) + .collect::>(); - // First, clear out tunnels - for (_, z_range, _, _) in &tunnel_bounds { - for z in z_range.start..z_range.end.min(col.alt as i32 + 1) { - canvas.set(wpos2d.with_z(z), Block::air(SpriteKind::Empty)); + // First, clear out tunnels + for (_, z_range, _, _, _, _) in &tunnel_bounds { + for z in z_range.start..z_range.end.min(col.alt as i32 + 1) { + canvas.set(wpos2d.with_z(z), Block::empty()); + } } - } - for (level, z_range, _radius, tunnel) in tunnel_bounds { - write_column( - canvas, - col, - level, - wpos2d, - z_range.clone(), - tunnel, - &mut mushroom_cache, - rng, - ); - } - }); + for (level, z_range, horizontal, vertical, dist, tunnel) in tunnel_bounds { + write_column( + canvas, + col, + level, + wpos2d, + z_range.clone(), + tunnel, + (horizontal, vertical, dist), + giant_tree_dist, + &mut structure_cache, + rng, + ); + } + }); + } } +#[allow(dead_code)] #[derive(Default)] struct Biome { humidity: f32, @@ -361,15 +491,50 @@ struct Biome { leafy: f32, dusty: f32, icy: f32, + snowy: f32, + crystal: f32, + sandy: f32, depth: f32, } +enum CaveStructure { + Mushroom(Mushroom), + Crystal(CrystalCluster), + Flower(Flower), + GiantRoot { + pos: Vec3, + radius: f32, + height: f32, + }, +} + struct Mushroom { pos: Vec3, stalk: f32, head_color: Rgb, } +struct Crystal { + dir: Vec3, + length: f32, + radius: f32, +} + +struct CrystalCluster { + pos: Vec3, + crystals: Vec, + color: Rgb, +} + +struct Flower { + pos: Vec3, + stalk: f32, + petals: usize, + petal_height: f32, + petal_radius: f32, + // rotation: Mat3, +} + fn write_column( canvas: &mut Canvas, col: &ColumnSample, @@ -377,10 +542,11 @@ fn write_column( wpos2d: Vec2, z_range: Range, tunnel: Tunnel, - mushroom_cache: &mut HashMap<(Vec3, Vec2), Option>, + dimensions: (f32, f32, f32), + giant_tree_factor: f32, + structure_cache: &mut SmallCache, Option>, rng: &mut R, ) { - mushroom_cache.clear(); let info = canvas.info(); // Exposed to the sky, or some other void above @@ -388,84 +554,218 @@ fn write_column( let void_below = !canvas.get(wpos2d.with_z(z_range.start - 1)).is_filled(); // Exposed to the sky let sky_above = z_range.end as f32 > col.alt; - + let cavern_height = (z_range.end - z_range.start) as f32; + let (cave_width, max_height, dist_cave_center) = dimensions; let biome = tunnel.biome_at(wpos2d.with_z(z_range.start), &info); let stalactite = { - let cavern_height = (z_range.end - z_range.start) as f64; - info - .index() - .noise - .cave_nz - .get(wpos2d.map(|e| e as f64 / 16.0).into_array()) + FastNoise2d::new(35) + .get(wpos2d.map(|e| e as f64 / 8.0)) .sub(0.5) .max(0.0) .mul(2.0) + .powi(if biome.icy > 0.7 {2} else {1}) // No stalactites near entrances - .mul(((col.alt as f64 - z_range.end as f64) / 8.0).clamped(0.0, 1.0)) - .mul(8.0 + cavern_height * 0.4) + .mul(((col.alt - z_range.end as f32) / 32.0).clamped(0.0, 1.0)) + // Prevent stalactites from blocking cave + .mul(((cave_width + max_height) / 40.0).clamped(0.0, 1.0)) + // Scale with cavern height, sandy and icy biomes have bigger stalactites + .mul(8.0 + cavern_height * (0.4 + (biome.sandy - 0.5).max(biome.icy - 0.6).max(0.0))) + }; + + let ceiling_cover = if biome.leafy > 0.3 + || biome.mushroom > 0.5 + || biome.icy > 0.6 + || biome.sandy > 0.4 + || biome.fire > 0.4 + || biome.crystal > 0.75 + { + // 1.0 because at some point we maybe want to use some noise value here instead + 1.0.mul(((col.alt - z_range.end as f32) / 32.0).clamped(0.0, 1.0)) + .mul(max_height * (dist_cave_center / cave_width).powf(3.33)) + .max(1.0) + .sub( + if col.marble_mid + > biome + .fire + .max(biome.icy - 0.6) + .max(biome.sandy - 0.3) + .max(biome.leafy - 0.4) + .max(biome.mushroom - 0.4) + .max(biome.crystal - 0.5) + { + max_height * col.marble_mid + } else { + 0.0 + }, + ) + .max(0.0) + } else { + 0.0 }; let basalt = if biome.fire > 0.0 { - let cavern_height = (z_range.end - z_range.start) as f64; - info.index() - .noise - .cave_nz - .get(wpos2d.map(|e| e as f64 / 48.0).into_array()) + FastNoise2d::new(36) + .get(wpos2d.map(|e| e as f64 / 32.0)) + .mul(1.25) .sub(0.5) .max(0.0) + .mul(((cave_width + max_height) / 32.0).clamped(0.0, 1.0)) .mul(6.0 + cavern_height * 0.5) - .mul(biome.fire as f64) + .mul(biome.fire) } else { 0.0 }; let lava = if biome.fire > 0.0 { - info.index() - .noise - .cave_nz - .get(wpos2d.map(|e| e as f64 / 64.0).into_array()) - .sub(0.5) + FastNoise2d::new(37) + .get(wpos2d.map(|e| e as f64 / 32.0)) + .mul(0.5) .abs() .sub(0.2) .min(0.0) // .mul((biome.temp as f64 - 1.5).mul(30.0).clamped(0.0, 1.0)) - .mul((biome.fire as f64 - 0.5).mul(30.0).clamped(0.0, 1.0)) + .mul((biome.fire - 0.5).mul(30.0).clamped(0.0, 1.0)) .mul(64.0) .max(-32.0) } else { 0.0 }; + let height_factor = (max_height / MAX_RADIUS * 0.5).clamped(0.0, 1.0).powf(2.0); + let width_factor = (cave_width / MAX_RADIUS * 0.5).clamped(0.0, 1.0).powf(2.0); + let ridge = FastNoise2d::new(38) + .get(wpos2d.map(|e| e as f64 / 512.0)) + .sub(0.25) + .max(0.0) + .mul(1.3) + .mul(height_factor) + .mul(width_factor) + .mul( + (0.75 * dist_cave_center) + + max_height * (close(dist_cave_center, cave_width, cave_width * 0.7, 3)), + ) + .mul(((col.alt - z_range.end as f32) / 64.0).clamped(0.0, 1.0)); + + let bump = FastNoise2d::new(39) + .get(wpos2d.map(|e| e as f64 / 4.0)) + .mul(1.15) + .add(1.0) + .mul(0.5) + .mul(((col.alt - z_range.end as f32) / 16.0).clamped(0.0, 1.0)) + .mul({ + let (val, total) = [ + (biome.sandy, 0.9), + (biome.dusty, 0.5), + (biome.leafy, 0.6), + (biome.barren, 0.6), + ] + .into_iter() + .fold((0.0, 0.0), |a, x| (a.0 + x.0.max(0.0) * x.1, a.1 + x.1)); + val / total + }) + .mul(cavern_height * 0.2) + .clamped(0.0, 4.0); + let rand = RandomField::new(37 + level); let is_ice = biome.icy + col.marble * 0.2 > 0.5 && col.marble > 0.6; + let is_snow = biome.snowy + col.marble_mid * 0.2 > 0.5 && col.marble_mid > 0.6; - let dirt = 1 + (!is_ice) as i32; + let (has_stalagmite, has_stalactite) = if biome.icy > 0.5 { + (col.marble_mid > 0.6, col.marble_mid < 0.5) + } else { + (true, true) + }; + + let stalagmite_only = if has_stalagmite && !has_stalactite { + 0.6f32 + } else { + 0.0f32 + }; + + // Don't cover stalgmites in ice biome with surface block + let dirt = if biome.icy > 0.5 && has_stalagmite && stalactite > 3.0 { + 0 + } else { + 1 + (!is_ice) as i32 + is_snow as i32 + }; let bedrock = z_range.start + lava as i32; - let base = bedrock + (stalactite * 0.4) as i32; - let floor = base + dirt; - let ceiling = z_range.end - stalactite as i32; + let ridge_bedrock = bedrock + (ridge * 0.7) as i32; + let base = ridge_bedrock + (stalactite * (0.4 + stalagmite_only)) as i32; + let floor = base + dirt + (ridge * 0.3) as i32 + bump as i32; + let ceiling = + z_range.end - (stalactite * has_stalactite as i32 as f32).max(ceiling_cover) as i32; - // Get mushroom block, if any, at a position - let mut get_mushroom = |wpos: Vec3, dynamic_rng: &mut R| { + let get_ceiling_drip = |wpos: Vec2, freq: f64, length: f32| { + let wposf = wpos.map(|e| e as f32); + let wposf = wposf + wposf.yx() * 1.1; + let dims = Vec2::new(11.0, 32.0); + let posf = wposf + Vec2::unit_y() * (wposf.x / dims.x).floor() * 89.0 / dims; + let pos = posf.map(|e| e.floor() as i32); + if rand.chance(pos.with_z(73), freq as f32) { + let drip_length = ((posf.y.fract() - 0.5).abs() * 2.0 * dims.y) + .mul(length * 0.01) + .powf(2.0) + .min(length); + + if (posf.x.fract() * 2.0 - 1.0).powi(2) < 1.0 { + drip_length + } else { + 0.0 + } + } else { + 0.0 + } + }; + + let ceiling_drip = ceiling + - if !void_above && !sky_above { + let c = if biome.mushroom > 0.9 && ceiling_cover > 0.0 { + Some((0.07, 7.0)) + } else if biome.icy > 0.9 { + Some((0.1 * col.marble_mid as f64, 9.0)) + } else { + None + }; + if let Some((freq, length)) = c { + get_ceiling_drip(wpos2d, freq, length).max(get_ceiling_drip( + wpos2d.yx(), + freq, + length, + )) as i32 + } else { + 0 + } + } else { + 0 + }; + + let mut get_structure = |wpos: Vec3, dynamic_rng: &mut R| { for (wpos2d, seed) in StructureGen2d::new(34537, 24, 8).get(wpos.xy()) { - let mushroom = if let Some(mushroom) = mushroom_cache - .entry((tunnel.a.wpos.with_z(tunnel.a.depth), wpos2d)) - .or_insert_with(|| { + let structure = if let Some(structure) = + structure_cache.get(wpos2d.with_z(tunnel.a.depth), |_| { let mut rng = RandomPerm::new(seed); - let (z_range, radius) = + let (z_range, horizontal, vertical, _) = tunnel.z_range_at(wpos2d.map(|e| e as f64 + 0.5), info)?; let pos = wpos2d.with_z(z_range.start); - if rng.gen_bool(0.5 * close(radius as f32, 64.0, 48.0) as f64) - && tunnel.biome_at(pos, &info).mushroom > 0.5 - // Ensure that we're not placing the mushroom over a void - && !tunnel_bounds_at(pos.xy(), &info, &info.land()) - .any(|(_, z_range, _, _)| z_range.contains(&(z_range.start - 1))) - // && pos.z as i32 > water_level - 2 + + let biome = tunnel.biome_at(pos, &info); + let ground_below = !tunnel_bounds_at(pos.xy(), &info, &info.land()) + .any(|(_, z_range, _, _, _, _)| z_range.contains(&(z_range.start - 1))); + if !ground_below { + return None; + } + + if biome.mushroom > 0.7 + && vertical > 16.0 + && rng.gen_bool( + 0.5 * close(vertical, MAX_RADIUS, MAX_RADIUS - 16.0, 2) as f64 + * close(biome.mushroom, 1.0, 0.7, 1) as f64, + ) { let purp = rng.gen_range(0..50); - Some(Mushroom { + Some(CaveStructure::Mushroom(Mushroom { pos, stalk: 8.0 + rng.gen::().powf(2.0) @@ -476,82 +776,366 @@ fn write_column( rng.gen_range(60..120), rng.gen_range(80..200) + purp, ), + })) + } else if biome.crystal > 0.5 + && rng.gen_bool(0.4 * close(biome.crystal, 1.0, 0.7, 2) as f64) + { + let on_ground = rng.gen_bool(0.6); + let pos = wpos2d.with_z(if on_ground { + z_range.start + } else { + z_range.end + }); + + let mut crystals: Vec = Vec::new(); + let max_length = + (48.0 * close(vertical, MAX_RADIUS, MAX_RADIUS, 1)).max(12.0); + let length = rng.gen_range(8.0..max_length); + let radius = + Lerp::lerp(2.0, 4.5, length / max_length + rng.gen_range(-0.1..0.1)); + let dir = Vec3::new( + rng.gen_range(-3.0..3.0), + rng.gen_range(-3.0..3.0), + rng.gen_range(0.5..10.0) * if on_ground { 1.0 } else { -1.0 }, + ) + .normalized(); + + crystals.push(Crystal { + dir, + length, + radius, + }); + + (0..4).for_each(|_| { + crystals.push(Crystal { + dir: Vec3::new( + rng.gen_range(-1.0..1.0), + rng.gen_range(-1.0..1.0), + (dir.z + rng.gen_range(-0.2..0.2)).clamped(0.0, 1.0), + ), + length: length * rng.gen_range(0.3..0.8), + radius: (radius * rng.gen_range(0.5..0.8)).max(1.0), + }); + }); + + let purple = rng.gen_range(25..75); + let blue = (rng.gen_range(45.0..75.0) * biome.icy) as u8; + + Some(CaveStructure::Crystal(CrystalCluster { + pos, + crystals, + color: Rgb::new( + 255 - blue * 2, + 255 - blue - purple, + 200 + rng.gen_range(25..55), + ), + })) + } else if biome.leafy > 0.8 + && vertical > 16.0 + && horizontal > 8.0 + && rng.gen_bool( + 0.25 * (close(vertical, MAX_RADIUS, MAX_RADIUS - 16.0, 2) + * close(horizontal, MAX_RADIUS, MAX_RADIUS - 8.0, 2) + * biome.leafy) as f64, + ) + { + let petal_radius = rng.gen_range(8.0..16.0); + Some(CaveStructure::Flower(Flower { + pos, + stalk: 6.0 + + rng.gen::().powf(2.0) + * (z_range.end - z_range.start - 8) as f32 + * 0.75, + petals: rng.gen_range(1..5) * 2 + 1, + petal_height: 0.4 * petal_radius * (1.0 + rng.gen::().powf(2.0)), + petal_radius, + })) + } else if (biome.leafy > 0.7 || giant_tree_factor > 0.0) + && rng.gen_bool( + (0.5 * close(biome.leafy, 1.0, 0.5, 1).max(1.0 + giant_tree_factor) + as f64) + .clamped(0.0, 1.0), + ) + { + Some(CaveStructure::GiantRoot { + pos, + radius: rng.gen_range( + 1.5..(3.5 + + close(vertical, MAX_RADIUS, MAX_RADIUS / 2.0, 2) * 3.0 + + close(horizontal, MAX_RADIUS, MAX_RADIUS / 2.0, 2) * 3.0), + ), + height: (z_range.end - z_range.start) as f32, }) } else { None } }) { - mushroom + structure } else { continue; }; - let wposf = wpos.map(|e| e as f64); - let warp_freq = 1.0 / 32.0; - let warp_amp = Vec3::new(12.0, 12.0, 12.0); - let wposf_warped = wposf.map(|e| e as f32) - + Vec3::new( - FastNoise::new(seed).get(wposf * warp_freq), - FastNoise::new(seed + 1).get(wposf * warp_freq), - FastNoise::new(seed + 2).get(wposf * warp_freq), - ) * warp_amp - * (wposf.z as f32 - mushroom.pos.z as f32) - .mul(0.1) - .clamped(0.0, 1.0); + match structure { + CaveStructure::Mushroom(mushroom) => { + let wposf = wpos.map(|e| e as f64); + let warp_freq = 1.0 / 32.0; + let warp_amp = Vec3::new(12.0, 12.0, 12.0); + let xy = wposf.xy(); + let xz = Vec2::new(wposf.x, wposf.z); + let yz = Vec2::new(wposf.y, wposf.z); + let wposf_warped = wposf.map(|e| e as f32) + + Vec3::new( + FastNoise2d::new(seed).get(yz * warp_freq), + FastNoise2d::new(seed).get(xz * warp_freq), + FastNoise2d::new(seed).get(xy * warp_freq), + ) * warp_amp + * (wposf.z as f32 - mushroom.pos.z as f32) + .mul(0.1) + .clamped(0.0, 1.0); - let rpos = wposf_warped - mushroom.pos.map(|e| e as f32); + let rpos = wposf_warped - mushroom.pos.map(|e| e as f32); - let stalk_radius = 2.5f32; - let head_radius = 12.0f32; - let head_height = 14.0; + let stalk_radius = 2.5f32; + let head_radius = 12.0f32; + let head_height = 14.0; - let dist_sq = rpos.xy().magnitude_squared(); - if dist_sq < head_radius.powi(2) { - let dist = dist_sq.sqrt(); - let head_dist = ((rpos - Vec3::unit_z() * mushroom.stalk) - / Vec2::broadcast(head_radius).with_z(head_height)) - .magnitude(); + let dist_sq = rpos.xy().magnitude_squared(); + if dist_sq < head_radius.powi(2) { + let dist = dist_sq.sqrt(); + let head_dist = ((rpos - Vec3::unit_z() * mushroom.stalk) + / Vec2::broadcast(head_radius).with_z(head_height)) + .magnitude(); - let stalk = mushroom.stalk + Lerp::lerp(head_height * 0.5, 0.0, dist / head_radius); + let stalk = mushroom.stalk + + Lerp::lerp_unclamped(head_height * 0.5, 0.0, dist / head_radius); - // Head - if rpos.z > stalk - && rpos.z <= mushroom.stalk + head_height - && dist - < head_radius * (1.0 - (rpos.z - mushroom.stalk) / head_height).powf(0.125) - { - if head_dist < 0.85 { - let radial = (rpos.x.atan2(rpos.y) * 10.0).sin() * 0.5 + 0.5; - return Some(Block::new( - BlockKind::GlowingMushroom, - Rgb::new(30, 50 + (radial * 100.0) as u8, 100 - (radial * 50.0) as u8), - )); - } else if head_dist < 1.0 { - return Some(Block::new(BlockKind::Wood, mushroom.head_color)); - } - } + // Head + if rpos.z > stalk + && rpos.z <= mushroom.stalk + head_height + && dist + < head_radius + * (1.0 - (rpos.z - mushroom.stalk) / head_height).powf(0.125) + { + if head_dist < 0.85 { + let radial = (rpos.x.atan2(rpos.y) * 10.0).sin() * 0.5 + 0.5; + let block_kind = if dynamic_rng.gen_bool(0.1) { + BlockKind::GlowingMushroom + } else { + BlockKind::Rock + }; + return Some(Block::new( + block_kind, + Rgb::new( + 30, + 120 + (radial * 40.0) as u8, + 180 - (radial * 40.0) as u8, + ), + )); + } else if head_dist < 1.0 { + return Some(Block::new(BlockKind::Wood, mushroom.head_color)); + } + } - if rpos.z <= mushroom.stalk + head_height - 1.0 - && dist_sq - < (stalk_radius * Lerp::lerp(1.5, 0.75, rpos.z / mushroom.stalk)).powi(2) - { - // Stalk - return Some(Block::new(BlockKind::Wood, Rgb::new(25, 60, 90))); - } else if ((mushroom.stalk - 0.1)..(mushroom.stalk + 0.9)).contains(&rpos.z) // Hanging orbs + if rpos.z <= mushroom.stalk + head_height - 1.0 + && dist_sq + < (stalk_radius * Lerp::lerp(1.5, 0.75, rpos.z / mushroom.stalk)) + .powi(2) + { + // Stalk + return Some(Block::new(BlockKind::Wood, Rgb::new(25, 60, 90))); + } else if ((mushroom.stalk - 0.1)..(mushroom.stalk + 0.9)).contains(&rpos.z) // Hanging orbs && dist > head_radius * 0.85 && dynamic_rng.gen_bool(0.1) - { - use SpriteKind::*; - let sprites = if dynamic_rng.gen_bool(0.1) { - &[Beehive, Lantern] as &[_] - } else { - &[Orb, CavernMycelBlue, CavernMycelBlue] as &[_] - }; - return Some(Block::air(*sprites.choose(dynamic_rng).unwrap())); - } + { + use SpriteKind::*; + let sprites = if dynamic_rng.gen_bool(0.1) { + &[Beehive, Lantern] as &[_] + } else { + &[MycelBlue, MycelBlue] as &[_] + }; + return Some(Block::air(*sprites.choose(dynamic_rng).unwrap())); + } + } + }, + CaveStructure::Crystal(cluster) => { + let wposf = wpos.map(|e| e as f32); + let cluster_pos = cluster.pos.map(|e| e as f32); + for crystal in &cluster.crystals { + let line = LineSegment3 { + start: cluster_pos, + end: cluster_pos + crystal.dir * crystal.length, + }; + + let projected = line.projected_point(wposf); + let dist_sq = projected.distance_squared(wposf); + if dist_sq < crystal.radius.powi(2) { + let rpos = wposf - cluster_pos; + let line_length = line.start.distance_squared(line.end); + let taper = if line_length < 0.001 { + 0.0 + } else { + rpos.dot(line.end - line.start) / line_length + }; + + let peak_cutoff = 0.8; + let taper_factor = 0.55; + let peak_taper = 0.3; + + let crystal_radius = if taper > peak_cutoff { + let taper = (taper - peak_cutoff) * 5.0; + Lerp::lerp_unclamped( + crystal.radius * taper_factor, + crystal.radius * peak_taper, + taper, + ) + } else { + let taper = taper * 1.25; + Lerp::lerp_unclamped( + crystal.radius, + crystal.radius * taper_factor, + taper, + ) + }; + + if dist_sq < crystal_radius.powi(2) { + if dist_sq / crystal_radius.powi(2) > 0.75 { + return Some(Block::new(BlockKind::GlowingRock, cluster.color)); + } else { + return Some(Block::new(BlockKind::Rock, cluster.color)); + } + } + } + } + }, + CaveStructure::Flower(flower) => { + let wposf = wpos.map(|e| e as f64); + let warp_freq = 1.0 / 16.0; + let warp_amp = Vec3::new(8.0, 8.0, 8.0); + let xy = wposf.xy(); + let xz = Vec2::new(wposf.x, wposf.z); + let yz = Vec2::new(wposf.y, wposf.z); + let wposf_warped = wposf.map(|e| e as f32) + + Vec3::new( + FastNoise2d::new(seed).get(yz * warp_freq), + FastNoise2d::new(seed).get(xz * warp_freq), + FastNoise2d::new(seed).get(xy * warp_freq), + ) * warp_amp + * (wposf.z as f32 - flower.pos.z as f32) + .mul(1.0 / flower.stalk) + .sub(1.0) + .min(0.0) + .abs() + .clamped(0.0, 1.0); + let rpos = wposf_warped - flower.pos.map(|e| e as f32); + + let stalk_radius = 2.5f32; + let petal_thickness = 2.5; + let dist_sq = rpos.xy().magnitude_squared(); + if rpos.z < flower.stalk + && dist_sq + < (stalk_radius + * Lerp::lerp_unclamped(1.0, 0.75, rpos.z / flower.stalk)) + .powi(2) + { + return Some(Block::new(BlockKind::Wood, Rgb::new(0, 108, 0))); + } + + let rpos = rpos - Vec3::unit_z() * flower.stalk; + let dist_sq = rpos.xy().magnitude_squared(); + let petal_radius_sq = flower.petal_radius.powi(2); + if dist_sq < petal_radius_sq { + let petal_height_at = + (dist_sq / petal_radius_sq).powf(1.0) * flower.petal_height; + if rpos.z > petal_height_at - 1.0 + && rpos.z <= petal_height_at + petal_thickness + { + let dist_ratio = dist_sq / petal_radius_sq; + let yellow = (60.0 * dist_ratio) as u8; + let near = rpos + .x + .atan2(rpos.y) + .rem_euclid(std::f32::consts::TAU / flower.petals as f32); + if dist_ratio < 0.175 { + let red = close(near, 0.0, 0.5, 1); + let purple = close(near, 0.0, 0.35, 1); + if dist_ratio > red || rpos.z < petal_height_at { + return Some(Block::new( + BlockKind::ArtLeaves, + Rgb::new(240, 80 - yellow, 80 - yellow), + )); + } else if dist_ratio > purple { + return Some(Block::new( + BlockKind::ArtLeaves, + Rgb::new(200, 14, 132), + )); + } else { + return Some(Block::new( + BlockKind::ArtLeaves, + Rgb::new(249, 156, 218), + )); + } + } else { + let inset = close(near, -1.0, 1.0, 2).max(close(near, 1.0, 1.0, 2)); + if dist_ratio < inset { + return Some(Block::new( + BlockKind::ArtLeaves, + Rgb::new(240, 80 - yellow, 80 - yellow), + )); + } + } + } + + // pollen + let pollen_height = 5.0; + if rpos.z > 0.0 + && rpos.z < pollen_height + && dist_sq + < (stalk_radius + * Lerp::lerp_unclamped(0.5, 1.25, rpos.z / pollen_height)) + .powi(2) + { + return Some(Block::new( + BlockKind::GlowingMushroom, + Rgb::new(239, 192, 0), + )); + } + } + }, + CaveStructure::GiantRoot { + pos, + radius, + height, + } => { + let wposf = wpos.map(|e| e as f64); + let warp_freq = 1.0 / 32.0; + let warp_amp = Vec3::new(20.0, 20.0, 20.0); + let xy = wposf.xy(); + let xz = Vec2::new(wposf.x, wposf.z); + let yz = Vec2::new(wposf.y, wposf.z); + let wposf_warped = wposf.map(|e| e as f32) + + Vec3::new( + FastNoise2d::new(seed).get(yz * warp_freq), + FastNoise2d::new(seed).get(xz * warp_freq), + FastNoise2d::new(seed).get(xy * warp_freq), + ) * warp_amp; + let rpos = wposf_warped - pos.map(|e| e as f32); + let dist_sq = rpos.xy().magnitude_squared(); + if dist_sq < radius.powi(2) { + // Moss + if col.marble_mid + > (std::f32::consts::PI * rpos.z / *height) + .sin() + .powf(2.0) + .mul(0.25) + .add(col.marble_small) + { + return Some(Block::new(BlockKind::Wood, Rgb::new(48, 70, 25))); + } + return Some(Block::new(BlockKind::Wood, Rgb::new(66, 41, 26))); + } + }, } } - None }; @@ -572,48 +1156,122 @@ fn write_column( && !void_below { Block::new(BlockKind::Rock, Rgb::new(50, 35, 75)) + } else if z < ridge_bedrock && !void_below { + Block::new(BlockKind::Rock, col.stone_col) } else if (z < base && !void_below) || (z >= ceiling && !void_above) { - let stalactite: Rgb = Lerp::lerp( - Lerp::lerp( - Lerp::lerp(Rgb::new(80, 100, 150), Rgb::new(0, 75, 200), biome.mushroom), - Lerp::lerp( - Rgb::new(100, 40, 40), - Rgb::new(100, 75, 100), - col.marble_small, + let stalactite: Rgb = Lerp::lerp_unclamped( + Lerp::lerp_unclamped( + Lerp::lerp_unclamped( + Lerp::lerp_unclamped( + Lerp::lerp_unclamped( + Lerp::lerp_unclamped( + Rgb::new(80, 100, 150), + Rgb::new(23, 44, 88), + biome.mushroom, + ), + Lerp::lerp_unclamped( + Rgb::new(100, 40, 40), + Rgb::new(100, 75, 100), + col.marble_small, + ), + biome.fire, + ), + Lerp::lerp_unclamped( + Rgb::new(238, 198, 139), + Rgb::new(111, 99, 64), + col.marble_mid, + ), + biome.sandy, + ), + Lerp::lerp_unclamped( + Rgb::new(0, 73, 12), + Rgb::new(49, 63, 12), + col.marble_small, + ), + biome.leafy, ), - biome.fire, + Lerp::lerp_unclamped( + Rgb::new(100, 150, 255), + Rgb::new(100, 120, 255), + col.marble, + ), + biome.icy, ), - Lerp::lerp(Rgb::new(100, 150, 255), Rgb::new(100, 120, 255), col.marble), - biome.icy, + Lerp::lerp_unclamped( + Rgb::new(105, 25, 131), + Rgb::new(251, 238, 255), + col.marble_mid, + ), + biome.crystal, ); Block::new( - if rand.chance(wpos, (biome.mushroom * biome.mineral).max(biome.icy)) { + if rand.chance( + wpos, + (biome.mushroom * 0.01) + .max(biome.icy * 0.1) + .max(biome.crystal * 0.005), + ) { BlockKind::GlowingWeakRock + } else if rand.chance(wpos, biome.sandy) { + BlockKind::Sand + } else if rand.chance(wpos, biome.leafy) { + BlockKind::ArtLeaves + } else if ceiling_cover > 0.0 { + BlockKind::Rock } else { BlockKind::WeakRock }, stalactite.map(|e| e as u8), ) + } else if z < ceiling && z >= ceiling_drip { + if biome.mushroom > 0.9 { + let block = if rand.chance(wpos2d.with_z(89), 0.05) { + BlockKind::GlowingMushroom + } else { + BlockKind::GlowingWeakRock + }; + Block::new(block, Rgb::new(10, 70, 148)) + } else if biome.icy > 0.9 { + Block::new(BlockKind::GlowingWeakRock, Rgb::new(120, 140, 255)) + } else { + Block::new(BlockKind::WeakRock, Rgb::new(80, 100, 150)) + } } else if z >= base && z < floor && !void_below && !sky_above { let (net_col, total) = [ ( - Lerp::lerp(Rgb::new(40, 20, 0), Rgb::new(80, 80, 30), col.marble_small), + Lerp::lerp_unclamped( + Rgb::new(68, 62, 58), + Rgb::new(97, 95, 85), + col.marble_small, + ), 0.05, ), ( - Lerp::lerp(Rgb::new(50, 50, 75), Rgb::new(75, 75, 50), col.marble_mid), + Lerp::lerp_unclamped( + Rgb::new(66, 37, 30), + Rgb::new(88, 62, 45), + col.marble_mid, + ), biome.dusty, ), ( - Lerp::lerp(Rgb::new(20, 65, 175), Rgb::new(20, 100, 80), col.marble_mid), + Lerp::lerp_unclamped( + Rgb::new(20, 65, 175), + Rgb::new(20, 100, 80), + col.marble_mid, + ), biome.mushroom, ), ( - Lerp::lerp(Rgb::new(120, 50, 20), Rgb::new(50, 5, 40), col.marble_small), + Lerp::lerp_unclamped( + Rgb::new(120, 50, 20), + Rgb::new(50, 5, 40), + col.marble_small, + ), biome.fire, ), ( - Lerp::lerp( + Lerp::lerp_unclamped( Rgb::new(0, 100, 50), Rgb::new(80, 100, 20), col.marble_small, @@ -621,6 +1279,31 @@ fn write_column( biome.leafy, ), (Rgb::new(170, 195, 255), biome.icy), + ( + Lerp::lerp_unclamped( + Rgb::new(105, 25, 131), + Rgb::new(251, 238, 255), + col.marble_mid, + ), + biome.crystal, + ), + ( + Lerp::lerp_unclamped( + Rgb::new(201, 174, 116), + Rgb::new(244, 239, 227), + col.marble_small, + ), + biome.sandy, + ), + ( + // Same as barren + Lerp::lerp_unclamped( + Rgb::new(68, 62, 58), + Rgb::new(97, 95, 85), + col.marble_small, + ), + biome.snowy, + ), ] .into_iter() .fold((Rgb::::zero(), 0.0), |a, x| { @@ -630,14 +1313,22 @@ fn write_column( if is_ice { Block::new(BlockKind::Ice, Rgb::new(120, 160, 255)) + } else if is_snow { + Block::new(BlockKind::ArtSnow, Rgb::new(170, 195, 255)) } else { Block::new( if biome.mushroom.max(biome.leafy) > 0.5 { BlockKind::Grass } else if biome.icy > 0.5 { - BlockKind::Snow - } else if biome.fire > 0.5 { + BlockKind::ArtSnow + } else if biome.fire.max(biome.snowy) > 0.5 { BlockKind::Rock + } else if biome.crystal > 0.5 { + if rand.chance(wpos, biome.crystal * 0.02) { + BlockKind::GlowingRock + } else { + BlockKind::Rock + } } else { BlockKind::Sand }, @@ -646,42 +1337,89 @@ fn write_column( } } else if let Some(sprite) = (z == floor && !void_below && !sky_above) .then(|| { - if rand.chance(wpos2d.with_z(1), biome.mushroom * 0.05) { + if col.marble_mid > 0.55 + && biome.mushroom > 0.6 + && rand.chance( + wpos2d.with_z(1), + biome.mushroom.powi(2) * 0.2 * col.marble_mid, + ) + { [ - (SpriteKind::CaveMushroom, 0.15), + (SpriteKind::GlowMushroom, 0.5), (SpriteKind::Mushroom, 0.25), - (SpriteKind::GrassBlue, 1.0), - (SpriteKind::CavernGrassBlueShort, 1.0), - (SpriteKind::CavernGrassBlueMedium, 1.0), - (SpriteKind::CavernGrassBlueLong, 1.0), + (SpriteKind::GrassBlue, 0.0), + (SpriteKind::GrassBlueMedium, 1.5), + (SpriteKind::GrassBlueLong, 2.0), (SpriteKind::Moonbell, 0.01), + (SpriteKind::SporeReed, 2.5), ] .choose_weighted(rng, |(_, w)| *w) .ok() .map(|s| s.0) - } else if rand.chance(wpos2d.with_z(15), biome.leafy * 0.05) { - [ - (SpriteKind::LongGrass, 1.0), - (SpriteKind::MediumGrass, 2.0), - (SpriteKind::ShortGrass, 2.0), - (SpriteKind::JungleFern, 0.5), - (SpriteKind::JungleLeafyPlant, 0.5), - (SpriteKind::JungleRedGrass, 0.35), - (SpriteKind::Mushroom, 0.15), - (SpriteKind::EnsnaringVines, 0.2), - (SpriteKind::Fern, 0.75), - (SpriteKind::LeafyPlant, 0.8), - (SpriteKind::Twigs, 0.07), - (SpriteKind::Wood, 0.03), - ] - .choose_weighted(rng, |(_, w)| *w) - .ok() - .map(|s| s.0) - } else if rand.chance(wpos2d.with_z(2), biome.dusty * 0.01) { + } else if col.marble_mid > 0.6 + && biome.leafy > 0.4 + && rand.chance( + wpos2d.with_z(15), + biome.leafy.powi(2) * 0.25 * col.marble_mid, + ) + { + let mixed = col.marble.add(col.marble_small.sub(0.5).mul(0.25)); + if (0.25..0.45).contains(&mixed) || (0.55..0.75).contains(&mixed) { + return [ + (SpriteKind::LongGrass, 1.0), + (SpriteKind::MediumGrass, 2.0), + (SpriteKind::ShortGrass, 0.0), + (SpriteKind::JungleFern, 0.5), + (SpriteKind::JungleRedGrass, 0.35), + (SpriteKind::Fern, 0.75), + (SpriteKind::LeafyPlant, 0.8), + (SpriteKind::JungleLeafyPlant, 0.5), + (SpriteKind::LanternPlant, 0.1), + (SpriteKind::LanternFlower, 0.1), + (SpriteKind::LushFlower, 0.2), + ] + .choose_weighted(rng, |(_, w)| *w) + .ok() + .map(|s| s.0); + } else if (0.0..0.25).contains(&mixed) { + return [(Some(SpriteKind::LanternPlant), 0.5), (None, 0.5)] + .choose_weighted(rng, |(_, w)| *w) + .ok() + .and_then(|s| s.0); + } else if (0.75..1.0).contains(&mixed) { + return [(Some(SpriteKind::LushFlower), 0.6), (None, 0.4)] + .choose_weighted(rng, |(_, w)| *w) + .ok() + .and_then(|s| s.0); + } else { + return [ + (SpriteKind::LongGrass, 1.0), + (SpriteKind::MediumGrass, 2.0), + (SpriteKind::ShortGrass, 0.0), + (SpriteKind::JungleFern, 0.5), + (SpriteKind::JungleLeafyPlant, 0.5), + (SpriteKind::JungleRedGrass, 0.35), + (SpriteKind::Mushroom, 0.15), + (SpriteKind::EnsnaringVines, 0.2), + (SpriteKind::Fern, 0.75), + (SpriteKind::LeafyPlant, 0.8), + (SpriteKind::Twigs, 0.07), + (SpriteKind::Wood, 0.03), + (SpriteKind::LanternPlant, 0.3), + (SpriteKind::LanternFlower, 0.3), + (SpriteKind::LushFlower, 0.5), + (SpriteKind::LushMushroom, 1.0), + ] + .choose_weighted(rng, |(_, w)| *w) + .ok() + .map(|s| s.0); + } + } else if rand.chance(wpos2d.with_z(2), biome.dusty.max(biome.sandy) * 0.01) { [ (SpriteKind::Bones, 0.5), (SpriteKind::Stones, 1.5), (SpriteKind::DeadBush, 1.0), + (SpriteKind::DeadPlant, 1.5), (SpriteKind::EnsnaringWeb, 0.5), (SpriteKind::Mud, 0.025), ] @@ -690,17 +1428,17 @@ fn write_column( .map(|s| s.0) } else if rand.chance(wpos2d.with_z(14), biome.barren * 0.003) { [ + (SpriteKind::Bones, 0.5), (SpriteKind::Welwitch, 0.5), (SpriteKind::DeadBush, 1.5), + (SpriteKind::DeadPlant, 1.5), + (SpriteKind::RockyMushroom, 1.5), (SpriteKind::Crate, 0.005), ] .choose_weighted(rng, |(_, w)| *w) .ok() .map(|s| s.0) - } else if rand.chance( - wpos2d.with_z(3), - close(biome.humidity, 0.0, 0.5) * biome.mineral * 0.005, - ) { + } else if rand.chance(wpos2d.with_z(3), biome.crystal * 0.005) { Some(SpriteKind::CrystalLow) } else if rand.chance(wpos2d.with_z(13), biome.fire * 0.001) { [ @@ -711,6 +1449,12 @@ fn write_column( .choose_weighted(rng, |(_, w)| *w) .ok() .map(|s| s.0) + } else if biome.icy > 0.5 && rand.chance(wpos2d.with_z(23), biome.icy * 0.005) { + Some(SpriteKind::IceCrystal) + } else if biome.icy > 0.5 + && rand.chance(wpos2d.with_z(31), biome.icy * biome.mineral * 0.005) + { + Some(SpriteKind::GlowIceCrystal) } else if rand.chance(wpos2d.with_z(5), 0.0025) { [ (Some(SpriteKind::VeloriteFrag), 0.3), @@ -746,8 +1490,8 @@ fn write_column( .ok() .and_then(|s| s.0) } else if rand.chance(wpos2d.with_z(7), 0.01) { - let shallow = close(biome.depth, 0.0, 0.4); - let middle = close(biome.depth, 0.5, 0.4); + let shallow = close(biome.depth, 0.0, 0.4, 3); + let middle = close(biome.depth, 0.5, 0.4, 3); //let deep = close(biome.depth, 1.0, 0.4); // TODO: Use this for deep only // things [ @@ -773,27 +1517,28 @@ fn write_column( Block::air(sprite) } else if let Some(sprite) = (z == ceiling - 1 && !void_above) .then(|| { - if rand.chance(wpos2d.with_z(3), biome.mushroom * 0.01) { - Some( - *[ - SpriteKind::CavernMycelBlue, - SpriteKind::CeilingMushroom, - SpriteKind::Orb, - ] - .choose(rng) - .unwrap(), - ) - } else if rand.chance(wpos2d.with_z(4), biome.leafy * 0.015) { + if biome.mushroom > 0.5 && rand.chance(wpos2d.with_z(3), biome.mushroom * 0.01) + { + [(SpriteKind::MycelBlue, 0.75), (SpriteKind::Mold, 1.0)] + .choose_weighted(rng, |(_, w)| *w) + .ok() + .map(|s| s.0) + } else if biome.leafy > 0.4 + && rand.chance(wpos2d.with_z(4), biome.leafy * 0.015) + { [ - (SpriteKind::Liana, 1.0), - (SpriteKind::Orb, 0.35), - (SpriteKind::CrystalHigh, 0.1), + (SpriteKind::Liana, 1.5), + (SpriteKind::CeilingLanternPlant, 1.25), + (SpriteKind::CeilingLanternFlower, 1.0), + (SpriteKind::CeilingJungleLeafyPlant, 1.5), ] .choose_weighted(rng, |(_, w)| *w) .ok() .map(|s| s.0) - } else if rand.chance(wpos2d.with_z(5), 0.0075) { - Some(*[SpriteKind::CrystalHigh].choose(rng).unwrap()) + } else if rand.chance(wpos2d.with_z(5), biome.barren * 0.015) { + Some(SpriteKind::Root) + } else if rand.chance(wpos2d.with_z(5), biome.crystal * 0.005) { + Some(SpriteKind::CrystalHigh) } else { None } @@ -801,8 +1546,10 @@ fn write_column( .flatten() { Block::air(sprite) + } else if let Some(structure_block) = get_structure(wpos, rng) { + structure_block } else { - get_mushroom(wpos, rng).unwrap_or(Block::air(SpriteKind::Empty)) + Block::empty() } }); @@ -813,132 +1560,247 @@ fn write_column( } fn apply_entity_spawns(canvas: &mut Canvas, wpos: Vec3, biome: &Biome, rng: &mut R) { - if RandomField::new(canvas.info().index().seed).chance(wpos, 0.05) { + if RandomField::new(canvas.info().index().seed).chance(wpos, 0.035) { if let Some(entity_asset) = [ // Mushroom biome ( Some("common.entity.wild.peaceful.truffler"), - (biome.mushroom + 0.02) * 0.35, + biome.mushroom + 0.02, + 0.35, + 0.5, ), ( Some("common.entity.wild.peaceful.fungome"), - (biome.mushroom + 0.02) * 0.5, + biome.mushroom + 0.02, + 0.5, + 0.5, ), ( Some("common.entity.wild.peaceful.bat"), - (biome.mushroom + 0.1) * 0.25, + biome.mushroom + 0.1, + 0.25, + 0.5, ), // Leafy biome ( Some("common.entity.wild.peaceful.holladon"), - (biome.leafy.max(biome.barren) + 0.1) * 0.5, + biome.leafy.max(biome.dusty) + 0.05, + 0.25, + 0.5, ), ( - Some("common.entity.wild.peaceful.turtle"), - (biome.leafy + 0.05) * 0.5, + Some("common.entity.dungeon.gnarling.mandragora"), + biome.leafy + 0.05, + 0.2, + 0.5, ), ( Some("common.entity.wild.aggressive.rootsnapper"), - (biome.leafy + 0.05) * 0.02, - ), - ( - Some("common.entity.wild.peaceful.axolotl"), - (biome.leafy + 0.05) * 0.5, + biome.leafy + 0.05, + 0.075, + 0.5, ), ( Some("common.entity.wild.aggressive.maneater"), - (biome.leafy + 0.0) * 0.05, + biome.leafy + 0.05, + 0.075, + 0.5, ), ( Some("common.entity.wild.aggressive.batfox"), - (biome.leafy.max(biome.barren) + 0.15) * 0.35, + biome + .leafy + .max(biome.barren) + .max(biome.sandy) + .max(biome.snowy) + + 0.3, + 0.25, + 0.5, ), ( - Some("common.entity.wild.aggressive.rocksnapper"), - (biome.leafy.max(biome.barren) + 0.1) * 0.08, - ), - ( - Some("common.entity.wild.aggressive.cave_salamander"), - (biome.leafy + 0.1) * 0.2, + Some("common.entity.wild.peaceful.crawler_moss"), + biome.leafy + 0.05, + 0.25, + 0.5, ), ( Some("common.entity.wild.aggressive.asp"), - (biome.leafy + 0.1) * 0.1, + biome.leafy.max(biome.sandy) + 0.1, + 0.2, + 0.5, ), ( Some("common.entity.wild.aggressive.swamp_troll"), - (biome.leafy + 0.0) * 0.1, + biome.leafy + 0.0, + 0.05, + 0.5, ), ( Some("common.entity.wild.peaceful.bat"), - (biome.leafy + 0.1) * 0.25, + biome.leafy + 0.1, + 0.25, + 0.5, ), // Dusty biome ( Some("common.entity.wild.aggressive.dodarock"), - (biome.dusty.max(biome.barren) + 0.05) * 0.05, + biome + .dusty + .max(biome.barren) + .max(biome.crystal) + .max(biome.snowy) + + 0.05, + 0.05, + 0.5, ), ( Some("common.entity.wild.aggressive.cave_spider"), - (biome.dusty + 0.0) * 0.05, + biome.dusty + 0.0, + 0.4, + 0.5, ), ( Some("common.entity.wild.aggressive.cave_troll"), - (biome.dusty + 0.1) * 0.05, - ), - ( - Some("common.entity.wild.aggressive.antlion"), - (biome.dusty.min(biome.depth) + 0.0) * 0.01, + biome.dusty + 0.1, + 0.05, + 0.5, ), ( Some("common.entity.wild.peaceful.rat"), - (biome.dusty.max(biome.barren) + 0.15) * 0.3, + biome.dusty + 0.1, + 0.3, + 0.5, ), ( Some("common.entity.wild.peaceful.bat"), - (biome.dusty.max(biome.barren) + 0.1) * 0.25, + biome.dusty.max(biome.sandy).max(biome.snowy) + 0.1, + 0.25, + 0.5, ), // Icy biome - ( - Some("common.entity.wild.aggressive.blue_oni"), - (biome.icy + 0.0) * 0.03, - ), ( Some("common.entity.wild.aggressive.icedrake"), - (biome.icy + 0.0) * 0.04, + biome.icy + 0.0, + 0.1, + 0.5, ), ( Some("common.entity.wild.aggressive.wendigo"), - (biome.icy.min(biome.depth) + 0.0) * 0.02, + biome.icy.min(biome.depth) + 0.0, + 0.02, + 0.5, + ), + ( + Some("common.entity.wild.aggressive.frostfang"), + biome.icy + 0.0, + 0.25, + 0.5, + ), + ( + Some("common.entity.wild.aggressive.tursus"), + biome.icy + 0.0, + 0.03, + 0.5, ), // Lava biome ( Some("common.entity.wild.aggressive.lavadrake"), - (biome.fire + 0.0) * 0.15, + biome.fire + 0.0, + 0.5, + 0.5, ), ( Some("common.entity.wild.peaceful.crawler_molten"), - (biome.fire + 0.0) * 0.35, + biome.fire + 0.0, + 0.5, + 0.5, + ), + ( + Some("common.entity.wild.aggressive.cave_salamander"), + biome.fire + 0.0, + 0.5, + 0.5, ), ( Some("common.entity.wild.aggressive.red_oni"), - (biome.fire + 0.0) * 0.05, + biome.fire + 0.0, + 0.03, + 0.5, + ), + // Crystal biome + ( + Some("common.entity.wild.aggressive.basilisk"), + biome.crystal + 0.1, + 0.1, + 0.5, + ), + ( + Some("common.entity.wild.aggressive.blue_oni"), + biome.crystal + 0.0, + 0.03, + 0.5, + ), + // Sandy biome + ( + Some("common.entity.wild.aggressive.antlion"), + biome.sandy.max(biome.dusty) + 0.1, + 0.025, + 0.5, + ), + ( + Some("common.entity.wild.aggressive.sandshark"), + biome.sandy + 0.1, + 0.025, + 0.5, + ), + ( + Some("common.entity.wild.peaceful.crawler_sand"), + biome.sandy + 0.1, + 0.25, + 0.5, + ), + // Snowy biome + ( + Some("common.entity.wild.aggressive.akhlut"), + (biome.snowy.max(biome.icy) + 0.1), + 0.05, + 0.5, + ), + ( + Some("common.entity.wild.aggressive.rocksnapper"), + biome.barren.max(biome.crystal).max(biome.snowy) + 0.1, + 0.1, + 0.5, ), // With depth ( Some("common.entity.wild.aggressive.black_widow"), - (biome.depth + 0.0) * 0.01, + biome.depth + 0.0, + 0.02, + 0.5, ), ( Some("common.entity.wild.aggressive.ogre"), - (biome.depth + 0.0) * 0.02, + biome.depth + 0.0, + 0.02, + 0.5, ), - ( - Some("common.entity.wild.aggressive.basilisk"), - (biome.depth + 0.1) * 0.005, - ), - (None, 100.0), + (None, 100.0, 0.0, 0.0), ] + .iter() + .filter_map(|(entity, biome_modifier, chance, cutoff)| { + if let Some(entity) = entity { + if *biome_modifier > *cutoff { + let close = close(1.0, *biome_modifier, *cutoff, 2); + (close > 0.0).then(|| (Some(entity), close * chance)) + } else { + None + } + } else { + Some((None, 100.0)) + } + }) + .collect_vec() .choose_weighted(rng, |(_, w)| *w) .ok() .and_then(|s| s.0) diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index 01c085823a..b19b5db492 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -933,7 +933,7 @@ pub fn apply_caverns_to(canvas: &mut Canvas, dynamic_rng: &mut R) { let sprites = if dynamic_rng.gen_bool(0.1) { &[Beehive, Lantern] as &[_] } else { - &[Orb, CavernMycelBlue, CavernMycelBlue] as &[_] + &[Orb, MycelBlue, MycelBlue] as &[_] }; return Some(Block::air(*sprites.choose(dynamic_rng).unwrap())); } @@ -1091,11 +1091,7 @@ pub fn apply_caverns_to(canvas: &mut Canvas, dynamic_rng: &mut R) { Block::air( *if dynamic_rng.gen_bool(0.9) { // High density - &[ - CavernGrassBlueShort, - CavernGrassBlueMedium, - CavernGrassBlueLong, - ] as &[_] + &[GrassBlueShort, GrassBlueMedium, GrassBlueLong] as &[_] } else if dynamic_rng.gen_bool(0.5) { // Medium density &[CaveMushroom] as &[_] @@ -1108,7 +1104,7 @@ pub fn apply_caverns_to(canvas: &mut Canvas, dynamic_rng: &mut R) { ) } else if z == cavern_top - 1 && dynamic_rng.gen_bool(0.001) { Block::air( - *[CrystalHigh, CeilingMushroom, Orb, CavernMycelBlue] + *[CrystalHigh, CeilingMushroom, Orb, MycelBlue] .choose(dynamic_rng) .unwrap(), ) diff --git a/world/src/layer/scatter.rs b/world/src/layer/scatter.rs index 52c33d2a68..136b506b9d 100644 --- a/world/src/layer/scatter.rs +++ b/world/src/layer/scatter.rs @@ -1,4 +1,9 @@ -use crate::{column::ColumnSample, sim::SimChunk, util::RandomField, Canvas, CONFIG}; +use crate::{ + column::ColumnSample, + sim::SimChunk, + util::{close, RandomField}, + Canvas, CONFIG, +}; use common::{ calendar::{Calendar, CalendarEvent}, terrain::{Block, BlockKind, SpriteKind}, @@ -9,10 +14,6 @@ use rand::prelude::*; use std::f32; use vek::*; -pub fn close(x: f32, tgt: f32, falloff: f32) -> f32 { - (1.0 - (x - tgt).abs() / falloff).max(0.0).powf(0.125) -} - /// Returns a decimal value between 0 and 1. /// The density is maximum at the middle of the highest and the lowest allowed /// altitudes, and zero otherwise. Quadratic curve. diff --git a/world/src/layer/shrub.rs b/world/src/layer/shrub.rs index e823281a7a..7458da215c 100644 --- a/world/src/layer/shrub.rs +++ b/world/src/layer/shrub.rs @@ -46,7 +46,7 @@ pub fn apply_shrubs_to(canvas: &mut Canvas, _dynamic_rng: &mut impl Rng) { && col.spawn_rate > 0.9 && col.path.map_or(true, |(d, _, _, _)| d > 6.0) && !tunnel_bounds_at(wpos, &info, &info.land()) - .any(|(_, z_range, _, _)| z_range.contains(&(col.alt as i32 - 1))) + .any(|(_, z_range, _, _, _, _)| z_range.contains(&(col.alt as i32 - 1))) { let kind = *info .chunks() diff --git a/world/src/layer/tree.rs b/world/src/layer/tree.rs index 5398f65a3f..55d5ae4d17 100644 --- a/world/src/layer/tree.rs +++ b/world/src/layer/tree.rs @@ -47,7 +47,7 @@ pub fn tree_valid_at( || col.path.map(|(d, _, _, _)| d < 12.0).unwrap_or(false) || info.map_or(false, |info| { tunnel_bounds_at(wpos, &info, &info.land()) - .any(|(_, z_range, _, _)| z_range.contains(&(col.alt as i32 - 2))) + .any(|(_, z_range, _, _, _, _)| z_range.contains(&(col.alt as i32 - 2))) }) { return false; diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index be8dd74c10..d4fced8b85 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -1,4 +1,4 @@ -use crate::{column::ColumnSample, sim::SimChunk, IndexRef, CONFIG}; +use crate::{column::ColumnSample, sim::SimChunk, util::close, IndexRef, CONFIG}; use common::{ assets::{self, AssetExt}, calendar::{Calendar, CalendarEvent}, @@ -17,10 +17,6 @@ type Weight = u32; type Min = u8; type Max = u8; -fn close(x: f32, tgt: f32, falloff: f32) -> f32 { - (1.0 - (x - tgt).abs() / falloff).max(0.0).powf(0.125) -} - #[derive(Clone, Debug, Deserialize)] pub struct SpawnEntry { /// User-facing info for wiki, statistical tools, etc. diff --git a/world/src/lib.rs b/world/src/lib.rs index 15836e8795..cebc3b1e2c 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -465,9 +465,9 @@ impl World { layer::apply_caverns_to(&mut canvas, &mut dynamic_rng); } if index.features.caves { - layer::apply_caves_to(&mut canvas, &mut dynamic_rng); + layer::apply_caves2_to(&mut canvas, &mut dynamic_rng); + // layer::apply_caves_to(&mut canvas, &mut dynamic_rng); } - layer::apply_caves2_to(&mut canvas, &mut dynamic_rng); if index.features.rocks { layer::apply_rocks_to(&mut canvas, &mut dynamic_rng); } diff --git a/world/src/site2/plot/bridge.rs b/world/src/site2/plot/bridge.rs index 4687706df8..e6f281effb 100644 --- a/world/src/site2/plot/bridge.rs +++ b/world/src/site2/plot/bridge.rs @@ -8,8 +8,6 @@ use num::integer::Roots; use rand::prelude::*; use vek::*; -use inline_tweak::tweak; - enum RoofKind { Crenelated, Hipped, @@ -618,7 +616,7 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) { .fill(rock.clone()); let offset = tower_size * 2 - 2; - let d = tweak!(2); + let d = 2; let n = (bridge.end.z - bridge.start.z - d) / offset; let p = (bridge.end.z - bridge.start.z - d) / n; diff --git a/world/src/util/fast_noise.rs b/world/src/util/fast_noise.rs index 84ac0dc87a..8e4b3fcc8a 100644 --- a/world/src/util/fast_noise.rs +++ b/world/src/util/fast_noise.rs @@ -110,9 +110,9 @@ impl Sampler<'static> for FastNoise2d { f.powi(2) * (3.0 - 2.0 * f) }); - let v0 = v00 + factor.y * (v10 - v00); - let v1 = v01 + factor.y * (v11 - v01); + let v0 = v00 + factor.x * (v10 - v00); + let v1 = v01 + factor.x * (v11 - v01); - (v0 + factor.x * (v1 - v0)) * 2.0 - 1.0 + (v0 + factor.y * (v1 - v0)) * 2.0 - 1.0 } } diff --git a/world/src/util/mod.rs b/world/src/util/mod.rs index 66fe6f4571..bad938ec35 100644 --- a/world/src/util/mod.rs +++ b/world/src/util/mod.rs @@ -36,6 +36,14 @@ pub fn attempt(max_iters: usize, mut f: impl FnMut() -> Option) -> Option< (0..max_iters).find_map(|_| f()) } +pub fn close(x: f32, tgt: f32, falloff: f32) -> f32 { + (1.0 - (x - tgt).abs() / falloff).max(0.0).powf(0.125) +} + +pub fn close_fast(x: f32, tgt: f32, falloff: f32, falloff_strength: i32) -> f32 { + (1.0 - ((x - tgt) / falloff).powi(falloff_strength * 2)).max(0.0) +} + pub const CARDINALS: [Vec2; 4] = [ Vec2::new(0, 1), Vec2::new(1, 0), diff --git a/world/src/util/small_cache.rs b/world/src/util/small_cache.rs index 2246d5b932..4a850b952c 100644 --- a/world/src/util/small_cache.rs +++ b/world/src/util/small_cache.rs @@ -1,23 +1,22 @@ use arr_macro::arr; -use vek::*; -fn calc_idx(v: Vec2) -> usize { - let mut x = v.x as u32; - let mut y = v.y as u32; - x = x.wrapping_mul(0x6eed0e9d); - y = y.wrapping_mul(0x2f72b421); - (x ^ y) as usize +fn calc_idx(v: impl Iterator) -> usize { + let mut r = 0; + for (e, h) in v.zip([0x6eed0e9d, 0x2f72b421, 0x18132f72, 0x891e2fba].into_iter()) { + r ^= (e as u32).wrapping_mul(h); + } + r as usize } // NOTE: Use 128 if TerrainChunkSize::RECT_SIZE.x = 128. const CACHE_LEN: usize = 32; -pub struct SmallCache { - index: [Option>; CACHE_LEN + 9], +pub struct SmallCache { + index: [Option; CACHE_LEN + 9], data: [V; CACHE_LEN + 9], random: u32, } -impl Default for SmallCache { +impl Default for SmallCache { fn default() -> Self { Self { index: [None; CACHE_LEN + 9], @@ -26,9 +25,9 @@ impl Default for SmallCache { } } } -impl SmallCache { - pub fn get) -> V>(&mut self, key: Vec2, f: F) -> &V { - let idx = calc_idx(key) % CACHE_LEN; +impl, V: Default> SmallCache { + pub fn get V>(&mut self, key: K, f: F) -> &V { + let idx = calc_idx(key.into_iter()) % CACHE_LEN; // Search if self.index[idx].as_ref().map(|k| k == &key).unwrap_or(false) {