From 01d3be963dabe1bbcb40afcca213990358dc13f2 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Sat, 3 Jan 2026 23:36:19 +0100 Subject: [PATCH] feat: Structures --- Cargo.lock | 252 ++++++------ Cargo.toml | 8 +- assets/structures.json | 362 +++++++++--------- pumpkin-util/src/math/block_box.rs | 20 +- pumpkin-util/src/random/mod.rs | 26 +- pumpkin-world/src/chunk_system.rs | 88 +++-- pumpkin-world/src/generation/proto_chunk.rs | 47 +-- pumpkin-world/src/generation/structure/mod.rs | 171 +++++++-- .../src/generation/structure/placement.rs | 53 ++- .../structure/structures/buried_treasure.rs | 7 +- .../generation/structure/structures/mod.rs | 13 +- .../structure/structures/nether_fortress.rs | 7 +- .../structure/structures/swamp_hut.rs | 201 +++++++--- 13 files changed, 772 insertions(+), 483 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22a4e4151..88d805fda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" dependencies = [ "axum-core", "bytes", @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", @@ -258,9 +258,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "byteorder" @@ -282,9 +282,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.49" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "shlex", @@ -313,13 +313,13 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.10.0-rc.5" +version = "0.10.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cbf41c6ec3c4b9eaf7f8f5c11a72cd7d3aa0428125c20d5ef4d09907a0f019" +checksum = "f895fb33c1ad22da4bc79d37c0bddff8aee2ba4575705345eb73b8ffbc386074" dependencies = [ "cfg-if", "cpufeatures", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -361,18 +361,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstyle", "clap_lex", @@ -514,30 +514,13 @@ dependencies = [ "libc", ] -[[package]] -name = "crc" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - [[package]] name = "crc-fast" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" +checksum = "e75b2483e97a5a7da73ac68a05b629f9c53cff58d8ed1c77866079e18b00dba5" dependencies = [ - "crc", "digest 0.10.7", - "rustversion", "spin", ] @@ -642,9 +625,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossfire" -version = "2.1.8" +version = "2.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cdbed44ce04d3b1581f2f41713381a799fdff8cedc0abafd7ada78284063dc3" +checksum = "7f19636ec7667a64122ad23414cd773dcdd32532a7df7a4f68ad16bba0db5f02" dependencies = [ "crossbeam-queue", "crossbeam-utils", @@ -705,7 +688,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6715836b4946e8585016e80b79c7561476aff3b22f7b756778e7b109d86086c6" dependencies = [ "num-traits", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "serdect", "subtle", "zeroize", @@ -723,9 +706,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.5" +version = "0.2.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919bd05924682a5480aec713596b9e2aabed3a0a6022fab6847f85a99e5f190a" +checksum = "e6165b8029cdc3e765b74d3548f85999ee799d5124877ce45c2c85ca78e4d4aa" dependencies = [ "hybrid-array", ] @@ -738,7 +721,7 @@ checksum = "fdd9b2855017318a49714c07ee8895b89d3510d54fa6d86be5835de74c389609" dependencies = [ "crypto-bigint 0.7.0-rc.10", "libm", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -788,18 +771,18 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case", "proc-macro2", @@ -822,13 +805,13 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-rc.4" +version = "0.11.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea390c940e465846d64775e55e3115d5dc934acb953de6f6e6360bc232fe2bf7" +checksum = "ebf9423bafb058e4142194330c52273c343f8a5beb7176d052f0e73b17dd35b9" dependencies = [ "block-buffer 0.11.0", "const-oid 0.10.1", - "crypto-common 0.2.0-rc.5", + "crypto-common 0.2.0-rc.8", "subtle", ] @@ -941,7 +924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -962,9 +945,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "flate2" @@ -1120,6 +1103,19 @@ dependencies = [ "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b99f0d993a2b9b97b9a201193aa8ad21305cde06a3be9a7e1f8f4201e5cc27e" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "rand_core 0.10.0-rc-3", + "wasip2", +] + [[package]] name = "group" version = "0.13.0" @@ -1227,7 +1223,7 @@ version = "0.13.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1c597ac7d6cc8143e30e83ef70915e7f883b18d8bec2e2b2bce47f5bbb06d57" dependencies = [ - "digest 0.11.0-rc.4", + "digest 0.11.0-rc.5", ] [[package]] @@ -1395,9 +1391,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -1409,9 +1405,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -1496,15 +1492,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jiff" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +checksum = "a87d9b8105c23642f50cbbae03d1f75d8422c5cb98ce7ee9271f7ff7505be6b8" dependencies = [ "jiff-static", "log", @@ -1515,9 +1511,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +checksum = "b787bebb543f8969132630c51fd0afab173a86c6abae56ff3b9e5e3e3f9f6e58" dependencies = [ "proc-macro2", "quote", @@ -1542,15 +1538,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.178" +version = "0.2.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" [[package]] name = "libloading" -version = "0.9.0" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", "windows-link", @@ -1845,9 +1841,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.4" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" +checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" dependencies = [ "memchr", "ucd-trie", @@ -1855,9 +1851,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.4" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" +checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed" dependencies = [ "pest", "pest_generator", @@ -1865,9 +1861,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.4" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" +checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5" dependencies = [ "pest", "pest_meta", @@ -1878,9 +1874,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.4" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" +checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365" dependencies = [ "pest", "sha2 0.10.9", @@ -1993,9 +1989,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" [[package]] name = "portable-atomic-util" @@ -2054,9 +2050,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] @@ -2327,12 +2323,11 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" version = "0.10.0-rc.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be866deebbade98028b705499827ad6967c8bb1e21f96a2609913c8c076e9307" +source = "git+https://github.com/rust-random/rand#75fe38fff59e5abb16ed5a146d61960cad27dc0f" dependencies = [ "chacha20", - "getrandom 0.3.4", - "rand_core 0.10.0-rc-2", + "getrandom 0.4.0-rc.0", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -2346,9 +2341,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.10.0-rc-2" +version = "0.10.0-rc-3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "104a23e4e8b77312a823b6b5613edbac78397e2f34320bc7ac4277013ec4478e" +checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05" [[package]] name = "rayon" @@ -2441,12 +2436,12 @@ dependencies = [ "const-oid 0.10.1", "crypto-bigint 0.7.0-rc.10", "crypto-primes", - "digest 0.11.0-rc.4", + "digest 0.11.0-rc.5", "pkcs1", "pkcs8 0.11.0-rc.8", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "sha1", - "signature 3.0.0-rc.5", + "signature 3.0.0-rc.6", "spki 0.8.0-rc.4", "subtle", "zeroize", @@ -2477,7 +2472,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2497,9 +2492,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "zeroize", ] @@ -2545,12 +2540,6 @@ dependencies = [ "twox-hash 2.1.2", ] -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - [[package]] name = "same-file" version = "1.0.6" @@ -2618,15 +2607,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -2642,9 +2631,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ "serde_core", ] @@ -2667,7 +2656,7 @@ checksum = "aa1ae819b9870cadc959a052363de870944a1646932d274a4e270f64bf79e5ef" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-rc.4", + "digest 0.11.0-rc.5", ] [[package]] @@ -2689,7 +2678,7 @@ checksum = "19d43dc0354d88b791216bb5c1bfbb60c0814460cc653ae0ebd71f286d0bd927" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-rc.4", + "digest 0.11.0-rc.5", ] [[package]] @@ -2730,10 +2719,11 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.7" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -2749,12 +2739,12 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.5" +version = "3.0.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0251c9d6468f4ba853b6352b190fb7c1e405087779917c238445eb03993826" +checksum = "597a96996ccff7dfa16f052bd995b4cecc72af22c35138738dc029f0ead6608d" dependencies = [ - "digest 0.11.0-rc.4", - "rand_core 0.10.0-rc-2", + "digest 0.11.0-rc.5", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -2858,9 +2848,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.111" +version = "2.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4" dependencies = [ "proc-macro2", "quote", @@ -2905,7 +2895,7 @@ dependencies = [ "fastrand", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3011,9 +3001,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.48.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ "bytes", "libc", @@ -3064,9 +3054,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.8" +version = "0.9.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" dependencies = [ "indexmap", "serde_core", @@ -3079,27 +3069,27 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tonic" @@ -3174,9 +3164,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3196,9 +3186,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -3441,9 +3431,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" dependencies = [ "rustls-pki-types", ] @@ -3470,7 +3460,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3770,3 +3760,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317f17ff091ac4515f17cc7a190d2769a8c9a96d227de5d64b500b01cda8f2cd" diff --git a/Cargo.toml b/Cargo.toml index 9ce0f30a7..12411e2c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ debug = true [workspace.dependencies] log = "0.4" -tokio = { version = "1.48", default-features = false } +tokio = { version = "1.49", default-features = false } syn = { version = "2.0", default-features = false, features=["printing"] } @@ -60,7 +60,7 @@ console-subscriber = { version = "0.5.0", default-features = false } crc-fast = "1.9.0" criterion = { version = "0.8", default-features = false } crossbeam-utils = "0.8.21" -crossfire = "2.1.8" +crossfire = "2.1.9" dashmap = "6.1" ecdsa = "0.16.9" enum_dispatch = "0.3.13" @@ -70,7 +70,7 @@ heck = "0.5" hmac = "=0.13.0-rc.3" indexmap = "2.12" itertools = "0.14.0" -libloading = "0.9" +libloading = "0.8" lru = "0.16.2" lz4-java-wrc = "0.2.0" md5 = "0.8" @@ -92,7 +92,7 @@ pumpkin-registry = { path = "pumpkin-registry" } pumpkin-util = { path = "pumpkin-util" } pumpkin-world = { path = "pumpkin-world" } quote = "1.0" -rand = "=0.10.0-rc.5" +rand = { git = "https://github.com/rust-random/rand"} rsa = "=0.10.0-rc.10" rustc-hash = "2.1.1" rustyline-async = "0.4.7" diff --git a/assets/structures.json b/assets/structures.json index 4f6227654..53a0f22b3 100644 --- a/assets/structures.json +++ b/assets/structures.json @@ -1,12 +1,5 @@ { - "ancient_city": { - "use_expansion_hack": false, - "max_distance_from_center": 116, - "start_jigsaw_name": "minecraft:city_anchor", - "size": 7, - "start_height": { - "absolute": -27 - }, + "minecraft:ancient_city": { "biomes": "#minecraft:has_structure/ancient_city", "spawn_overrides": { "ambient": { @@ -45,40 +38,47 @@ "step": "underground_decoration", "terrain_adaptation": "beard_box", "start_pool": "minecraft:ancient_city/city_center", + "start_jigsaw_name": "minecraft:city_anchor", + "size": 7, + "start_height": { + "absolute": -27 + }, + "use_expansion_hack": false, + "max_distance_from_center": 116, "type": "minecraft:jigsaw" }, - "bastion_remnant": { - "use_expansion_hack": false, - "max_distance_from_center": 80, - "size": 6, - "start_height": { - "absolute": 33 - }, + "minecraft:bastion_remnant": { "biomes": "#minecraft:has_structure/bastion_remnant", "spawn_overrides": {}, "step": "surface_structures", "start_pool": "minecraft:bastion/starts", + "size": 6, + "start_height": { + "absolute": 33 + }, + "use_expansion_hack": false, + "max_distance_from_center": 80, "type": "minecraft:jigsaw" }, - "buried_treasure": { + "minecraft:buried_treasure": { "biomes": "#minecraft:has_structure/buried_treasure", "spawn_overrides": {}, "step": "underground_structures", "type": "minecraft:buried_treasure" }, - "desert_pyramid": { + "minecraft:desert_pyramid": { "biomes": "#minecraft:has_structure/desert_pyramid", "spawn_overrides": {}, "step": "surface_structures", "type": "minecraft:desert_pyramid" }, - "end_city": { + "minecraft:end_city": { "biomes": "#minecraft:has_structure/end_city", "spawn_overrides": {}, "step": "surface_structures", "type": "minecraft:end_city" }, - "fortress": { + "minecraft:fortress": { "biomes": "#minecraft:has_structure/nether_fortress", "spawn_overrides": { "monster": { @@ -120,39 +120,39 @@ "step": "underground_decoration", "type": "minecraft:fortress" }, - "igloo": { + "minecraft:igloo": { "biomes": "#minecraft:has_structure/igloo", "spawn_overrides": {}, "step": "surface_structures", "type": "minecraft:igloo" }, - "jungle_pyramid": { + "minecraft:jungle_pyramid": { "biomes": "#minecraft:has_structure/jungle_temple", "spawn_overrides": {}, "step": "surface_structures", "type": "minecraft:jungle_temple" }, - "mansion": { + "minecraft:mansion": { "biomes": "#minecraft:has_structure/woodland_mansion", "spawn_overrides": {}, "step": "surface_structures", "type": "minecraft:woodland_mansion" }, - "mineshaft": { + "minecraft:mineshaft": { "biomes": "#minecraft:has_structure/mineshaft", "spawn_overrides": {}, "step": "underground_structures", "mineshaft_type": "normal", "type": "minecraft:mineshaft" }, - "mineshaft_mesa": { + "minecraft:mineshaft_mesa": { "biomes": "#minecraft:has_structure/mineshaft_mesa", "spawn_overrides": {}, "step": "underground_structures", "mineshaft_type": "mesa", "type": "minecraft:mineshaft" }, - "monument": { + "minecraft:monument": { "biomes": "#minecraft:has_structure/ocean_monument", "spawn_overrides": { "axolotls": { @@ -178,7 +178,7 @@ "step": "surface_structures", "type": "minecraft:ocean_monument" }, - "nether_fossil": { + "minecraft:nether_fossil": { "biomes": "#minecraft:has_structure/nether_fossil", "spawn_overrides": {}, "step": "underground_decoration", @@ -194,7 +194,7 @@ }, "type": "minecraft:nether_fossil" }, - "ocean_ruin_cold": { + "minecraft:ocean_ruin_cold": { "biomes": "#minecraft:has_structure/ocean_ruin_cold", "spawn_overrides": {}, "step": "surface_structures", @@ -203,7 +203,7 @@ "cluster_probability": 0.9, "type": "minecraft:ocean_ruin" }, - "ocean_ruin_warm": { + "minecraft:ocean_ruin_warm": { "biomes": "#minecraft:has_structure/ocean_ruin_warm", "spawn_overrides": {}, "step": "surface_structures", @@ -212,14 +212,7 @@ "cluster_probability": 0.9, "type": "minecraft:ocean_ruin" }, - "pillager_outpost": { - "use_expansion_hack": true, - "project_start_to_heightmap": "WORLD_SURFACE_WG", - "max_distance_from_center": 80, - "size": 7, - "start_height": { - "absolute": 0 - }, + "minecraft:pillager_outpost": { "biomes": "#minecraft:has_structure/pillager_outpost", "spawn_overrides": { "monster": { @@ -237,176 +230,183 @@ "step": "surface_structures", "terrain_adaptation": "beard_thin", "start_pool": "minecraft:pillager_outpost/base_plates", + "size": 7, + "start_height": { + "absolute": 0 + }, + "use_expansion_hack": true, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 80, "type": "minecraft:jigsaw" }, - "ruined_portal": { + "minecraft:ruined_portal": { "biomes": "#minecraft:has_structure/ruined_portal_standard", "spawn_overrides": {}, "step": "surface_structures", "setups": [ { - "vines": false, - "can_be_cold": true, - "replace_with_blackstone": false, - "weight": 0.5, "placement": "underground", "air_pocket_probability": 1.0, "mossiness": 0.2, - "overgrown": false - }, - { + "overgrown": false, "vines": false, "can_be_cold": true, "replace_with_blackstone": false, - "weight": 0.5, + "weight": 0.5 + }, + { "placement": "on_land_surface", "air_pocket_probability": 0.5, "mossiness": 0.2, - "overgrown": false + "overgrown": false, + "vines": false, + "can_be_cold": true, + "replace_with_blackstone": false, + "weight": 0.5 } ], "type": "minecraft:ruined_portal" }, - "ruined_portal_desert": { + "minecraft:ruined_portal_desert": { "biomes": "#minecraft:has_structure/ruined_portal_desert", "spawn_overrides": {}, "step": "surface_structures", "setups": [ { - "vines": false, - "can_be_cold": false, - "replace_with_blackstone": false, - "weight": 1.0, "placement": "partly_buried", "air_pocket_probability": 0.0, "mossiness": 0.0, - "overgrown": false + "overgrown": false, + "vines": false, + "can_be_cold": false, + "replace_with_blackstone": false, + "weight": 1.0 } ], "type": "minecraft:ruined_portal" }, - "ruined_portal_jungle": { + "minecraft:ruined_portal_jungle": { "biomes": "#minecraft:has_structure/ruined_portal_jungle", "spawn_overrides": {}, "step": "surface_structures", "setups": [ { - "vines": true, - "can_be_cold": false, - "replace_with_blackstone": false, - "weight": 1.0, "placement": "on_land_surface", "air_pocket_probability": 0.5, "mossiness": 0.8, - "overgrown": true + "overgrown": true, + "vines": true, + "can_be_cold": false, + "replace_with_blackstone": false, + "weight": 1.0 } ], "type": "minecraft:ruined_portal" }, - "ruined_portal_mountain": { + "minecraft:ruined_portal_mountain": { "biomes": "#minecraft:has_structure/ruined_portal_mountain", "spawn_overrides": {}, "step": "surface_structures", "setups": [ { - "vines": false, - "can_be_cold": true, - "replace_with_blackstone": false, - "weight": 0.5, "placement": "in_mountain", "air_pocket_probability": 1.0, "mossiness": 0.2, - "overgrown": false - }, - { + "overgrown": false, "vines": false, "can_be_cold": true, "replace_with_blackstone": false, - "weight": 0.5, + "weight": 0.5 + }, + { "placement": "on_land_surface", "air_pocket_probability": 0.5, "mossiness": 0.2, - "overgrown": false + "overgrown": false, + "vines": false, + "can_be_cold": true, + "replace_with_blackstone": false, + "weight": 0.5 } ], "type": "minecraft:ruined_portal" }, - "ruined_portal_nether": { + "minecraft:ruined_portal_nether": { "biomes": "#minecraft:has_structure/ruined_portal_nether", "spawn_overrides": {}, "step": "surface_structures", "setups": [ { - "vines": false, - "can_be_cold": false, - "replace_with_blackstone": true, - "weight": 1.0, "placement": "in_nether", "air_pocket_probability": 0.5, "mossiness": 0.0, - "overgrown": false + "overgrown": false, + "vines": false, + "can_be_cold": false, + "replace_with_blackstone": true, + "weight": 1.0 } ], "type": "minecraft:ruined_portal" }, - "ruined_portal_ocean": { + "minecraft:ruined_portal_ocean": { "biomes": "#minecraft:has_structure/ruined_portal_ocean", "spawn_overrides": {}, "step": "surface_structures", "setups": [ { - "vines": false, - "can_be_cold": true, - "replace_with_blackstone": false, - "weight": 1.0, "placement": "on_ocean_floor", "air_pocket_probability": 0.0, "mossiness": 0.8, - "overgrown": false + "overgrown": false, + "vines": false, + "can_be_cold": true, + "replace_with_blackstone": false, + "weight": 1.0 } ], "type": "minecraft:ruined_portal" }, - "ruined_portal_swamp": { + "minecraft:ruined_portal_swamp": { "biomes": "#minecraft:has_structure/ruined_portal_swamp", "spawn_overrides": {}, "step": "surface_structures", "setups": [ { - "vines": true, - "can_be_cold": false, - "replace_with_blackstone": false, - "weight": 1.0, "placement": "on_ocean_floor", "air_pocket_probability": 0.0, "mossiness": 0.5, - "overgrown": false + "overgrown": false, + "vines": true, + "can_be_cold": false, + "replace_with_blackstone": false, + "weight": 1.0 } ], "type": "minecraft:ruined_portal" }, - "shipwreck": { + "minecraft:shipwreck": { "biomes": "#minecraft:has_structure/shipwreck", "spawn_overrides": {}, "step": "surface_structures", "is_beached": false, "type": "minecraft:shipwreck" }, - "shipwreck_beached": { + "minecraft:shipwreck_beached": { "biomes": "#minecraft:has_structure/shipwreck_beached", "spawn_overrides": {}, "step": "surface_structures", "is_beached": true, "type": "minecraft:shipwreck" }, - "stronghold": { + "minecraft:stronghold": { "biomes": "#minecraft:has_structure/stronghold", "spawn_overrides": {}, "step": "surface_structures", "terrain_adaptation": "bury", "type": "minecraft:stronghold" }, - "swamp_hut": { + "minecraft:swamp_hut": { "biomes": "#minecraft:has_structure/swamp_hut", "spawn_overrides": { "creature": { @@ -435,22 +435,72 @@ "step": "surface_structures", "type": "minecraft:swamp_hut" }, - "trail_ruins": { - "use_expansion_hack": false, - "project_start_to_heightmap": "WORLD_SURFACE_WG", - "max_distance_from_center": 80, - "size": 7, - "start_height": { - "absolute": -15 - }, + "minecraft:trail_ruins": { "biomes": "#minecraft:has_structure/trail_ruins", "spawn_overrides": {}, "step": "underground_structures", "terrain_adaptation": "bury", "start_pool": "minecraft:trail_ruins/tower", + "size": 7, + "start_height": { + "absolute": -15 + }, + "use_expansion_hack": false, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 80, "type": "minecraft:jigsaw" }, - "trial_chambers": { + "minecraft:trial_chambers": { + "biomes": "#minecraft:has_structure/trial_chambers", + "spawn_overrides": { + "ambient": { + "bounding_box": "piece", + "spawns": [] + }, + "axolotls": { + "bounding_box": "piece", + "spawns": [] + }, + "creature": { + "bounding_box": "piece", + "spawns": [] + }, + "misc": { + "bounding_box": "piece", + "spawns": [] + }, + "monster": { + "bounding_box": "piece", + "spawns": [] + }, + "underground_water_creature": { + "bounding_box": "piece", + "spawns": [] + }, + "water_ambient": { + "bounding_box": "piece", + "spawns": [] + }, + "water_creature": { + "bounding_box": "piece", + "spawns": [] + } + }, + "step": "underground_structures", + "terrain_adaptation": "encapsulate", + "start_pool": "minecraft:trial_chambers/chamber/end", + "size": 20, + "start_height": { + "min_inclusive": { + "absolute": -40 + }, + "max_inclusive": { + "absolute": -20 + }, + "type": "minecraft:uniform" + }, + "use_expansion_hack": false, + "max_distance_from_center": 116, "pool_aliases": [ { "groups": [ @@ -545,131 +595,81 @@ ], "dimension_padding": 10, "liquid_settings": "ignore_waterlogging", - "use_expansion_hack": false, - "max_distance_from_center": 116, - "size": 20, - "start_height": { - "min_inclusive": { - "absolute": -40 - }, - "max_inclusive": { - "absolute": -20 - }, - "type": "minecraft:uniform" - }, - "biomes": "#minecraft:has_structure/trial_chambers", - "spawn_overrides": { - "ambient": { - "bounding_box": "piece", - "spawns": [] - }, - "axolotls": { - "bounding_box": "piece", - "spawns": [] - }, - "creature": { - "bounding_box": "piece", - "spawns": [] - }, - "misc": { - "bounding_box": "piece", - "spawns": [] - }, - "monster": { - "bounding_box": "piece", - "spawns": [] - }, - "underground_water_creature": { - "bounding_box": "piece", - "spawns": [] - }, - "water_ambient": { - "bounding_box": "piece", - "spawns": [] - }, - "water_creature": { - "bounding_box": "piece", - "spawns": [] - } - }, - "step": "underground_structures", - "terrain_adaptation": "encapsulate", - "start_pool": "minecraft:trial_chambers/chamber/end", "type": "minecraft:jigsaw" }, - "village_desert": { - "use_expansion_hack": true, - "project_start_to_heightmap": "WORLD_SURFACE_WG", - "max_distance_from_center": 80, - "size": 6, - "start_height": { - "absolute": 0 - }, + "minecraft:village_desert": { "biomes": "#minecraft:has_structure/village_desert", "spawn_overrides": {}, "step": "surface_structures", "terrain_adaptation": "beard_thin", "start_pool": "minecraft:village/desert/town_centers", - "type": "minecraft:jigsaw" - }, - "village_plains": { - "use_expansion_hack": true, - "project_start_to_heightmap": "WORLD_SURFACE_WG", - "max_distance_from_center": 80, "size": 6, "start_height": { "absolute": 0 }, + "use_expansion_hack": true, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 80, + "type": "minecraft:jigsaw" + }, + "minecraft:village_plains": { "biomes": "#minecraft:has_structure/village_plains", "spawn_overrides": {}, "step": "surface_structures", "terrain_adaptation": "beard_thin", "start_pool": "minecraft:village/plains/town_centers", - "type": "minecraft:jigsaw" - }, - "village_savanna": { - "use_expansion_hack": true, - "project_start_to_heightmap": "WORLD_SURFACE_WG", - "max_distance_from_center": 80, "size": 6, "start_height": { "absolute": 0 }, + "use_expansion_hack": true, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 80, + "type": "minecraft:jigsaw" + }, + "minecraft:village_savanna": { "biomes": "#minecraft:has_structure/village_savanna", "spawn_overrides": {}, "step": "surface_structures", "terrain_adaptation": "beard_thin", "start_pool": "minecraft:village/savanna/town_centers", - "type": "minecraft:jigsaw" - }, - "village_snowy": { - "use_expansion_hack": true, - "project_start_to_heightmap": "WORLD_SURFACE_WG", - "max_distance_from_center": 80, "size": 6, "start_height": { "absolute": 0 }, + "use_expansion_hack": true, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 80, + "type": "minecraft:jigsaw" + }, + "minecraft:village_snowy": { "biomes": "#minecraft:has_structure/village_snowy", "spawn_overrides": {}, "step": "surface_structures", "terrain_adaptation": "beard_thin", "start_pool": "minecraft:village/snowy/town_centers", - "type": "minecraft:jigsaw" - }, - "village_taiga": { - "use_expansion_hack": true, - "project_start_to_heightmap": "WORLD_SURFACE_WG", - "max_distance_from_center": 80, "size": 6, "start_height": { "absolute": 0 }, + "use_expansion_hack": true, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 80, + "type": "minecraft:jigsaw" + }, + "minecraft:village_taiga": { "biomes": "#minecraft:has_structure/village_taiga", "spawn_overrides": {}, "step": "surface_structures", "terrain_adaptation": "beard_thin", "start_pool": "minecraft:village/taiga/town_centers", + "size": 6, + "start_height": { + "absolute": 0 + }, + "use_expansion_hack": true, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 80, "type": "minecraft:jigsaw" } } \ No newline at end of file diff --git a/pumpkin-util/src/math/block_box.rs b/pumpkin-util/src/math/block_box.rs index 2a8faeeec..44c332fc6 100644 --- a/pumpkin-util/src/math/block_box.rs +++ b/pumpkin-util/src/math/block_box.rs @@ -1,4 +1,7 @@ -use crate::math::{position::BlockPos, vector3::Vector3}; +use crate::math::{ + position::BlockPos, + vector3::{Axis, Vector3}, +}; #[derive(Clone, Copy, Debug)] pub struct BlockBox { @@ -21,6 +24,21 @@ impl BlockBox { }, } } + pub fn create_box( + x: i32, + y: i32, + z: i32, + axis: Axis, + width: i32, + height: i32, + depth: i32, + ) -> Self { + if axis == Axis::Z { + Self::new(x, y, z, x + width - 1, y + height - 1, z + depth - 1) + } else { + Self::new(x, y, z, x + depth - 1, y + height - 1, z + width - 1) + } + } pub fn from_pos(pos: BlockPos) -> Self { Self { diff --git a/pumpkin-util/src/random/mod.rs b/pumpkin-util/src/random/mod.rs index f0393c31f..59e0c3f33 100644 --- a/pumpkin-util/src/random/mod.rs +++ b/pumpkin-util/src/random/mod.rs @@ -69,17 +69,15 @@ pub fn get_decorator_seed(population_seed: u64, index: usize, step: usize) -> u6 } #[inline] -pub fn get_region_seed(world_seed: u64, region_x: i32, region_z: i32, salt: i32) -> u64 { - let region_x_long: u64 = region_x as u64; - let region_z_long: u64 = region_z as u64; - let salt_long: u64 = salt as u64; - region_x_long - .wrapping_mul(341873128712) - .wrapping_add(region_z_long.wrapping_mul(132897987541)) - .wrapping_add(world_seed) - .wrapping_add(salt_long) -} +pub fn get_region_seed(world_seed: u64, region_x: i32, region_z: i32, salt: u32) -> u64 { + let x_part = (region_x as i64).wrapping_mul(341873128712) as u64; + let z_part = (region_z as i64).wrapping_mul(132897987541) as u64; + world_seed + .wrapping_add(x_part) + .wrapping_add(z_part) + .wrapping_add(salt as i64 as u64) +} #[inline] pub fn get_carver_seed( random: &mut RandomGenerator, @@ -152,8 +150,16 @@ pub fn hash_block_pos(x: i32, y: i32, z: i32) -> i64 { #[cfg(test)] mod tests { + use crate::random::get_region_seed; + use super::hash_block_pos; + #[test] + fn region_seed() { + let seed = get_region_seed(12345612, 1, 1, 14357620); + assert_eq!(seed, 474797819485) + } + #[test] fn block_position_hash() { let values: [((i32, i32, i32), i64); 8] = [ diff --git a/pumpkin-world/src/chunk_system.rs b/pumpkin-world/src/chunk_system.rs index 3e8e446a6..db1f8ae11 100644 --- a/pumpkin-world/src/chunk_system.rs +++ b/pumpkin-world/src/chunk_system.rs @@ -515,6 +515,8 @@ pub enum StagedChunkEnum { Empty = 1, // EMPTY STRUCTURE_STARTS STRUCTURE_REFERENCES /// Chunk with biomes populated, ready for noise generation Biomes, + StructureStart, + StructureReferences, /// Chunk with terrain noise generated, ready for surface building Noise, /// Chunk with surface built, ready for features and structures @@ -528,12 +530,14 @@ pub enum StagedChunkEnum { impl From for StagedChunkEnum { fn from(v: u8) -> Self { match v { - 1 => Empty, - 2 => Biomes, - 3 => Noise, - 4 => Surface, - 5 => Features, - 6 => Full, + 1 => Self::Empty, + 2 => Self::Biomes, + 3 => Self::StructureStart, + 4 => Self::StructureReferences, + 5 => Self::Noise, + 6 => Self::Surface, + 7 => Self::Features, + 8 => Self::Full, _ => panic!(), } } @@ -543,8 +547,8 @@ impl From for StagedChunkEnum { fn from(status: ChunkStatus) -> Self { match status { ChunkStatus::Empty => Empty, - ChunkStatus::StructureStarts => Empty, - ChunkStatus::StructureReferences => Empty, + ChunkStatus::StructureStarts => StagedChunkEnum::StructureStart, + ChunkStatus::StructureReferences => StagedChunkEnum::StructureReferences, ChunkStatus::Biomes => Biomes, ChunkStatus::Noise => Noise, ChunkStatus::Surface => Surface, @@ -561,12 +565,14 @@ impl From for StagedChunkEnum { impl From for ChunkStatus { fn from(status: StagedChunkEnum) -> Self { match status { - Empty => ChunkStatus::Empty, - Biomes => ChunkStatus::Biomes, - Noise => ChunkStatus::Noise, - Surface => ChunkStatus::Surface, - Features => ChunkStatus::Features, - Full => ChunkStatus::Full, + StagedChunkEnum::Empty => ChunkStatus::Empty, + StagedChunkEnum::StructureStart => ChunkStatus::StructureStarts, + StagedChunkEnum::StructureReferences => ChunkStatus::StructureReferences, + StagedChunkEnum::Biomes => ChunkStatus::Biomes, + StagedChunkEnum::Noise => ChunkStatus::Noise, + StagedChunkEnum::Surface => ChunkStatus::Surface, + StagedChunkEnum::Features => ChunkStatus::Features, + StagedChunkEnum::Full => ChunkStatus::Full, _ => panic!(), } } @@ -589,34 +595,40 @@ impl StagedChunkEnum { const fn get_direct_radius(self) -> i32 { // self exclude match self { - Empty => 0, - Biomes => 0, - Noise => 0, - Surface => 0, - Features => 1, - Full => 1, + Self::Empty => 0, + Self::StructureStart => 0, + Self::StructureReferences => 0, + Self::Biomes => 0, + Self::Noise => 0, + Self::Surface => 0, + Self::Features => 1, + Self::Full => 1, _ => panic!(), } } const fn get_write_radius(self) -> i32 { // self exclude match self { - Empty => 0, - Biomes => 0, - Noise => 0, - Surface => 0, - Features => 1, - Full => 0, + Self::Empty => 0, + Self::StructureStart => 0, + Self::StructureReferences => 0, + Self::Biomes => 0, + Self::Noise => 0, + Self::Surface => 0, + Self::Features => 1, + Self::Full => 0, _ => panic!(), } } const fn get_direct_dependencies(self) -> &'static [StagedChunkEnum] { match self { - Biomes => &[Empty], - Noise => &[Biomes], - Surface => &[Noise], - Features => &[Surface, Surface], - Full => &[Features, Features], + Self::Biomes => &[Self::Empty], + Self::StructureStart => &[Self::Biomes], + Self::StructureReferences => &[Self::StructureStart], + Self::Noise => &[Self::StructureReferences], + Self::Surface => &[Self::Noise], + Self::Features => &[Self::Surface, Self::Surface], + Self::Full => &[Self::Features, Self::Features], _ => panic!(), } } @@ -754,7 +766,7 @@ impl Chunk { fn get_stage_id(&self) -> u8 { match self { Chunk::Proto(data) => data.stage_id(), - Chunk::Level(_) => 6, + Chunk::Level(_) => 8, } } fn get_proto_chunk_mut(&mut self) -> &mut ProtoChunk { @@ -1103,6 +1115,12 @@ impl Cache { let mid = ((self.size * self.size) >> 1) as usize; match stage { Empty => panic!("empty stage"), + StagedChunkEnum::StructureStart => self.chunks[mid] + .get_proto_chunk_mut() + .set_structure_starts(random_config), + StagedChunkEnum::StructureReferences => self.chunks[mid] + .get_proto_chunk_mut() + .set_structure_references(), Biomes => self.chunks[mid] .get_proto_chunk_mut() .step_to_biomes(dimension, noise_router), @@ -1125,7 +1143,7 @@ impl Cache { self.chunks[mid].get_proto_chunk_mut().stage = Full; self.chunks[mid].upgrade_to_level_chunk(settings); } - _ => panic!("unknown stage {stage:?}"), + StagedChunkEnum::None => {} } } } @@ -1213,7 +1231,7 @@ struct ChunkHolder { pub occupied: NodeKey, pub occupied_by: EdgeKey, pub public: bool, - pub tasks: [NodeKey; 7], + pub tasks: [NodeKey; 9], } impl Default for ChunkHolder { @@ -1225,7 +1243,7 @@ impl Default for ChunkHolder { occupied: NodeKey::null(), occupied_by: EdgeKey::null(), public: false, - tasks: [NodeKey::null(); 7], + tasks: [NodeKey::null(); 9], } } } diff --git a/pumpkin-world/src/generation/proto_chunk.rs b/pumpkin-world/src/generation/proto_chunk.rs index 38fd1020e..a587fb827 100644 --- a/pumpkin-world/src/generation/proto_chunk.rs +++ b/pumpkin-world/src/generation/proto_chunk.rs @@ -136,6 +136,7 @@ pub struct ProtoChunk { pub flat_motion_blocking_no_leaves_height_map: Box<[i16]>, // may want to use chunk status structure_starts: HashMap, + // Height of the chunk for indexing height: u16, bottom_y: i8, @@ -479,7 +480,6 @@ impl ProtoChunk { } pub fn step_to_biomes(&mut self, dimension: Dimension, noise_router: &ProtoNoiseRouters) { - debug_assert_eq!(self.stage, StagedChunkEnum::Empty); let start_x = start_block_x(self.x); let start_z = start_block_z(self.z); let horizontal_biome_end = biome_coords::from_block(16); @@ -501,7 +501,7 @@ impl ProtoChunk { random_config: &GlobalRandomConfig, noise_router: &ProtoNoiseRouters, ) { - debug_assert_eq!(self.stage, StagedChunkEnum::Biomes); + //debug_assert_eq!(self.stage, StagedChunkEnum::Biomes); let generation_shape = &settings.shape; let horizontal_cell_count = CHUNK_DIM / generation_shape.horizontal_cell_block_count(); @@ -913,17 +913,14 @@ impl ProtoChunk { let _chunk_box = chunk.get_block_box_for_chunk(); for (_structure_config, instance) in chunk.structure_starts.clone() { + dbg!("generating"); match instance { StructureInstance::Start(pos, _stype) => { // Use the collector directly to place blocks pos.collector .generate_in_chunk(chunk, random_config.seed as i64); } - StructureInstance::Reference(_start_block_pos) => { - // In Minecraft, a Reference tells the engine to look up the - // "Start" data from the chunk at start_block_pos and generate its pieces here. - // If you are only generating "Starts" for now, this can be a TODO. - } + StructureInstance::Reference(_start_block_pos) => {} } } // TODO: This needs to be different depending on what biomes are in the chunk -> affects the @@ -947,42 +944,40 @@ impl ProtoChunk { } pub fn set_structure_starts(&mut self, random_config: &GlobalRandomConfig) { - for (name, set) in STRUCTURE_SETS.iter() { + for (_set_name, set) in STRUCTURE_SETS.iter() { let calculator = StructurePlacementCalculator { seed: random_config.seed as i64, }; - // 1. Check if the placement allows a structure to start in THIS specific chunk if !set.placement.should_generate(calculator, self.x, self.z) { continue; } - - // 2. Iterate through potential structures in the set - for structure_entry in &set.structures { - // FIX: Pass the 'name', 'seed', 'coords', and 'self' (the ProtoChunk) + if set.structures.len() == 1 + && let Some(structure_entry) = set.structures.first() + { let position = structure_entry.structure.try_generate( - name, random_config.seed as i64, self.x, self.z, self, ); - if let Some(pos) = position { - // Ensure the structure config exists in our registry - if let Some(structure_config) = STRUCTURES.get(name) { - // Minecraft logic: Insert the START in the origin chunk - self.structure_starts.insert( - structure_config.clone(), - StructureInstance::Start(pos, structure_entry.structure.clone()), - ); - - // Minecraft optimization: Usually only one structure start per chunk - return; - } + if let Some(pos) = position + && let Some(structure_config) = STRUCTURES.get(&structure_entry.structure) + { + self.structure_starts.insert( + structure_config.clone(), + StructureInstance::Start(pos, structure_entry.structure.clone()), + ); } } + // TODO add weight } + self.stage = StagedChunkEnum::StructureStart; + } + + pub fn set_structure_references(&mut self) { + self.stage = StagedChunkEnum::StructureReferences; } fn get_block_box_for_chunk(&self) -> BlockBox { diff --git a/pumpkin-world/src/generation/structure/mod.rs b/pumpkin-world/src/generation/structure/mod.rs index 06fa2c5da..a6bd199ab 100644 --- a/pumpkin-world/src/generation/structure/mod.rs +++ b/pumpkin-world/src/generation/structure/mod.rs @@ -6,11 +6,14 @@ use serde::Deserialize; use crate::{ ProtoChunk, - generation::structure::{ - placement::StructurePlacement, - structures::{ - StructureGenerator, StructurePosition, buried_treasure::BuriedTreasureGenerator, - nether_fortress::NetherFortressGenerator, + generation::{ + biome_coords, + structure::{ + placement::StructurePlacement, + structures::{ + StructureGenerator, StructurePosition, buried_treasure::BuriedTreasureGenerator, + nether_fortress::NetherFortressGenerator, swamp_hut::SwampHutGenerator, + }, }, }, }; @@ -21,55 +24,169 @@ pub mod structures; #[derive(Deserialize)] pub struct StructureSet { pub placement: StructurePlacement, - pub structures: Vec, + pub structures: Vec, } #[derive(Deserialize)] -pub struct Structures { - pub structure: StructureType, +pub struct WeightedEntry { + pub structure: StructureKeys, + pub weight: u32, } #[derive(Deserialize, Clone)] pub enum StructureType { #[serde(rename = "minecraft:buried_treasure")] BuriedTreasure(BuriedTreasureGenerator), + #[serde(rename = "minecraft:desert_pyramid")] + DesertPyramid, + #[serde(rename = "minecraft:end_city")] + EndCity, #[serde(rename = "minecraft:fortress")] NetherFortress(NetherFortressGenerator), + #[serde(rename = "minecraft:igloo")] + Igloo, + #[serde(rename = "minecraft:jigsaw")] + Jigsaw, + #[serde(rename = "minecraft:jungle_temple")] + JungleTemple, + #[serde(rename = "minecraft:mineshaft")] + Mineshaft, + #[serde(rename = "minecraft:nether_fossil")] + NetherFossil, + #[serde(rename = "minecraft:ocean_monument")] + OceanMonument, + #[serde(rename = "minecraft:ocean_ruin")] + OceanRuin, + #[serde(rename = "minecraft:ruined_portal")] + RuinedPortal, + #[serde(rename = "minecraft:shipwreck")] + Shipwreck, + #[serde(rename = "minecraft:stronghold")] + Stronghold, + #[serde(rename = "minecraft:swamp_hut")] + SwampHut(SwampHutGenerator), + #[serde(rename = "minecraft:woodland_mansion")] + WoodlandMansion, } -impl StructureType { +#[derive(Deserialize, Clone, PartialEq, Eq, Hash)] +pub enum StructureKeys { + #[serde(rename = "minecraft:pillager_outpost")] + PillagerOutpost, + #[serde(rename = "minecraft:mineshaft")] + Mineshaft, + #[serde(rename = "minecraft:mineshaft_mesa")] + MineshaftMesa, + #[serde(rename = "minecraft:mansion")] + Mansion, + #[serde(rename = "minecraft:jungle_pyramid")] + JunglePyramid, + #[serde(rename = "minecraft:desert_pyramid")] + DesertPyramid, + #[serde(rename = "minecraft:igloo")] + Igloo, + #[serde(rename = "minecraft:shipwreck")] + Shipwreck, + #[serde(rename = "minecraft:shipwreck_beached")] + ShipwreckBeached, + #[serde(rename = "minecraft:swamp_hut")] + SwampHut, + #[serde(rename = "minecraft:stronghold")] + Stronghold, + #[serde(rename = "minecraft:monument")] + Monument, + #[serde(rename = "minecraft:ocean_ruin_cold")] + OceanRuinCold, + #[serde(rename = "minecraft:ocean_ruin_warm")] + OceanRuinWarm, + #[serde(rename = "minecraft:fortress")] + Fortress, + #[serde(rename = "minecraft:nether_fossil")] + NetherFossil, + #[serde(rename = "minecraft:end_city")] + EndCity, + #[serde(rename = "minecraft:buried_treasure")] + BuriedTreasure, + #[serde(rename = "minecraft:bastion_remnant")] + BastionRemnant, + #[serde(rename = "minecraft:village_plains")] + VillagePlains, + #[serde(rename = "minecraft:village_desert")] + VillageDesert, + #[serde(rename = "minecraft:village_savanna")] + VillageSavanna, + #[serde(rename = "minecraft:village_snowy")] + VillageSnowy, + #[serde(rename = "minecraft:village_taiga")] + VillageTaiga, + #[serde(rename = "minecraft:ruined_portal")] + RuinedPortal, + #[serde(rename = "minecraft:ruined_portal_desert")] + RuinedPortalDesert, + #[serde(rename = "minecraft:ruined_portal_jungle")] + RuinedPortalJungle, + #[serde(rename = "minecraft:ruined_portal_swamp")] + RuinedPortalSwamp, + #[serde(rename = "minecraft:ruined_portal_mountain")] + RuinedPortalMountain, + #[serde(rename = "minecraft:ruined_portal_ocean")] + RuinedPortalOcean, + #[serde(rename = "minecraft:ruined_portal_nether")] + RuinedPortalNether, + #[serde(rename = "minecraft:ancient_city")] + AncientCity, + #[serde(rename = "minecraft:trail_ruins")] + TrailRuins, + #[serde(rename = "minecraft:trial_chambers")] + TrialChambers, +} + +#[derive(Deserialize, Clone)] +pub struct EmptyStruct {} + +impl StructureKeys { pub fn try_generate( &self, - name: &str, seed: i64, chunk_x: i32, chunk_z: i32, chunk_ref_for_biomes: &ProtoChunk, ) -> Option { let structure_pos = match self { - StructureType::BuriedTreasure(generator) => { - generator.try_generate(seed, chunk_x, chunk_z) - } - StructureType::NetherFortress(generator) => { - generator.try_generate(seed, chunk_x, chunk_z) - } + StructureKeys::BuriedTreasure => BuriedTreasureGenerator::get_structure_position( + &BuriedTreasureGenerator, + seed, + chunk_x, + chunk_z, + ), + StructureKeys::Fortress => NetherFortressGenerator::get_structure_position( + &NetherFortressGenerator, + seed, + chunk_x, + chunk_z, + ), + StructureKeys::SwampHut => SwampHutGenerator::get_structure_position( + &SwampHutGenerator, + seed, + chunk_x, + chunk_z, + ), + // TODO + _ => None, }; if let Some(pos) = structure_pos - && let Some(structure_data) = STRUCTURES.get(name) + && let Some(structure_data) = STRUCTURES.get(self) { // Get the biome at the structure's starting position let current_biome = chunk_ref_for_biomes.get_biome( - pos.start_pos.0.x, - pos.start_pos.0.y, - pos.start_pos.0.z, + biome_coords::from_block(pos.start_pos.0.x), + biome_coords::from_block(pos.start_pos.0.y), + biome_coords::from_block(pos.start_pos.0.z), ); - + let biomes = Biome::get_tag_values(&structure_data.biomes).unwrap(); // Check if the biome is allowed for this structure - if Biome::get_tag_values(&structure_data.biomes) - .unwrap_or_default() - .contains(¤t_biome.registry_id) - { + if biomes.contains(¤t_biome.registry_id) { return Some(pos); } } @@ -91,8 +208,8 @@ pub struct Structure { biomes: String, } -pub static STRUCTURES: LazyLock> = LazyLock::new( - || include_json_static!("../../../../assets/structures.json", HashMap), +pub static STRUCTURES: LazyLock> = LazyLock::new( + || include_json_static!("../../../../assets/structures.json", HashMap), ); pub static STRUCTURE_SETS: LazyLock> = LazyLock::new( diff --git a/pumpkin-world/src/generation/structure/placement.rs b/pumpkin-world/src/generation/structure/placement.rs index 1af120981..ddd196134 100644 --- a/pumpkin-world/src/generation/structure/placement.rs +++ b/pumpkin-world/src/generation/structure/placement.rs @@ -1,7 +1,8 @@ use pumpkin_util::{ math::floor_div, random::{ - RandomGenerator, RandomImpl, get_carver_seed, get_region_seed, xoroshiro128::Xoroshiro, + RandomGenerator, RandomImpl, get_carver_seed, get_region_seed, legacy_rand::LegacyRand, + xoroshiro128::Xoroshiro, }, }; use serde::Deserialize; @@ -10,7 +11,7 @@ use serde::Deserialize; pub struct StructurePlacement { frequency_reduction_method: Option, frequency: Option, - salt: i32, + salt: u32, #[serde(flatten)] r#type: StructurePlacementType, } @@ -43,8 +44,11 @@ impl StructurePlacement { #[serde(rename_all = "snake_case")] pub enum FrequencyReductionMethod { Default, + #[serde(rename = "legacy_type_1")] LegacyType1, + #[serde(rename = "legacy_type_2")] LegacyType2, + #[serde(rename = "legacy_type_3")] LegacyType3, } @@ -54,7 +58,7 @@ impl FrequencyReductionMethod { seed: i64, chunk_x: i32, chunk_z: i32, - salt: i32, + salt: u32, frequency: f32, ) -> bool { match self { @@ -105,7 +109,7 @@ impl StructurePlacementType { calculator: &StructurePlacementCalculator, chunk_x: i32, chunk_z: i32, - salt: i32, + salt: u32, ) -> bool { match self { StructurePlacementType::RandomSpread(placement) => { @@ -120,7 +124,7 @@ impl StructurePlacementType { pub struct RandomSpreadStructurePlacement { spacing: i32, separation: i32, - spread_type: SpreadType, + spread_type: Option, } #[derive(Deserialize)] @@ -142,14 +146,15 @@ impl SpreadType { } impl RandomSpreadStructurePlacement { - fn get_start_chunk(&self, seed: i64, chunk_x: i32, chunk_z: i32, salt: i32) -> (i32, i32) { + fn get_start_chunk(&self, seed: i64, chunk_x: i32, chunk_z: i32, salt: u32) -> (i32, i32) { let x = floor_div(chunk_x, self.spacing); let z = floor_div(chunk_z, self.spacing); let region_seed = get_region_seed(seed as u64, x, z, salt); - let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(region_seed)); + let mut random = RandomGenerator::Legacy(LegacyRand::from_seed(region_seed)); let bound = self.spacing - self.separation; - let rand_x = self.spread_type.get(&mut random, bound); - let rand_z = self.spread_type.get(&mut random, bound); + let spread_type = self.spread_type.as_ref().unwrap_or(&SpreadType::Linear); + let rand_x = spread_type.get(&mut random, bound); + let rand_z = spread_type.get(&mut random, bound); (x * self.spacing + rand_x, z * self.spacing + rand_z) } @@ -158,7 +163,7 @@ impl RandomSpreadStructurePlacement { calculator: &StructurePlacementCalculator, chunk_x: i32, chunk_z: i32, - salt: i32, + salt: u32, ) -> bool { let pos = self.get_start_chunk(calculator.seed, chunk_x, chunk_z, salt); (chunk_x == pos.0) && (chunk_z == pos.1) @@ -168,3 +173,31 @@ impl RandomSpreadStructurePlacement { pub struct StructurePlacementCalculator { pub seed: i64, } + +#[cfg(test)] +mod tests { + use pumpkin_util::random::{ + RandomGenerator, RandomImpl, get_region_seed, legacy_rand::LegacyRand, + }; + + use crate::generation::structure::placement::RandomSpreadStructurePlacement; + + #[test] + fn test_get_start_chunk_random() { + let region_seed = get_region_seed(123, 1, 1, 14357620); + let mut random = RandomGenerator::Legacy(LegacyRand::from_seed(region_seed)); + assert_eq!(random.next_bounded_i32(32 - 8), 8) + } + + #[test] + fn test_get_start_chunk() { + let random = RandomSpreadStructurePlacement { + spacing: 32, + separation: 8, + spread_type: None, + }; + let (x, z) = random.get_start_chunk(123, 1, 1, 14357620); + assert_eq!(x, 5); + assert_eq!(z, 4); + } +} diff --git a/pumpkin-world/src/generation/structure/structures/buried_treasure.rs b/pumpkin-world/src/generation/structure/structures/buried_treasure.rs index 1ac655e4d..8a1379d1a 100644 --- a/pumpkin-world/src/generation/structure/structures/buried_treasure.rs +++ b/pumpkin-world/src/generation/structure/structures/buried_treasure.rs @@ -19,7 +19,12 @@ use crate::{ pub struct BuriedTreasureGenerator; impl StructureGenerator for BuriedTreasureGenerator { - fn try_generate(&self, _seed: i64, chunk_x: i32, chunk_z: i32) -> Option { + fn get_structure_position( + &self, + _seed: i64, + chunk_x: i32, + chunk_z: i32, + ) -> Option { let x = get_center_x(chunk_x); let z = get_center_z(chunk_z); diff --git a/pumpkin-world/src/generation/structure/structures/mod.rs b/pumpkin-world/src/generation/structure/structures/mod.rs index e71253915..4a8892227 100644 --- a/pumpkin-world/src/generation/structure/structures/mod.rs +++ b/pumpkin-world/src/generation/structure/structures/mod.rs @@ -5,7 +5,7 @@ use pumpkin_util::math::{block_box::BlockBox, position::BlockPos, vector3::Vecto use crate::{ ProtoChunk, - generation::{height_limit::HeightLimitView, structure::StructureType}, + generation::{height_limit::HeightLimitView, structure::StructureKeys}, }; pub mod buried_treasure; @@ -101,8 +101,6 @@ pub fn fill_downwards(x: i32, y: i32, z: i32, state: &BlockState, chunk: &mut Pr let start_y = y; let end_y = chunk.bottom_y() as i32; // e.g. -64 - // FIX: Use .rev() because ranges like 60..-64 are empty. - // Also, usually you want to stop if you hit a solid block (optional, depends on need). for current_y in (end_y..=start_y).rev() { chunk.set_block_state(&Vector3::new(x, current_y, z), state); } @@ -160,13 +158,18 @@ pub struct StructurePosition { } pub trait StructureGenerator { - fn try_generate(&self, seed: i64, chunk_x: i32, chunk_z: i32) -> Option; + fn get_structure_position( + &self, + seed: i64, + chunk_x: i32, + chunk_z: i32, + ) -> Option; } #[derive(Clone)] pub enum StructureInstance { /// This chunk is the "owner" of the structure. - Start(StructurePosition, StructureType), + Start(StructurePosition, StructureKeys), /// This chunk just contains a piece of a structure starting elsewhere. /// Stores the BlockPos of the 'Start' so you can look it up. Reference(BlockPos), diff --git a/pumpkin-world/src/generation/structure/structures/nether_fortress.rs b/pumpkin-world/src/generation/structure/structures/nether_fortress.rs index 0aa5e4027..044abcfdd 100644 --- a/pumpkin-world/src/generation/structure/structures/nether_fortress.rs +++ b/pumpkin-world/src/generation/structure/structures/nether_fortress.rs @@ -17,7 +17,12 @@ use crate::{ pub struct NetherFortressGenerator; impl StructureGenerator for NetherFortressGenerator { - fn try_generate(&self, _seed: i64, chunk_x: i32, chunk_z: i32) -> Option { + fn get_structure_position( + &self, + _seed: i64, + chunk_x: i32, + chunk_z: i32, + ) -> Option { let start_x = chunk_pos::start_block_x(chunk_x); let start_z = chunk_pos::start_block_z(chunk_z); let start_y = 64; diff --git a/pumpkin-world/src/generation/structure/structures/swamp_hut.rs b/pumpkin-world/src/generation/structure/structures/swamp_hut.rs index f78dc85af..88888d4e3 100644 --- a/pumpkin-world/src/generation/structure/structures/swamp_hut.rs +++ b/pumpkin-world/src/generation/structure/structures/swamp_hut.rs @@ -1,7 +1,11 @@ use pumpkin_data::Block; use pumpkin_util::{ HeightMap, - math::{block_box::BlockBox, position::BlockPos, vector3::Vector3}, + math::{ + block_box::BlockBox, + position::BlockPos, + vector3::{Axis, Vector3}, + }, }; use serde::Deserialize; @@ -20,14 +24,17 @@ use crate::{ pub struct SwampHutGenerator; impl StructureGenerator for SwampHutGenerator { - fn try_generate(&self, _seed: i64, chunk_x: i32, chunk_z: i32) -> Option { + fn get_structure_position( + &self, + _seed: i64, + chunk_x: i32, + chunk_z: i32, + ) -> Option { let x = get_center_x(chunk_x); let z = get_center_z(chunk_z); - let box_min_x = x; - let box_min_z = z; - let bounding_box = - BlockBox::new(box_min_x, 60, box_min_z, box_min_x + 7, 80, box_min_z + 7); + // TODO: random axis + let bounding_box = BlockBox::create_box(x, 64, z, Axis::X, 7, 7, 9); let mut collector = StructurePiecesCollector::default(); collector.add_piece(Box::new(SwampHutPiece { bounding_box })); @@ -50,62 +57,148 @@ impl StructurePiece for SwampHutPiece { } fn place(&self, chunk: &mut ProtoChunk, _seed: i64) { - let origin_x = self.bounding_box.min.x; - let origin_z = self.bounding_box.min.z; + let min = self.bounding_box.min; + let origin_x = min.x; + let origin_z = min.z; - // Find surface height (approximate, usually slightly submerged in swamp) - let floor_y = chunk.get_top_y(&HeightMap::OceanFloorWg, origin_x + 3, origin_z + 3) + 3; // +3 to lift it up + // Vanilla uses adjustToAverageHeight. + let surface_y = chunk.get_top_y(&HeightMap::OceanFloorWg, origin_x + 3, origin_z + 3); + let origin_y = surface_y + 1; - let origin_y = floor_y; + let spruce_planks = &Block::SPRUCE_PLANKS.default_state; + let oak_log = &Block::OAK_LOG.default_state; + let oak_fence = &Block::OAK_FENCE.default_state; + let air = &Block::AIR.default_state; - let fill_rel = |min_x, min_y, min_z, max_x, max_y, max_z, block, c: &mut ProtoChunk| { + // 1. THE FLOOR + fill( + origin_x + 1, + origin_y + 1, + origin_z + 1, + origin_x + 5, + origin_y + 1, + origin_z + 7, + spruce_planks, + chunk, + ); + + // 2. THE CEILING + fill( + origin_x + 1, + origin_y + 4, + origin_z + 2, + origin_x + 5, + origin_y + 4, + origin_z + 7, + spruce_planks, + chunk, + ); + + // 3. THE ENTRANCE PLATFORM + fill( + origin_x + 2, + origin_y + 1, + origin_z, + origin_x + 4, + origin_y + 1, + origin_z, + spruce_planks, + chunk, + ); + + // Front Wall + fill( + origin_x + 2, + origin_y + 2, + origin_z + 2, + origin_x + 3, + origin_y + 3, + origin_z + 2, + spruce_planks, + chunk, + ); + // Left Wall + fill( + origin_x + 1, + origin_y + 2, + origin_z + 3, + origin_x + 1, + origin_y + 3, + origin_z + 6, + spruce_planks, + chunk, + ); + // Right Wall + fill( + origin_x + 5, + origin_y + 2, + origin_z + 3, + origin_x + 5, + origin_y + 3, + origin_z + 6, + spruce_planks, + chunk, + ); + // Back Wall + fill( + origin_x + 2, + origin_y + 2, + origin_z + 7, + origin_x + 4, + origin_y + 3, + origin_z + 7, + spruce_planks, + chunk, + ); + + // 5. THE LOGS + let logs = [(1, 2), (5, 2), (1, 7), (5, 7)]; + for (lx, lz) in logs { fill( - origin_x + min_x, - origin_y + min_y, - origin_z + min_z, - origin_x + max_x, - origin_y + max_y, - origin_z + max_z, - block, - c, - ) - }; - - let offset = |x, y, z| Vector3::new(origin_x + x, origin_y + y, origin_z + z); - - // 1. Stilts (Logs downwards) - let spruce_log = &Block::SPRUCE_LOG.default_state; - let stilts = [(1, 1), (1, 6), (6, 1), (6, 6)]; - - for (sx, sz) in stilts { - fill_downwards(origin_x + sx, origin_y, origin_z + sz, spruce_log, chunk); + origin_x + lx, + origin_y, + origin_z + lz, + origin_x + lx, + origin_y + 3, + origin_z + lz, + oak_log, + chunk, + ); + fill_downwards(origin_x + lx, origin_y - 1, origin_z + lz, oak_log, chunk); } - // 2. Main Platform (Spruce Planks) - let spruce_planks = &Block::SPRUCE_PLANKS.default_state; - fill_rel(0, 0, 0, 7, 0, 7, spruce_planks, chunk); + // Placed at Y=2 (feet level) or Y=3 (eye level) + let y_floor = origin_y + 2; + let y_eye = origin_y + 3; - // 3. Walls - fill_rel(0, 1, 0, 7, 3, 0, spruce_planks, chunk); // North - fill_rel(0, 1, 7, 7, 3, 7, spruce_planks, chunk); // South - fill_rel(0, 1, 0, 0, 3, 7, spruce_planks, chunk); // West - fill_rel(7, 1, 0, 7, 3, 7, spruce_planks, chunk); // East + chunk.set_block_state( + &Vector3::new(origin_x + 3, y_floor, origin_z + 6), + Block::CRAFTING_TABLE.default_state, + ); + chunk.set_block_state( + &Vector3::new(origin_x + 4, y_floor, origin_z + 6), + Block::CAULDRON.default_state, + ); + chunk.set_block_state( + &Vector3::new(origin_x + 1, y_eye, origin_z + 5), + Block::POTTED_RED_MUSHROOM.default_state, + ); - // 4. Roof (Simple block roof for now, stairs are complex without proper state orientation helpers) - fill_rel(0, 4, 0, 7, 4, 7, spruce_planks, chunk); - fill_rel(1, 5, 1, 6, 5, 6, spruce_planks, chunk); + // Fences & Gaps + chunk.set_block_state(&Vector3::new(origin_x + 2, y_eye, origin_z + 2), oak_fence); // Above the door + chunk.set_block_state(&Vector3::new(origin_x + 3, y_eye, origin_z + 7), oak_fence); // Back window + chunk.set_block_state( + &Vector3::new(origin_x + 1, y_floor, origin_z + 1), + oak_fence, + ); // Balcony left + chunk.set_block_state( + &Vector3::new(origin_x + 5, y_floor, origin_z + 1), + oak_fence, + ); // Balcony right - // 5. Windows/Air - fill_rel(1, 1, 1, 6, 3, 6, Block::AIR.default_state, chunk); // Clear inside - - // 6. Interior Decorations - chunk.set_block_state(&offset(2, 1, 2), Block::CRAFTING_TABLE.default_state); - chunk.set_block_state(&offset(2, 1, 3), Block::CAULDRON.default_state); - - // Note: Flower Pot usually requires block entity data or specific state, simplifying here - chunk.set_block_state(&offset(5, 1, 3), Block::POTTED_BLUE_ORCHID.default_state); - - // Fence on balcony - chunk.set_block_state(&offset(3, 1, 0), Block::OAK_FENCE.default_state); + // Clear window air (Java: addBlock AIR at 1, 3, 4 and 5, 3, 4/5) + chunk.set_block_state(&Vector3::new(origin_x + 1, y_eye, origin_z + 4), air); + chunk.set_block_state(&Vector3::new(origin_x + 5, y_eye, origin_z + 4), air); + chunk.set_block_state(&Vector3::new(origin_x + 5, y_eye, origin_z + 5), air); } }