mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 16:50:28 +00:00
Compare commits
1644 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5f3a2bb579 | |||
| 9a94b26126 | |||
| c3909ca1e0 | |||
| ff031df903 | |||
| ceba9512c7 | |||
| 77dbe92ef7 | |||
| 1623a4f958 | |||
| 375f0ba60f | |||
| 433d695e8b | |||
| d139019e01 | |||
| 805f99f57a | |||
| 4e5b02ef42 | |||
| e80e998cec | |||
| fde29220af | |||
| d3a9b57872 | |||
| 4671ec5bd3 | |||
| 9f4a8e06e1 | |||
| c8f2871aaa | |||
| 4a537a56aa | |||
| 4917160123 | |||
| b3f80dcb64 | |||
| d49b9ccad5 | |||
| a8387ce419 | |||
| 94854f2bdb | |||
| 47f531089e | |||
| abd83e8278 | |||
| b5e7c7c112 | |||
| d71f7d4c36 | |||
| 84898a7a6b | |||
| 0c1a6efc72 | |||
| 200281f140 | |||
| f1ea8074de | |||
| f896a9a278 | |||
| 79b3b34669 | |||
| ce2b964ce3 | |||
| 0ee5f49972 | |||
| 3bc10cdb6a | |||
| 86ba52850d | |||
| 27eebf6a47 | |||
| 2d2bba20b6 | |||
| eb3994005c | |||
| 0a7cdb82a3 | |||
| 158deaa971 | |||
| e51e025e9c | |||
| 8e0d64dccd | |||
| 23f47de10a | |||
| 89651597c2 | |||
| 5c0c833b70 | |||
| 33d654dc8e | |||
| f0c602d7e7 | |||
| 0e37a839fe | |||
| 3f9ead0d66 | |||
| 5eeb5af6c4 | |||
| 08c1447967 | |||
| 37b5a2ec92 | |||
| defb31e309 | |||
| 0a46e9050d | |||
| 002da30fd5 | |||
| e177c9e792 | |||
| b1bfe00bf3 | |||
| 9a75ee78a1 | |||
| 0e9cbd8e2f | |||
| 772675639e | |||
| 13300861ee | |||
| 719b9a06f4 | |||
| f5b115e618 | |||
| e1e4a63517 | |||
| 0dc1492c4d | |||
| a184fe40d0 | |||
| f462b8198b | |||
| de3b213deb | |||
| be444f75b7 | |||
| d98238c262 | |||
| 8e96745a85 | |||
| 802bce40c8 | |||
| 76728fe593 | |||
| f3d1751c87 | |||
| 81e354f91c | |||
| aab28ff4f9 | |||
| 0e3a756011 | |||
| 02198e1b88 | |||
| 00aeb98419 | |||
| 1a784b51ac | |||
| 34c0895c1f | |||
| 379fa601a3 | |||
| fcbf51d80b | |||
| 9d83dfd164 | |||
| 72686601ee | |||
| 73baaec6cd | |||
| 0be7213ee5 | |||
| 3f3e2fe97c | |||
| 549edd11ea | |||
| 36f89946d4 | |||
| 18644d6100 | |||
| 9d38ee4329 | |||
| b75a8f85e4 | |||
| aad58f5968 | |||
| a548c30484 | |||
| 9ba46ae3a5 | |||
| 49efbed6f5 | |||
| 4001a56100 | |||
| f46f35d2ad | |||
| 70dbd2f2c0 | |||
| bf1be62d54 | |||
| a5cbce3667 | |||
| d0591f292e | |||
| 27874ce0a5 | |||
| 170687abdb | |||
| 46b61d841d | |||
| 41b7021121 | |||
| 183255140b | |||
| bea8f97179 | |||
| 60fec05e12 | |||
| e79cc21c11 | |||
| 5188477a6d | |||
| 58b743e6e8 | |||
| 9fa5307a60 | |||
| b4ea09929c | |||
| 09d847bc5a | |||
| dacddef5d6 | |||
| 3c593c7013 | |||
| 36d0ef77fb | |||
| 105be0c346 | |||
| 39d21fbe08 | |||
| 50fc589001 | |||
| ffa55cb7a3 | |||
| ff0985bd31 | |||
| 622fed96e5 | |||
| c219eff149 | |||
| 514e7065e2 | |||
| 0a16453f98 | |||
| ca2fe27fb3 | |||
| 6f2c01ceb3 | |||
| 8b74a5dee0 | |||
| 460a7651bc | |||
| b7a6b839e6 | |||
| 75bff93ecd | |||
| 57a45f08f0 | |||
| ba35b56016 | |||
| 8fd10956e4 | |||
| 9a5c1302ac | |||
| f918f1ef66 | |||
| 2afcee28a6 | |||
| 6efff02c19 | |||
| d3e0831d9e | |||
| 345012810a | |||
| 73e0899e7c | |||
| 8deae0480c | |||
| 7b87498751 | |||
| 33f1aa07d3 | |||
| 3ab671827d | |||
| 4d17edef80 | |||
| 9d5b33f130 | |||
| 97c0dcad9d | |||
| ef4fe4eb7a | |||
| 9514641e1e | |||
| e6c51bcfd0 | |||
| 084ecb9ad8 | |||
| 5cc58babca | |||
| b10130c5c6 | |||
| 5bc34eb626 | |||
| 7d74245109 | |||
| 11b6080413 | |||
| 4df23e464b | |||
| 7ea5747f8e | |||
| caad76f6dd | |||
| ba2f24f1f5 | |||
| 57bb6bca94 | |||
| 4bb09b126a | |||
| ae96d8f526 | |||
| 4a918d00a3 | |||
| cd65785de4 | |||
| 51cd4cd4b7 | |||
| e7efdd61a6 | |||
| 0006762ff3 | |||
| 4e4627d11d | |||
| 228b26f7c4 | |||
| ef846d53ad | |||
| f6f7529cb5 | |||
| 606315ea64 | |||
| 46f7c95314 | |||
| 4d826c880c | |||
| 6da3acc8a1 | |||
| 8fff27fddd | |||
| 75673b5b8e | |||
| 5ded3552d3 | |||
| ded308c01c | |||
| ee336b01a6 | |||
| 66465f27ff | |||
| 764a4fa535 | |||
| 5dd5c37055 | |||
| 2e0f892fff | |||
| cad0e4105c | |||
| b10898b837 | |||
| 6255ac7379 | |||
| c90ca076ab | |||
| 73af05bf09 | |||
| 84eab0de4a | |||
| 393a868e6a | |||
| 8955e4bb81 | |||
| bae2af80c8 | |||
| 6826f44770 | |||
| 1b5095dd36 | |||
| 95992cc49b | |||
| 7b0185ba7c | |||
| 6b7fb82202 | |||
| f246c8ada3 | |||
| a97273f358 | |||
| 878bede60b | |||
| b771e108b6 | |||
| 5c916f7758 | |||
| e9db14f52c | |||
| b3f072d689 | |||
| 4fdef98bd9 | |||
| 8670c4cdf3 | |||
| 64c2a41d19 | |||
| 4e225a6592 | |||
| c491ac5b24 | |||
| 68875cc17b | |||
| f1bf3990c1 | |||
| 4334b16ded | |||
| 274f864d6a | |||
| 329d94ba9c | |||
| 03ab463723 | |||
| 3580267532 | |||
| 358e09d05b | |||
| 1f7c4ee4e7 | |||
| b3100e01e2 | |||
| 02d3445dd9 | |||
| c1c85174ed | |||
| 6cdef5d4ad | |||
| 57cbea4000 | |||
| 3522b5f17c | |||
| 5c58bd54a3 | |||
| ee6d475ad0 | |||
| d170b4e0fd | |||
| bc324df7ca | |||
| 9b75410ea7 | |||
| 44550e8d8e | |||
| 12845a6004 | |||
| 140295602c | |||
| 547f4884aa | |||
| 72e5ac76e6 | |||
| 7d3bdeee8f | |||
| e471950047 | |||
| 1306dad776 | |||
| eb9685c734 | |||
| e8fa5514cc | |||
| f1290b36d8 | |||
| befc0c6636 | |||
| f851276fc2 | |||
| bc334fa214 | |||
| 829696ccc8 | |||
| 43adf056c3 | |||
| f8a602790a | |||
| a175601424 | |||
| 7d056bd88c | |||
| eb79a6f762 | |||
| 59af552be2 | |||
| d63606a9b1 | |||
| fa0fb3cd15 | |||
| 6c8c4f0e01 | |||
| 155349a00c | |||
| 5f13536dc3 | |||
| 75a2dd7b6e | |||
| 3cec404c6b | |||
| b3a8f375bc | |||
| dc5e71e3de | |||
| 1d5abbcb6b | |||
| a1acfef721 | |||
| 7bef490125 | |||
| 8a2c54c85b | |||
| ef4a28fd23 | |||
| 10d44ce217 | |||
| 36ceabd749 | |||
| 29e1d05c71 | |||
| f92ecb31a7 | |||
| b7343ca327 | |||
| b6d8453042 | |||
| 0ee359b0a3 | |||
| 60046c4664 | |||
| b31f917acf | |||
| 639fc71f7a | |||
| 8d19368999 | |||
| 19e46fbe4c | |||
| d280e113e6 | |||
| 0e9f9bd2b0 | |||
| 7e883ab5ce | |||
| 892ba38fec | |||
| 5da26e2b53 | |||
| 2edf365781 | |||
| 82920e570f | |||
| f5da9d1dfb | |||
| cdb957403e | |||
| 21d8be4726 | |||
| 7a4bf38cbc | |||
| 18de2c3f99 | |||
| d7be33fa55 | |||
| ca791026bd | |||
| e21bb5c26d | |||
| 71aa42011f | |||
| b0bf9d042e | |||
| dbd5edabae | |||
| 4487be03f1 | |||
| 3610230c71 | |||
| 6e6a378225 | |||
| b05852e074 | |||
| cffdf7aeeb | |||
| e4d05312aa | |||
| 0997326aef | |||
| 3139416b35 | |||
| 42cf7b9543 | |||
| 2ae4f80351 | |||
| 3b156586dc | |||
| 6ba4a48e29 | |||
| 7c2908e5ca | |||
| 2a24fa56d7 | |||
| 2a6d130d20 | |||
| 1a1000bbef | |||
| e1cbb29ae4 | |||
| 37c358e3d1 | |||
| 32b2f15f3b | |||
| 752f57bbea | |||
| e2bb2d8712 | |||
| aeb2da4ede | |||
| 0c02e4cb9a | |||
| 546431bbef | |||
| 111eb6b593 | |||
| 7c2982aa0a | |||
| e1656bac20 | |||
| a0225d6ece | |||
| 13497a02a4 | |||
| c120ab76d0 | |||
| a47541cfeb | |||
| 14273268c8 | |||
| cce9b69c45 | |||
| e85afd7dd6 | |||
| f3329bbff1 | |||
| c6428cff66 | |||
| cb4c8f28ef | |||
| 0829960232 | |||
| 924783adb2 | |||
| 86d34347db | |||
| ccb8adec10 | |||
| 98a9035ae8 | |||
| 536733911b | |||
| 865ec58d70 | |||
| 33ca98ccaf | |||
| 41fc28e1e9 | |||
| abca785b1e | |||
| 92d173cb89 | |||
| dff2388b37 | |||
| 2f2fb54dea | |||
| 2daac81565 | |||
| 901b58f56a | |||
| 3000547ee9 | |||
| 15fec550c7 | |||
| c49202017f | |||
| 78d34498d9 | |||
| 8a2024e8d8 | |||
| 7de66fecf8 | |||
| 642372eaa1 | |||
| 6a95810e65 | |||
| 4c6c284b93 | |||
| 1d8c012ae5 | |||
| 522d4e4d3a | |||
| 915dcf9b9b | |||
| 4dd43ea86d | |||
| 21ec335db9 | |||
| 46c03438b3 | |||
| 9ced14b813 | |||
| d2055d60fd | |||
| 529cd463de | |||
| ab78bea9aa | |||
| 5df016e43e | |||
| cacfd66cf7 | |||
| fce8c823be | |||
| 036a166909 | |||
| 36682bc04c | |||
| 7574c356a0 | |||
| e1ce5e117c | |||
| ef0692977c | |||
| cfdce200dd | |||
| 727f7ce2fb | |||
| bcae15225f | |||
| baccd04c8d | |||
| 34b1aca556 | |||
| ba179c0991 | |||
| 01ba75a29b | |||
| c96e908a1e | |||
| 355805347b | |||
| e13f8163a2 | |||
| 099d5f60c8 | |||
| 80583e1596 | |||
| c83924a7a4 | |||
| 9081f3a004 | |||
| cfeeb432ea | |||
| c31925f383 | |||
| 72ad5b65df | |||
| b7c381b0f9 | |||
| 7b23aa796f | |||
| 2c44857575 | |||
| 2001b4c6f8 | |||
| d73872a1c6 | |||
| 23a35f8097 | |||
| df4636428c | |||
| 589e46477e | |||
| 11cf4c3a95 | |||
| 7d92d273cf | |||
| e5fa4fd1f1 | |||
| 8c9afc4592 | |||
| 3122962dc1 | |||
| 14e035bf2e | |||
| b2cc0d48aa | |||
| 613b96288a | |||
| 8b12dda604 | |||
| 61a40b4825 | |||
| eac8d3b4e8 | |||
| 5799b81414 | |||
| 1aa73bf742 | |||
| 9f6dcfd71b | |||
| d80d653d3a | |||
| 4f92205085 | |||
| b62c4d742f | |||
| 012209cfcf | |||
| 4d6d14a3d8 | |||
| 7f05933a1a | |||
| 29d8e7eed4 | |||
| 3cf680ab88 | |||
| 9abac34b83 | |||
| a94c0adeb5 | |||
| e2088bbbb8 | |||
| 1d7ddc2844 | |||
| 443b372736 | |||
| 170b3d95ea | |||
| ee88f9e75f | |||
| fbc1a38a8d | |||
| d333b186b1 | |||
| 2363ad8c6c | |||
| 55686e2704 | |||
| 5a445fefac | |||
| 2c85284cfb | |||
| 0c2a8c6bbc | |||
| b3efaa4f6a | |||
| 69b994df0d | |||
| 2141e7489e | |||
| f4f0dca3bd | |||
| 9d6ad582d8 | |||
| 0aadfdb356 | |||
| 7d6746ad47 | |||
| 5409725709 | |||
| 779834267e | |||
| a33982a432 | |||
| 881477c42f | |||
| d58eb699f1 | |||
| 1aa0c715b9 | |||
| db61729e11 | |||
| dbadef5672 | |||
| aac16414d9 | |||
| 47d2b66046 | |||
| e2ba671626 | |||
| 0cb29e471e | |||
| ad5435f69d | |||
| c9221ca64c | |||
| e5f0e64cf3 | |||
| 2c5567296d | |||
| 2da54b9843 | |||
| 8126f3c2be | |||
| 3b2f2ab679 | |||
| ee6ecb9613 | |||
| 12d51e3f27 | |||
| d71b1ca984 | |||
| 37d98df8c3 | |||
| 132a200e43 | |||
| aa5947a9bd | |||
| deb6de3d6c | |||
| b148401f0f | |||
| 33a39cb237 | |||
| 8f5d2c80f4 | |||
| 50f895c8f4 | |||
| dad0a0bd29 | |||
| 4a3f21f8f7 | |||
| 47d2ec6bb0 | |||
| 0e815500d0 | |||
| 6d2a634686 | |||
| 158adb55af | |||
| dc80fc1ffb | |||
| 09e7d58eaf | |||
| cc9f9cc8d8 | |||
| 7ce8dfbc65 | |||
| d95e998e5d | |||
| 81023e1d67 | |||
| 6434b6b213 | |||
| 20c7f2f1fb | |||
| e5e926cf10 | |||
| 544b3767d2 | |||
| 876e4b86ae | |||
| 089710247b | |||
| 0797c113a6 | |||
| 1e3cb91ed2 | |||
| dcc6f025a6 | |||
| f23e7f29fd | |||
| 3c94b5960d | |||
| 245acde336 | |||
| 53df9a47fc | |||
| f036bddf9e | |||
| 3d4e2e4263 | |||
| 111470c9f4 | |||
| 8a1d329fd9 | |||
| 2307138fa8 | |||
| 84cb428b6c | |||
| c46f84a00e | |||
| d93f11b5f2 | |||
| 6f41d16408 | |||
| 0feae25be5 | |||
| d0069ffe83 | |||
| cec83aeb78 | |||
| c468054bbe | |||
| 372931a9c5 | |||
| 9a640de8d3 | |||
| f4968e1509 | |||
| 1858bab210 | |||
| c811fd31b1 | |||
| 098cb740dd | |||
| 9ac63ce469 | |||
| db0067a6d9 | |||
| 5de8df188a | |||
| fa66bd3c42 | |||
| e89d473669 | |||
| 90f3138395 | |||
| 4e789479e4 | |||
| 3fbb93d157 | |||
| 90a48345c2 | |||
| 7c00cad4c9 | |||
| 963e070f92 | |||
| 908a5dc309 | |||
| 3adcdb4019 | |||
| fbbf09a937 | |||
| 254bc93f93 | |||
| ed7bfd2d68 | |||
| 76e8c2d2b1 | |||
| b0aca47e74 | |||
| 5d703327db | |||
| 5ebe09444b | |||
| 136ceddff5 | |||
| b4bee3a65d | |||
| f870dab568 | |||
| 7027574d35 | |||
| c55c19a32e | |||
| f05e4c1852 | |||
| 1eb2d5c3ac | |||
| 3b98f8c0ab | |||
| 229886d84c | |||
| c1dc637eb2 | |||
| a5db29f2ad | |||
| 20e6b8bb63 | |||
| c7f6e34647 | |||
| dc59bb5d2e | |||
| 64f66474b1 | |||
| d4abedaa05 | |||
| 6e18978586 | |||
| 5b2e8b7fbd | |||
| 2608e94980 | |||
| 1d469687cb | |||
| a9248435a2 | |||
| b4cdb7f16c | |||
| 675a4465d7 | |||
| 839013d89a | |||
| 8e933a1bb4 | |||
| 10308959a1 | |||
| 68ac277471 | |||
| b93ff99b2e | |||
| 285367f616 | |||
| e3dd42c856 | |||
| a54b48f68a | |||
| de2d37cdf5 | |||
| 75b72a500d | |||
| 7da0580eda | |||
| 6883151809 | |||
| 00e9ab4263 | |||
| 2acfada4f8 | |||
| d07f9fe341 | |||
| 9c9487ced6 | |||
| 9d131a8992 | |||
| cd57a32f31 | |||
| 4c2ece3eb7 | |||
| 59318d75fc | |||
| d9eef2e5d5 | |||
| 2f189d94ac | |||
| 223db88462 | |||
| f2d9511f01 | |||
| ef1f1c0af0 | |||
| da28244f81 | |||
| 77ba13ce93 | |||
| eb8bafe5d8 | |||
| 411ef10c0c | |||
| 01d4174092 | |||
| d072e72590 | |||
| 38e4e9bc94 | |||
| 126ddaf9c7 | |||
| 4bf5be5734 | |||
| c8a4f8be6a | |||
| 049c5cc83a | |||
| ef1f2e882d | |||
| e94d90050a | |||
| 8977e82b73 | |||
| dfff178bfe | |||
| 4f00dadc22 | |||
| 7b439f005e | |||
| 5c165cd40d | |||
| 43a84cca3d | |||
| a4d87a428c | |||
| 414c0b8a38 | |||
| a11e02a84a | |||
| 1a08414822 | |||
| 0b6b66b7e6 | |||
| 278ab648dd | |||
| fe101f1221 | |||
| b6b6cb185d | |||
| ee373bbe4b | |||
| 49857f6b91 | |||
| 8655f7811a | |||
| ce47cd9316 | |||
| c4c71ac9ef | |||
| eaebc445f6 | |||
| 3ec15960cf | |||
| 5275c40c6a | |||
| 68ef5a5a32 | |||
| 63bfa6bf14 | |||
| bce25b8702 | |||
| c88fbc0321 | |||
| 0d1e7fd686 | |||
| bd2ec52832 | |||
| c3b9902c5f | |||
| 69a5cfecd1 | |||
| 304ae3075b | |||
| 0550f36447 | |||
| b82e84d447 | |||
| 7a59aeb80c | |||
| 0228facd71 | |||
| af90088505 | |||
| 2ddf620fb8 | |||
| 0c3d4f4f4e | |||
| e339b26657 | |||
| cee42ac467 | |||
| a2b061ce0d | |||
| 7d2c2bb141 | |||
| 8cd31ead99 | |||
| 3a8fb37cd6 | |||
| 2abf809d0f | |||
| cc9c7870ba | |||
| 2fe04d7f6b | |||
| 977316c57f | |||
| d2c5f711ef | |||
| b8baa05922 | |||
| 98b332fe54 | |||
| 6e61154cc5 | |||
| 0a5450a345 | |||
| 83baf377e0 | |||
| ffc884384c | |||
| 0c302456a2 | |||
| 41e7ad35bd | |||
| 82b474ead2 | |||
| d544e16885 | |||
| 4396623420 | |||
| d2795bfdb6 | |||
| 42fb3642f9 | |||
| 834404c477 | |||
| 85d951e367 | |||
| 5b5a531731 | |||
| 7faadc3529 | |||
| 2ff456dd45 | |||
| 3ac7099db5 | |||
| 3b936b68e6 | |||
| 3034f748df | |||
| 4daf2d65ee | |||
| cccc819fd8 | |||
| d4ec346254 | |||
| b0c6dc612f | |||
| 78503cf1b7 | |||
| eb51a89971 | |||
| e2350650d0 | |||
| b93a6703cb | |||
| 83bc8cb026 | |||
| 3a89dc8309 | |||
| 6d1e592f32 | |||
| 42880e01b9 | |||
| e2f38ed577 | |||
| c62a1cf8b5 | |||
| ef95b25c2d | |||
| 4b8efd1a36 | |||
| 7d03d5a26b | |||
| 0b49bf4dc9 | |||
| b4d34589d8 | |||
| 60ead9f7a0 | |||
| d46de7b324 | |||
| 4a3c22a8d6 | |||
| d79c37fc49 | |||
| 15107459be | |||
| 9fc9688fa6 | |||
| ee3dd1259c | |||
| ff16246e42 | |||
| a71da4f4c2 | |||
| 2267759378 | |||
| 2b0b06e14f | |||
| 518eda919d | |||
| c8a58ce702 | |||
| 61797170b6 | |||
| 480bc738dd | |||
| 2075ed101b | |||
| e771588647 | |||
| 0529a5017e | |||
| f16bd6cc61 | |||
| 2a8b9b1c35 | |||
| f507ba5474 | |||
| 422de4eea1 | |||
| c6e745c796 | |||
| c7437f8fb7 | |||
| f7b5ca5690 | |||
| 05a0c28a1c | |||
| 09416bc34c | |||
| d188a79ed7 | |||
| a9372553f5 | |||
| c81e4f4b40 | |||
| 55bcad82d2 | |||
| 21136f4c3c | |||
| aeadfb21dd | |||
| a02847e3ed | |||
| aa39dc4b81 | |||
| f13d66d095 | |||
| b99085b49f | |||
| 68f8c8cea8 | |||
| 0f767c6896 | |||
| 862d008f4c | |||
| 1a105b3417 | |||
| fb2cc99382 | |||
| 6bd0efbcf0 | |||
| 9fe8ac7b32 | |||
| c131d81686 | |||
| 5ab0e0d6c5 | |||
| 5cbd815092 | |||
| c051040b12 | |||
| 17d903ff32 | |||
| 2c1f599abf | |||
| 754b06881d | |||
| eea72a8470 | |||
| fdbf2b2f58 | |||
| cc769fa871 | |||
| aa605b7402 | |||
| bef81d2704 | |||
| 42e357892f | |||
| 44595a861a | |||
| 14e406c45b | |||
| 003f6c7e74 | |||
| 57c38307f5 | |||
| f6fd338bd7 | |||
| fc10d0c303 | |||
| 7939005428 | |||
| 072ce5b03e | |||
| 9794bf3565 | |||
| 37d80b63d9 | |||
| 077b14a998 | |||
| c6458c901d | |||
| 52b6de12ae | |||
| 03671ad209 | |||
| b99980e5c0 | |||
| 5e0a6b9472 | |||
| 3540753ff8 | |||
| 2b3cee6b7c | |||
| 5881e4465f | |||
| 48c7e4ab40 | |||
| 9bcf06e1b2 | |||
| 0bfa6f4b04 | |||
| 0bf8d54598 | |||
| 0c43cfcc5f | |||
| 2ea66cd295 | |||
| a7d0d52dfb | |||
| 8a35e3f21d | |||
| 9c024df9e5 | |||
| bde7760634 | |||
| ed986ddcb8 | |||
| b6aae73ef6 | |||
| 7883a39375 | |||
| f0a71b3ad0 | |||
| 5e77878427 | |||
| 7b9891150d | |||
| e5d5a88cbe | |||
| 3c3e3dafb5 | |||
| cb3ec5f300 | |||
| 2a08645265 | |||
| 6b060a1ff6 | |||
| 1d6eb0c48f | |||
| 42c407698d | |||
| 3fd5aaf56c | |||
| b4a4d7e377 | |||
| f7d53c9db3 | |||
| 3dc98a2bc2 | |||
| f393f76a87 | |||
| a00dfac937 | |||
| 999e09a653 | |||
| 29580e125d | |||
| c3e083607d | |||
| 463c323f0a | |||
| d13c0dd198 | |||
| aa5ccd0196 | |||
| 039e45ef97 | |||
| 3a626d9101 | |||
| 069b0d425a | |||
| 83029989b9 | |||
| edac8953c1 | |||
| 012a01da71 | |||
| 17470fd74b | |||
| 43235f2fc8 | |||
| 3c58d6decd | |||
| 8560438bac | |||
| c6f42da61b | |||
| 121dd16652 | |||
| d36fc7dec1 | |||
| 74237e7568 | |||
| 53cc36c879 | |||
| fc50f53944 | |||
| 570a3bccc5 | |||
| 7039a28326 | |||
| ca52a3e740 | |||
| 1801c831ba | |||
| e72669354a | |||
| 0ce072a2ca | |||
| 62b3f47fa7 | |||
| cd018fb970 | |||
| 8e2683c165 | |||
| b6abe0e7ac | |||
| f6ee8a3a1d | |||
| f07519565b | |||
| ffedfcc781 | |||
| fb7c827e15 | |||
| f921e22b5c | |||
| 719260e3da | |||
| 34c83e87c4 | |||
| 70b0c55a39 | |||
| c926625090 | |||
| ea7e78c498 | |||
| 36d417d3db | |||
| ecc4504f00 | |||
| ddebb8fec1 | |||
| 7852165907 | |||
| ea5dd297cb | |||
| 8d7468457f | |||
| eb29da7639 | |||
| ad7d173b7e | |||
| 287c029bda | |||
| 4be63b8c65 | |||
| 6d844c2d3a | |||
| 1c93c2bbb4 | |||
| 3792a1ab05 | |||
| 9c5b789aa2 | |||
| 1ac3964589 | |||
| 5e3f310154 | |||
| d10a1d1660 | |||
| a0a05436a0 | |||
| c8d24f1694 | |||
| 7c32626bc0 | |||
| 46e7bd917a | |||
| dc688e49ce | |||
| e1a6cdb484 | |||
| 2b92e2e73b | |||
| 8467a19781 | |||
| bb87bfa1de | |||
| c07d5052b2 | |||
| f7eba23081 | |||
| 6729565a59 | |||
| 5da0a861b6 | |||
| 9ae259f1ed | |||
| a092dfdc3b | |||
| f353d1686c | |||
| 0f50b29c4e | |||
| 3d9d0d46fb | |||
| b4e6f2775e | |||
| 631c8b705a | |||
| d2b52e486a | |||
| fd3335508b | |||
| 26dd7e1eea | |||
| 4000899d6d | |||
| 17e2bdc6f7 | |||
| 737f95e458 | |||
| 51c8da51d3 | |||
| ffb93d0a6f | |||
| 086d944f10 | |||
| a461a57f0d | |||
| 7307b58696 | |||
| 0f9592a508 | |||
| fb13ab40ca | |||
| 6b26cfc964 | |||
| 4646fdee89 | |||
| 27561931cc | |||
| 13c696b392 | |||
| 849b3116c9 | |||
| 0e87da2eff | |||
| 4c9cfbfdf9 | |||
| d49ee4f3fc | |||
| 5ea6f44a96 | |||
| 71620c2b29 | |||
| fa3849b85e | |||
| 49211bf6e0 | |||
| 5df7dc7590 | |||
| 9ed4375165 | |||
| de68334249 | |||
| c21ebddfb6 | |||
| 5f993cca57 | |||
| 3caf3a9380 | |||
| 5dbc2c2895 | |||
| 1a1016bdf8 | |||
| b5047fc5ab | |||
| a199ea2c20 | |||
| dc8a5933bf | |||
| 9d832391e4 | |||
| 78c3e14086 | |||
| b9965bdbc5 | |||
| 961a42d1cb | |||
| 026547bdfc | |||
| fb6c86801e | |||
| 007c761537 | |||
| 4db94e50e5 | |||
| 7a9ea7f281 | |||
| 62d0f109b4 | |||
| f088928483 | |||
| 30b02a03c4 | |||
| cfc7960c70 | |||
| 4c01cb4b8d | |||
| 03e8d0f381 | |||
| a8f12ae847 | |||
| 81b2f352de | |||
| 2ad8e381fd | |||
| d5da0e4002 | |||
| 46153cb358 | |||
| ea3f8096fd | |||
| 9872d22c06 | |||
| aeb0372d59 | |||
| 2a965e847f | |||
| 626c65fc3e | |||
| fb1ebd0e11 | |||
| 30f7f002d5 | |||
| 77d341ebab | |||
| 0a896862fe | |||
| 68d262b6b6 | |||
| ebba3472e2 | |||
| 7ccb126571 | |||
| d3ea370b74 | |||
| 58fcf0b808 | |||
| decd99a15c | |||
| a4764d3158 | |||
| 3225746940 | |||
| df8489c1af | |||
| 2a2db4bc52 | |||
| 8ff6c3e65c | |||
| df0a2f29d1 | |||
| e94d1cb98c | |||
| fa098666f1 | |||
| 9f1e97d9a2 | |||
| 31e20b12c0 | |||
| 23fcd4a651 | |||
| 7da87c27ee | |||
| 5401917703 | |||
| 2c12892111 | |||
| e5eaba9150 | |||
| 27d12efb31 | |||
| 6a4f6c509b | |||
| 1004eefbf6 | |||
| ff40bf5a3a | |||
| bcdfb42fa1 | |||
| 8773c414c5 | |||
| 1852d9103f | |||
| fb1b440e72 | |||
| 0ad3867a91 | |||
| 011a915d38 | |||
| 5726a07249 | |||
| b3a75b3738 | |||
| 888cecdc16 | |||
| 28b16943f7 | |||
| a0c46aaf7a | |||
| 89c43e98b9 | |||
| 7a238f833b | |||
| 909de9409b | |||
| 0aa10a631a | |||
| 6c8b8a3d51 | |||
| b73cbdd8a2 | |||
| e0f5d51b71 | |||
| e76e17439f | |||
| d1140556c7 | |||
| e34a788353 | |||
| ca3f39c2a2 | |||
| 5cf1b56782 | |||
| 305c29dad2 | |||
| 1fc139cc8c | |||
| 7305236724 | |||
| 353f5a1f26 | |||
| ad3bcf5a98 | |||
| cfa1c39889 | |||
| 72d4c0a0c1 | |||
| 5ce87b0e35 | |||
| 4c43b35e0e | |||
| 650892f340 | |||
| 33cdc55e21 | |||
| 90aa1e1dce | |||
| 907c1519bd | |||
| 0228761452 | |||
| a01bfe35e8 | |||
| a193d7534f | |||
| c1e6a3d7d8 | |||
| 3f0b4131be | |||
| 6a2fedb773 | |||
| 177cc512fa | |||
| 8579b6f6eb | |||
| bce7481290 | |||
| 7a935e10f0 | |||
| 3d5b23d0f5 | |||
| 1e0ffd10c6 | |||
| 799e1c9bf3 | |||
| d92a68e3f2 | |||
| 039d004fa5 | |||
| 5d2e3f03fa | |||
| 9cb0f1aeb8 | |||
| 2f19a95437 | |||
| 04b748979e | |||
| 4247f85f70 | |||
| 0e3b40564b | |||
| ddd5dbaeed | |||
| 3c3b24fc03 | |||
| f6d5295980 | |||
| 39160f9ff8 | |||
| f87540472a | |||
| e8e80c9a7a | |||
| e39730c238 | |||
| 58acca3078 | |||
| bf5e7f589d | |||
| da5a7a7856 | |||
| 1c78c4a80e | |||
| 05064861a6 | |||
| 3296120a2a | |||
| 69b1c86055 | |||
| b1945d1593 | |||
| 56214bf03f | |||
| c804947923 | |||
| 480bb84d9c | |||
| e45b44c0aa | |||
| e0ec34c638 | |||
| bf4b5a94a4 | |||
| 7ddb2346f1 | |||
| 0603d58f6b | |||
| 07e8360c90 | |||
| 41be7598ea | |||
| c4fd4fa9d3 | |||
| 00578c55c2 | |||
| f8a366308a | |||
| 52e269dbe9 | |||
| 86af411991 | |||
| 41aeafe54c | |||
| 39a62edc7d | |||
| 15b0e265cc | |||
| e1e851d6f3 | |||
| 7dea8b143f | |||
| 0e6b93023c | |||
| 66126067c0 | |||
| c08f779171 | |||
| 8ca4e380fa | |||
| 81900d80b5 | |||
| ac9ab133a9 | |||
| f0385e4096 | |||
| 163129e245 | |||
| e60a8a109b | |||
| 9416e2fbaa | |||
| 3afc9d2c5d | |||
| 66555b21a6 | |||
| f93842dc94 | |||
| 3bb52b5cfe | |||
| 95c5e7022e | |||
| b0adc47907 | |||
| 508fc17d05 | |||
| f90a1c7883 | |||
| c1f8be668c | |||
| 1442660e49 | |||
| 95749bea5d | |||
| f46e285bc9 | |||
| 2fa8831c63 | |||
| 86336eea01 | |||
| 71bd433442 | |||
| 99a2f1af3a | |||
| 72488c9d18 | |||
| cb90563519 | |||
| bf9fcc37cb | |||
| 4dcd013db4 | |||
| 6c69e3fad1 | |||
| 709b41aceb | |||
| 845b932451 | |||
| 3215c17609 | |||
| 8a6e61469b | |||
| ec77519923 | |||
| b52e00a842 | |||
| edb9b13bd1 | |||
| 1eb515e751 | |||
| 4083597f23 | |||
| 48f799e1c5 | |||
| f08f79f754 | |||
| 672cf59972 | |||
| dc88c322fb | |||
| df16edac7f | |||
| 0c8aedd972 | |||
| 3da2565f57 | |||
| ca84628eb9 | |||
| 88adbb16d2 | |||
| 0912b8b161 | |||
| af53987fbd | |||
| 0818f943b1 | |||
| 2ef2b61cc5 | |||
| 16c80a0976 | |||
| 4d2639207d | |||
| fe57ae2471 | |||
| c09231b039 | |||
| f7ccb00bbe | |||
| b925fe8ff5 | |||
| 275320af0b | |||
| 9bee597cb9 | |||
| 50c1e8f1a7 | |||
| 2c963e14d5 | |||
| a2a8f6e471 | |||
| e533555b52 | |||
| 71a39ba05b | |||
| 1c7c7af105 | |||
| ad66fa8022 | |||
| b222129478 | |||
| c6eeb9a3ea | |||
| b9c77fbdfa | |||
| c68d092814 | |||
| 4a8d19cbf2 | |||
| fab02d4d16 | |||
| fc073325fb | |||
| f8d270540e | |||
| 69ec02341f | |||
| e10948a7cf | |||
| ed2e56c776 | |||
| 4db469199c | |||
| a69be58b58 | |||
| 4cc07a7b02 | |||
| 8214b17a4e | |||
| 7a665d6f9c | |||
| 2d7cf5151f | |||
| 65d8dc803d | |||
| 5749af4bb2 | |||
| d0872f42da | |||
| 8b7cf2a74c | |||
| 7dc1f2fe92 | |||
| ffe05bc7f9 | |||
| 135e8269fa | |||
| 1832e58498 | |||
| b4408f048c | |||
| 397c464fb2 | |||
| 6b9dfc5d43 | |||
| b882e5e62b | |||
| 2d5b384ae4 | |||
| 86dee3bb29 | |||
| 4287ff8a3c | |||
| da34aeed42 | |||
| 402ac166ff | |||
| 27f472dd57 | |||
| 64d9eca618 | |||
| 6f88519df8 | |||
| 2325886adb | |||
| a5947be122 | |||
| 1e9e1dce75 | |||
| 01f6df4a19 | |||
| 5ed7733320 | |||
| b880b6592b | |||
| a52271dfb9 | |||
| bf0ac5afe2 | |||
| a30451597c | |||
| d8d9d99598 | |||
| 381cf0a6ee | |||
| 45dec188a6 | |||
| fda30ff76d | |||
| 429c9a5d33 | |||
| 51df2daaa8 | |||
| 73c210a1bf | |||
| 85206d5239 | |||
| e3f7e7b246 | |||
| 7376533027 | |||
| baf7230b1b | |||
| e616d21bea | |||
| 7aaa94dedc | |||
| 50da6d9d9b | |||
| 7a3597a722 | |||
| ac50f23090 | |||
| 2307897b31 | |||
| 2d316fa042 | |||
| 2aa9c86499 | |||
| bfee773229 | |||
| 0441760cae | |||
| 35194fc09c | |||
| 6c0628ddcb | |||
| 9e1ab776cf | |||
| 034b01a04c | |||
| a2dcbf69c7 | |||
| f761559e6e | |||
| 017a4f8e08 | |||
| 2018e3aa9f | |||
| 7cf51356a6 | |||
| 0001c20eea | |||
| 0940611b89 | |||
| 05911027bd | |||
| c57e55c286 | |||
| 8f4818709a | |||
| b04f7cfc55 | |||
| ba7722ce45 | |||
| 5e5ce0722f | |||
| 325035822f | |||
| 3557536968 | |||
| 07520b9014 | |||
| d17dcc17b0 | |||
| 8b4e51b876 | |||
| 65ec50577d | |||
| 516c19c312 | |||
| dcee8b8e8b | |||
| a1306c88c0 | |||
| e4fd2d1d48 | |||
| 711451a4b3 | |||
| 2d4e46a43f | |||
| 2b2255a590 | |||
| 92046fe345 | |||
| 7a53175a5f | |||
| 5a35d8b40e | |||
| 596262bd64 | |||
| 37ef406a78 | |||
| 2a4e6830e1 | |||
| 8ffa931a2f | |||
| 8bfb69baee | |||
| 45c682c595 | |||
| 1c9724c232 | |||
| c29dac9847 | |||
| 42ea10f72c | |||
| 7bc42e07c4 | |||
| dc07b60688 | |||
| 7e0fa4854f | |||
| 22eae6d515 | |||
| d8ad9e043e | |||
| 5e3efc8cae | |||
| 02bf258d9b | |||
| b07aaa5bb5 | |||
| f70f353329 | |||
| 1e16c9a7c3 | |||
| ec42ffbf60 | |||
| 0de7a437bb | |||
| 09b751243a | |||
| 3a0b20a5bd | |||
| 478416aedd | |||
| 677da12d1e | |||
| b23c7c33aa | |||
| a0816e2edc | |||
| 460b5f0fa5 | |||
| a18610d07d | |||
| b434036684 | |||
| 8637992b56 | |||
| 4ca4b40053 | |||
| 17634f0fb5 | |||
| c86b84832d | |||
| eaeab7adaf | |||
| a2d64499e1 | |||
| 0958f29e6e | |||
| a12fe99ad7 | |||
| 5b1ebf1d61 | |||
| 9fe6c2b137 | |||
| 6ad29f5002 | |||
| 190e4a7702 | |||
| efe5564b6f | |||
| 082946936f | |||
| 1fd1dd92d3 | |||
| 1633eacd67 | |||
| b8f00dd20b | |||
| c1ddc70a53 | |||
| eb34d30b00 | |||
| fba5fc05d1 | |||
| 8a38377443 | |||
| cca697a272 | |||
| 11c37b087d | |||
| 085bfc5533 | |||
| 34b7c8f098 | |||
| 20d25ffbba | |||
| 10dbc97bea | |||
| 9089703c1d | |||
| 7ca02a945d | |||
| 75bd324897 | |||
| 1a9fdabc4a | |||
| f1fbe8e55c | |||
| e60dfe0242 | |||
| ee9c60b127 | |||
| ac7a7f3129 | |||
| c4d15aa64a | |||
| 3b07aece86 | |||
| e3be3d2453 | |||
| 966d48241b | |||
| bedde0d061 | |||
| b50330df93 | |||
| 023ae3e269 | |||
| 97fb779b19 | |||
| 8010e64ecc | |||
| dd259c4d8f | |||
| 9d30130f85 | |||
| 42cd6d82ca | |||
| e227095319 | |||
| dfcf8c6185 | |||
| d2d96813ad | |||
| 7fee2b9718 | |||
| 1c97ec10e1 | |||
| 28eed33e40 | |||
| bb515444c6 | |||
| de267a8251 | |||
| d506f5f3a3 | |||
| 40ef026f82 | |||
| a447be3c50 | |||
| a6edb6aef6 | |||
| 4b944ee2fe | |||
| da4d6b26d8 | |||
| 733e6282a8 | |||
| c79ce49e4d | |||
| 94ee2c27eb | |||
| 1267661819 | |||
| a59763da64 | |||
| e5ab20e167 | |||
| b3a14432ce | |||
| 5d3afcc82c | |||
| 6a0f026cc1 | |||
| 9b723888ab | |||
| f25f3053cd | |||
| 932da70534 | |||
| f0c343e6fa | |||
| 9545ba3801 | |||
| 51ea7a11e0 | |||
| 7a15b150eb | |||
| 43426ea084 | |||
| e1dadaca6a | |||
| d8f948919d | |||
| c55c404973 | |||
| ade6a7685b | |||
| ca0e93d61b | |||
| d276514305 | |||
| 6579df929b | |||
| 3cec0aa9ce | |||
| 323d58aeb0 | |||
| 320279f9a6 | |||
| 4f873f7730 | |||
| c52d8b3804 | |||
| 9f52c9e055 | |||
| 610336e868 | |||
| b89df817ff | |||
| 1ccc2e477f | |||
| 13a5d15139 | |||
| 6e06bfa86d | |||
| 1c3148d96b | |||
| 5d1c3b16e6 | |||
| a2907e5808 | |||
| 28373086ad | |||
| 16159c9723 | |||
| 1d341b6a00 | |||
| 691d8ff6f1 | |||
| 532138b71e | |||
| 06493819a6 | |||
| f4e6259a44 | |||
| c03c230e70 | |||
| 4535151d0d | |||
| 68e7631a3b | |||
| 6a235e66a0 | |||
| 61d0daf9c7 | |||
| 03e58f48a9 | |||
| 1028ed0989 | |||
| 7bf1ba13c8 | |||
| 869edff873 | |||
| b2a50e6141 | |||
| 6bb0f29433 | |||
| 84537e2f99 | |||
| c53aa12377 | |||
| a6440187ed | |||
| 83126454ea | |||
| ceeb59301e | |||
| 46b918f9be | |||
| 8fc3977236 | |||
| 79dcc63152 | |||
| 208cbbd8e0 | |||
| 243a7fd8d1 | |||
| 76f8af1b64 | |||
| c406bfd63f | |||
| da3a5f67fa | |||
| 184bce293f | |||
| 34acf03564 | |||
| 3737e3510d | |||
| d0e20ea6ca | |||
| 062f5a5152 | |||
| 8207d55848 | |||
| 44e0a8452f | |||
| ad7cc4fce0 | |||
| 1a733d10c0 | |||
| 7c30ab095e | |||
| 2e60de8916 | |||
| 20992e4334 | |||
| 0e059f7000 | |||
| 20a9c0d718 | |||
| 9b30d11791 | |||
| 8c721bc0b0 | |||
| 172006f2f6 | |||
| a5d9fca932 | |||
| 174b23c8ef | |||
| 42ece3f27a | |||
| a76e583c51 | |||
| 939b528d11 | |||
| e1feb9bc5e | |||
| 226420b1d2 | |||
| 8eaf0e1880 | |||
| 26e5e4c0c8 | |||
| db20ad5539 | |||
| 4ba759c374 | |||
| eb9f484863 | |||
| a2a3dbbc87 | |||
| dbfd354338 | |||
| 217bfb4565 | |||
| 3cffdf54d8 | |||
| bfa4a062c4 | |||
| 424cceef03 | |||
| 8de78ef5f2 | |||
| 927273511c | |||
| 712ec7b74c | |||
| 146afbece6 | |||
| af1c04ebdc | |||
| 626f5c4471 | |||
| 43510c20de | |||
| c0392b206b | |||
| 408cfceb92 | |||
| e96f43f3b0 | |||
| 0205b7ac55 | |||
| 7736b7b73d | |||
| 416be81124 | |||
| 317ba915e7 | |||
| 4fc1605c8d | |||
| b1f69203eb | |||
| 790aa540f8 | |||
| a902798c7c | |||
| 07a145d3c3 | |||
| b36f9fda45 | |||
| b9dd1e007c | |||
| c207f51bfc | |||
| b06e04e306 | |||
| 6cf8cec2c3 | |||
| 1f27a6e735 | |||
| ce5e691851 | |||
| b9b49508b9 | |||
| 158cb1d08e | |||
| 368be1d112 | |||
| 81bc6b90fe | |||
| f6af478765 | |||
| eda6afa79b | |||
| 2afd8b9b8d | |||
| f6cc6d682f | |||
| ed35d62b8b | |||
| d7a131b733 | |||
| 2a8a11b035 | |||
| 0e7f323036 | |||
| d2b6963763 | |||
| 0259b620e4 | |||
| 16bcc12ccb | |||
| 98a708ceae | |||
| 5586cc99b0 | |||
| fdf112b0b2 | |||
| 628f695abb | |||
| 5a8ca230c0 | |||
| a3aa6d49cf | |||
| bf78577d26 | |||
| 38a3936938 | |||
| da8c62d961 | |||
| fb93d417ee | |||
| b9a6f11245 | |||
| c0bcc40f6a | |||
| c6e6478043 | |||
| 92341751fc | |||
| 71b053bee6 | |||
| 9840bf09fa | |||
| 4f4dc45a48 | |||
| e3b00d45ec | |||
| e211b27a80 | |||
| 491b6aa96d | |||
| 06d09bc422 | |||
| c4171f1a26 | |||
| fd22dca0fa | |||
| 9d2b354a33 | |||
| b4e9ad0412 | |||
| aa3991592c | |||
| ec17781f4a | |||
| 72bf8da59d | |||
| 7a37e3044c | |||
| 4fa8e7f17a | |||
| eb50b29e95 | |||
| 3d141fc47f | |||
| 9715171aba | |||
| 8a5666227d | |||
| 614431af2f | |||
| 48d9b44344 | |||
| aff3e474af | |||
| ddf9ed86a7 | |||
| 9cd45686d3 | |||
| 76d165e21b | |||
| 6002620d4d | |||
| 3f1cbc9095 | |||
| fa2a25b7c6 | |||
| 9b3e64a595 | |||
| 63cb98a327 | |||
| f4fa8c861e | |||
| 8c577c39ab | |||
| c3487f95ec | |||
| 427e20a4dc | |||
| 5b0617888c | |||
| 25d6f1debf | |||
| ce2807b1f6 | |||
| d0f3ae6581 | |||
| 7de4d84c39 | |||
| 48abed87db | |||
| 65b52e76ec | |||
| c3a90b2022 | |||
| 67e30df22b | |||
| 3d6e9f69de | |||
| 75209dc6eb | |||
| 097d33a056 | |||
| f044b25769 | |||
| 76f6184640 | |||
| 6e3c09d081 | |||
| 7e0fd93708 | |||
| eb1df32714 | |||
| e32d9433d5 | |||
| 41e6b7f243 | |||
| 6f5de4d0b4 | |||
| c2c67fbe72 | |||
| 6ef6e39128 | |||
| 914f0bd862 | |||
| 4d0ca617a0 | |||
| 72e9e0cf9a | |||
| d143ff87fb | |||
| db8c15b49c | |||
| 2368763d74 | |||
| 476828985e | |||
| 8df87df374 | |||
| cb2e4da32c | |||
| 765322ef57 | |||
| 720295650b | |||
| d37fad80b6 | |||
| 50637f03d6 | |||
| 37a70891f3 | |||
| 16b0ea2c13 | |||
| f1bcd5fd79 | |||
| bdcf3099b1 | |||
| 445b87f1fa | |||
| 61600c96c4 | |||
| b25878414f | |||
| 09031d5c90 | |||
| e56cf9f36e | |||
| 8998d46f20 | |||
| 901ec1cda3 | |||
| c93dd19678 | |||
| 56170d8392 | |||
| f5fdb6cb30 | |||
| 1892dd1c37 | |||
| d7811959fa | |||
| 18bc083431 | |||
| ab100c85a1 | |||
| e971223e4f | |||
| 56651a6307 | |||
| cd4ccc993b | |||
| 7c5b7e5b45 | |||
| cc660e820d | |||
| b8a841f88e | |||
| a1a043c296 | |||
| e3df44e16f | |||
| 764f93f40f | |||
| 9bcdc40eb5 | |||
| 10f62b75b6 | |||
| 0a6a3268da | |||
| 0e88d95ed5 | |||
| 2dc2d00c0c | |||
| 6cde584dd9 | |||
| 13cfb3adc6 | |||
| bb463dae7e | |||
| 98d147a304 | |||
| 4d8d8f656a | |||
| 89d53d0ea3 | |||
| 4945a3bbfa | |||
| 8f51707505 | |||
| 3de02c5d63 | |||
| ca55f06853 | |||
| 33276f1cf3 | |||
| e7b13d2063 | |||
| 1fc16772af | |||
| 318aede719 | |||
| cc55588967 | |||
| 53296b2367 | |||
| 9eef2599b9 | |||
| 6a1ac49e54 | |||
| 1c06a39df3 | |||
| 4778149c50 | |||
| c928a1a806 | |||
| 4c1ac827ad | |||
| 687efb7444 | |||
| 09b4da7974 | |||
| 1dc2f2c23c | |||
| ed1eb02256 | |||
| dda2ed955d | |||
| b3503026b4 | |||
| 328bdee602 | |||
| 988579b708 | |||
| a7d0e7f49b | |||
| b03c8b4a11 | |||
| c35d1acbbf | |||
| 016fbaf468 | |||
| 0a6cde69d6 | |||
| 05cd7084ef | |||
| 33ab4c5bfd | |||
| 554369be31 | |||
| acf3844139 | |||
| c6bdf2e37a | |||
| 06ab30339d | |||
| 3c354df5d8 | |||
| a2a8728203 | |||
| 0366e2e33c | |||
| 5919bdac50 | |||
| c4415c6fd2 | |||
| 1968bdf88d | |||
| 13ffb0ace1 | |||
| 471059a03e | |||
| 02be2969a2 | |||
| c8bb538c36 | |||
| 4c12483a57 | |||
| e445fd986d | |||
| d7bb818f51 | |||
| eef0e04682 | |||
| 9c857bf86b | |||
| d440dacf30 | |||
| b6c40302b6 | |||
| 7b9c88f8a6 | |||
| a776ecfc2b | |||
| ffbc253477 | |||
| b4ed874043 | |||
| f1845b1ecd | |||
| f2946d85aa |
@@ -37,10 +37,13 @@ assignees: ""
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I have checked that I am on the latest version of Terra.
|
- [ ] I have checked that I am on the latest version of Terra.
|
||||||
- [ ] I have searched the github issue tracker for similar issues, including closed ones.
|
- [ ] I have searched the github issue tracker for similar issues, including
|
||||||
- [ ] I have made sure that this is not a bug with another mod or plugin, and it is Terra that is causing the issue.
|
closed ones.
|
||||||
- [ ] I have checked that this is an issue with Terra and not an issue with the pack I am using.
|
- [ ] I have made sure that this is not a bug with another mod or plugin, and it
|
||||||
<!-- If this is an issue with the default Terra pack, please open an issue on the pack repo: https://github.com/PolyhedralDev/TerraDefaultConfig/issues/new -->
|
is Terra that is causing the issue.
|
||||||
|
- [ ] I have checked that this is an issue with Terra and not an issue with the
|
||||||
|
pack I am using.
|
||||||
|
<!-- If this is an issue with the default Terra pack, please open an issue on the pack repo: https://github.com/PolyhedralDev/TerraOverworldConfig/issues/new -->
|
||||||
- [ ] I have attached a copy of the `latest.log` file
|
- [ ] I have attached a copy of the `latest.log` file
|
||||||
- [ ] I have filled out and provided all the appropriate information.
|
- [ ] I have filled out and provided all the appropriate information.
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,11 @@ assignees: ""
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I have checked that I am on the latest version of Terra.
|
- [ ] I have checked that I am on the latest version of Terra.
|
||||||
- [ ] I have searched github for similar features requests, including closed ones, and found none.
|
- [ ] I have searched github for similar features requests, including closed
|
||||||
|
ones, and found none.
|
||||||
- [ ] I believe this is within the scope of Terra.
|
- [ ] I believe this is within the scope of Terra.
|
||||||
- [ ] This feature request is for *all* of Terra, and isn't something that should be implemented by a pack or addon.
|
- [ ] This feature request is for *all* of Terra, and isn't something that
|
||||||
|
should be implemented by a pack or addon.
|
||||||
|
|
||||||
## Feature Description
|
## Feature Description
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: "Other Issue"
|
name: "Other Issue"
|
||||||
about: "Use this template if your issue doesn't accurately fit into any of the other categories."
|
about: "Use this template if your issue doesn't accurately fit into any of the
|
||||||
|
other categories."
|
||||||
title: ""
|
title: ""
|
||||||
labels: "Type: Question, Status: Pending"
|
labels: "Type: Question, Status: Pending"
|
||||||
assignees: ""
|
assignees: ""
|
||||||
|
|||||||
@@ -33,9 +33,11 @@
|
|||||||
|
|
||||||
<!-- In order to be accepted, your changes must be under the GPLv3 license. Please check one of the following: -->
|
<!-- In order to be accepted, your changes must be under the GPLv3 license. Please check one of the following: -->
|
||||||
|
|
||||||
- [ ] I am the original author of this code, and I am willing to release it under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html).
|
- [ ] I am the original author of this code, and I am willing to release it
|
||||||
- [ ] I am not the original author of this code, but it is in public domain or released
|
under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html).
|
||||||
under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) or a compatible license.
|
- [ ] I am not the original author of this code, but it is in public domain or
|
||||||
|
released under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) or a
|
||||||
|
compatible license.
|
||||||
<!--
|
<!--
|
||||||
Please provide reliable evidence of this.
|
Please provide reliable evidence of this.
|
||||||
NOTE: for compatible licenses, you must make sure to add the included license somewhere in the program, if so required.
|
NOTE: for compatible licenses, you must make sure to add the included license somewhere in the program, if so required.
|
||||||
@@ -82,7 +84,8 @@
|
|||||||
|
|
||||||
#### Compatiblity
|
#### Compatiblity
|
||||||
|
|
||||||
- [ ] Breaking change <!-- A fix, or a feature, that breaks some previous functionality to Terra. -->
|
- [ ] Breaking
|
||||||
|
change <!-- A fix, or a feature, that breaks some previous functionality to Terra. -->
|
||||||
- [ ] Non-Breaking change.
|
- [ ] Non-Breaking change.
|
||||||
<!--
|
<!--
|
||||||
A change which does not break *any* previous functionality of Terra.
|
A change which does not break *any* previous functionality of Terra.
|
||||||
@@ -94,8 +97,9 @@
|
|||||||
|
|
||||||
#### Contribution Guidelines.
|
#### Contribution Guidelines.
|
||||||
|
|
||||||
- [ ] I have read the [`CONTRIBUTING.md`](https://github.com/PolyhedralDev/Terra/blob/master/CONTRIBUTING.md) document in the root of the
|
- [ ] I have read
|
||||||
git repository.
|
the [`CONTRIBUTING.md`](https://github.com/PolyhedralDev/Terra/blob/master/CONTRIBUTING.md)
|
||||||
|
document in the root of the git repository.
|
||||||
- [ ] My code follows the code style for this
|
- [ ] My code follows the code style for this
|
||||||
project. <!-- There is an included `.editorconfig` file in the base of the repo. Please use a plugin for your IDE of choice that follows those settings. -->
|
project. <!-- There is an included `.editorconfig` file in the base of the repo. Please use a plugin for your IDE of choice that follows those settings. -->
|
||||||
|
|
||||||
@@ -111,4 +115,4 @@
|
|||||||
<!--
|
<!--
|
||||||
If it only introduces small changes, you don't need to add tests.
|
If it only introduces small changes, you don't need to add tests.
|
||||||
But if you add big changes, you should probably at least write *some* testing, where applicable.
|
But if you add big changes, you should probably at least write *some* testing, where applicable.
|
||||||
-->
|
-->
|
||||||
|
|||||||
+118
-10
@@ -65,6 +65,8 @@ hs_err_pid*
|
|||||||
.idea/**/dictionaries
|
.idea/**/dictionaries
|
||||||
.idea/**/shelf
|
.idea/**/shelf
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
# Generated files
|
# Generated files
|
||||||
.idea/**/contentModel.xml
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
@@ -127,17 +129,123 @@ fabric.properties
|
|||||||
# Android studio 3.1+ serialized cache file
|
# Android studio 3.1+ serialized cache file
|
||||||
.idea/caches/build_file_checksums.ser
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
# Ignore Gradle build output directory
|
### Windows template
|
||||||
build
|
# Windows thumbnail cache files
|
||||||
/target/
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
.idea/sonarlint/**
|
# Dump file
|
||||||
.idea/codeStyles/**
|
*.stackdump
|
||||||
.idea/**.xml
|
|
||||||
.idea/modules/**.iml
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
### macOS template
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### Linux template
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
### Application
|
||||||
|
# Archive love files
|
||||||
|
*.log.gz
|
||||||
|
|
||||||
|
# binary files
|
||||||
|
*.bin
|
||||||
|
|
||||||
|
# Database files
|
||||||
|
*.db
|
||||||
|
|
||||||
|
# Cache files
|
||||||
|
*.meta
|
||||||
|
*.data
|
||||||
|
|
||||||
|
### JEnv template
|
||||||
|
# JEnv local Java version configuration file
|
||||||
|
.java-version
|
||||||
|
|
||||||
|
# Used by previous versions of JEnv
|
||||||
|
.jenv-version
|
||||||
|
|
||||||
|
### VisualStudioCode template
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
### NetBeans template
|
||||||
|
**/nbproject/private/
|
||||||
|
**/nbproject/Makefile-*.mk
|
||||||
|
**/nbproject/Package-*.bash
|
||||||
|
build/
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
||||||
|
|
||||||
|
###
|
||||||
|
**/target/
|
||||||
|
|
||||||
!lib/*.jar
|
|
||||||
/run/
|
/run/
|
||||||
idea/**
|
|
||||||
|
|
||||||
testDir/
|
**/testDir/
|
||||||
|
|
||||||
|
platforms/**/run/**
|
||||||
|
|
||||||
|
|||||||
+18
-38
@@ -27,8 +27,8 @@ for everyone. We do not tolerate harassment of participants in any form.
|
|||||||
## When and How to Use These Guidelines
|
## When and How to Use These Guidelines
|
||||||
|
|
||||||
This code of conduct applies to all Terra community spaces, both online and off.
|
This code of conduct applies to all Terra community spaces, both online and off.
|
||||||
This applies to the github discussion tab, the
|
This applies to the github discussion tab, the
|
||||||
[Polyhedral Development community discord server](https://discord.gg/PXUEbbF),
|
[Polyhedral Development community discord server](https://discord.gg/PXUEbbF),
|
||||||
and any other Terra community. In addition, we may choose to invoke them in
|
and any other Terra community. In addition, we may choose to invoke them in
|
||||||
instances of harassment outside the Terra communities, and we will punish the
|
instances of harassment outside the Terra communities, and we will punish the
|
||||||
responsible individuals appropriately. We will not tolerate harassment in any
|
responsible individuals appropriately. We will not tolerate harassment in any
|
||||||
@@ -58,8 +58,8 @@ listen carefully, apologize sincerely, and correct the behavior going forward.
|
|||||||
Any member of the Terra community should always be open to new ideas and must
|
Any member of the Terra community should always be open to new ideas and must
|
||||||
always be open to the possibility of being wrong. Nobody can always be right,
|
always be open to the possibility of being wrong. Nobody can always be right,
|
||||||
and we are only human; we are
|
and we are only human; we are
|
||||||
[fallible](https://www.merriam-webster.com/dictionary/fallible) by nature.
|
[fallible](https://www.merriam-webster.com/dictionary/fallible) by nature. It is
|
||||||
It is okay to make mistakes, but we must be willing to admit when we make one.
|
okay to make mistakes, but we must be willing to admit when we make one.
|
||||||
|
|
||||||
### Be Direct but Professional
|
### Be Direct but Professional
|
||||||
|
|
||||||
@@ -315,19 +315,15 @@ Terra has a global moderation team which is currently comprised of the following
|
|||||||
members:
|
members:
|
||||||
|
|
||||||
- solonovamax
|
- solonovamax
|
||||||
-
|
- discord: [@solonovamax#6983](https://discord.com/channels/@me/566146322273402881)*
|
||||||
discord: [@solonovamax#6983](https://discord.com/channels/@me/566146322273402881)*
|
|
||||||
- github: [@solonovamax](https://github.com/solonovamax)
|
- github: [@solonovamax](https://github.com/solonovamax)
|
||||||
-
|
- email: [solonovamax@12oclockpoint.com](mailto:solonovamax@12oclockpoint.com)
|
||||||
email: [solonovamax@12oclockpoint.com](mailto:solonovamax@12oclockpoint.com)
|
|
||||||
- dfsek
|
- dfsek
|
||||||
-
|
- discord: [@dfsek#4208](https://discord.com/channels/@me/378350362236682240)*
|
||||||
discord: [@dfsek#4208](https://discord.com/channels/@me/378350362236682240)*
|
|
||||||
- github: [@dfsek](https://github.com/dfsek)
|
- github: [@dfsek](https://github.com/dfsek)
|
||||||
- email: [dfsek@protonmail.com](mailto:dfsek@protonmail.com)
|
- email: [dfsek@protonmail.com](mailto:dfsek@protonmail.com)
|
||||||
- duplex (duplexsystem)
|
- duplex (duplexsystem)
|
||||||
-
|
- discord: [@Duplex#0797](https://discord.com/channels/@me/356822848641171456)*
|
||||||
discord: [@Duplex#0797](https://discord.com/channels/@me/356822848641171456)*
|
|
||||||
- github: [@duplexsystem](https://github.com/duplexsystem)
|
- github: [@duplexsystem](https://github.com/duplexsystem)
|
||||||
- email: [duplexsys@protonmail.com](mailto:duplexsys@protonmail.com)
|
- email: [duplexsys@protonmail.com](mailto:duplexsys@protonmail.com)
|
||||||
|
|
||||||
@@ -401,32 +397,17 @@ issue on this github repo, or contact a member of the global moderation team.
|
|||||||
## License and Attribution
|
## License and Attribution
|
||||||
|
|
||||||
This set of guidelines is distributed under a
|
This set of guidelines is distributed under a
|
||||||
[Creative Commons Attribution-ShareAlike license](https://creativecommons.org/licenses/by-sa/3.0/)
|
[Creative Commons Attribution-ShareAlike license](https://creativecommons.org/licenses/by-sa/3.0/).
|
||||||
.
|
|
||||||
|
|
||||||
These guidelines have been adapted from
|
These guidelines have been adapted with modifications from the following sources:
|
||||||
[Mozilla's Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/)
|
|
||||||
, which were adapted from:
|
|
||||||
|
|
||||||
- Mozilla's original Community Participation Guidelines
|
- [Mozilla's Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/)
|
||||||
- The [Ubuntu Code of Conduct](https://ubuntu.com/community/code-of-conduct)
|
- The [Ubuntu Code of Conduct](https://ubuntu.com/community/code-of-conduct)
|
||||||
-
|
- Mozilla's [View Source Conference Code of Conduct](https://viewsourceconf.org/berlin-2016/code-of-conduct/)
|
||||||
|
- The [Rust Language Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct)
|
||||||
Mozilla's [View Source Conference Code of Conduct](https://viewsourceconf.org/berlin-2016/code-of-conduct/)
|
- The [Stumptown Syndicate's Citizen Code of Conduct](http://citizencodeofconduct.org/)
|
||||||
|
- The [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html)
|
||||||
- And
|
- The [WisCon code of conduct](http://wiscon.net/policies/anti-harassment/code-of-conduct/)
|
||||||
the [Rust Language Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct)
|
|
||||||
|
|
||||||
which in turn were based
|
|
||||||
on [Stumptown Syndicate's Citizen Code of Conduct](http://citizencodeofconduct.org/)
|
|
||||||
, along with some adapted text from
|
|
||||||
the [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html) and
|
|
||||||
the [WisCon code of conduct](http://wiscon.net/policies/anti-harassment/code-of-conduct/)
|
|
||||||
.
|
|
||||||
|
|
||||||
It was then modified by solonovamax with various inclusions from
|
|
||||||
the [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html) and
|
|
||||||
a few other sources.
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
@@ -443,7 +424,6 @@ people are not comfortable
|
|||||||
using [neopronouns](https://www.mypronouns.org/neopronouns). But if someone
|
using [neopronouns](https://www.mypronouns.org/neopronouns). But if someone
|
||||||
refuses to use your more common pronouns, you should report them to us.
|
refuses to use your more common pronouns, you should report them to us.
|
||||||
Additionally, you may not ask people to use unreasonable pronouns, such as '
|
Additionally, you may not ask people to use unreasonable pronouns, such as '
|
||||||
acab/acabself', 'that/bitch', 'ur/mom', or
|
acab/acabself', 'that/bitch', 'ur/mom', or anything else that may be considered
|
||||||
'dream/dreamself' (pronouns related to real people, eg. the minecraft youtuber '
|
disrectful. Doing so will be considered mockery of individuals who use
|
||||||
dreamwastaken'). Doing so will be considered mockery of individuals who use
|
|
||||||
non-standard pronouns and is very disrespectful.
|
non-standard pronouns and is very disrespectful.
|
||||||
+15
-11
@@ -63,7 +63,8 @@ to [Terra global moderation team](CODE_OF_CONDUCT.md#Reporting).
|
|||||||
|
|
||||||
## I don't want to read this whole thing I just have a question!!!
|
## I don't want to read this whole thing I just have a question!!!
|
||||||
|
|
||||||
> **Note:** Please don't file an issue to ask a question. You'll get faster results by using the resources below.
|
> **Note:** Please don't file an issue to ask a question. You'll get faster
|
||||||
|
> results by using the resources below.
|
||||||
|
|
||||||
We have an official discord server where you can request help from various users
|
We have an official discord server where you can request help from various users
|
||||||
|
|
||||||
@@ -77,9 +78,9 @@ Unsure where to begin contributing to Terra? You can start by looking through "
|
|||||||
beginner" and "help wanted" issues:
|
beginner" and "help wanted" issues:
|
||||||
|
|
||||||
- [Beginner issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Good%20First%20Issue)
|
- [Beginner issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Good%20First%20Issue)
|
||||||
- issues which should be friendly to anyone new to terra.
|
- issues which should be friendly to anyone new to terra.
|
||||||
- [Help wanted issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Help%20Wanted)
|
- [Help wanted issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Help%20Wanted)
|
||||||
- issues which should be a bit more involved than "beginner" issues.
|
- issues which should be a bit more involved than "beginner" issues.
|
||||||
|
|
||||||
New to github? Working on your first Pull Request? Check
|
New to github? Working on your first Pull Request? Check
|
||||||
out [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github)
|
out [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github)
|
||||||
@@ -103,7 +104,9 @@ you don't need to create one. When you are creating a bug report,
|
|||||||
please [include as many details as possible](#how-do-i-submit-a-good-bug-report)
|
please [include as many details as possible](#how-do-i-submit-a-good-bug-report)
|
||||||
.
|
.
|
||||||
|
|
||||||
> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
|
> **Note:** If you find a **Closed** issue that seems like it is the same thing
|
||||||
|
> that you're experiencing, open a new issue and include a link to the original
|
||||||
|
> issue in the body of your new one.
|
||||||
|
|
||||||
#### Before Submitting A Bug Report
|
#### Before Submitting A Bug Report
|
||||||
|
|
||||||
@@ -114,9 +117,9 @@ please [include as many details as possible](#how-do-i-submit-a-good-bug-report)
|
|||||||
- Make sure that this is not a *specific* compatibility issue with another
|
- Make sure that this is not a *specific* compatibility issue with another
|
||||||
terrain generation mod. Do not request *specific* compatibility with mods or
|
terrain generation mod. Do not request *specific* compatibility with mods or
|
||||||
plugins (e.g. "Compatibility with TechCraft v7"). That should be implemented
|
plugins (e.g. "Compatibility with TechCraft v7"). That should be implemented
|
||||||
in an addon, **not** in the main project.
|
in an addon, **not** in the platform project.
|
||||||
*General* compatibility (e.g. "Ability to pull Vanilla/Modded features from
|
*General* compatibility (e.g. "Ability to pull Vanilla/Modded features from
|
||||||
parent biomes") will be considered in the main project.
|
parent biomes") will be considered in the platform project.
|
||||||
- Search for
|
- Search for
|
||||||
any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+)
|
any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+)
|
||||||
open with your problem. If you open a duplicate, it will be closed as such.
|
open with your problem. If you open a duplicate, it will be closed as such.
|
||||||
@@ -200,7 +203,7 @@ please [include as many details as possible](#how-do-i-submit-a-good-enhancement
|
|||||||
|
|
||||||
Enhancement suggestions are tracked
|
Enhancement suggestions are tracked
|
||||||
as [GitHub issues](https://guides.github.com/features/issues/). Create an issue
|
as [GitHub issues](https://guides.github.com/features/issues/). Create an issue
|
||||||
on our main repository and provide the following information:
|
on our platform repository and provide the following information:
|
||||||
|
|
||||||
- **Use a clear and descriptive title** for the issue to identify the
|
- **Use a clear and descriptive title** for the issue to identify the
|
||||||
suggestion.
|
suggestion.
|
||||||
@@ -243,7 +246,7 @@ accepted.
|
|||||||
|
|
||||||
Pull Requests are tracked
|
Pull Requests are tracked
|
||||||
as [GitHub Pull Requests](https://guides.github.com/activities/forking/#making-a-pull-request)
|
as [GitHub Pull Requests](https://guides.github.com/activities/forking/#making-a-pull-request)
|
||||||
. Create a pr on our main repository and provide the following information:
|
. Create a pr on our platform repository and provide the following information:
|
||||||
|
|
||||||
- **Use a clear and descriptive title** to identify the pull request.
|
- **Use a clear and descriptive title** to identify the pull request.
|
||||||
- **State what this pull request adds/fixes**.
|
- **State what this pull request adds/fixes**.
|
||||||
@@ -347,7 +350,7 @@ TODO
|
|||||||
#### General Compatibility
|
#### General Compatibility
|
||||||
|
|
||||||
General compatibility (example: injection of Vanilla structures/features/carvers
|
General compatibility (example: injection of Vanilla structures/features/carvers
|
||||||
into packs) is acceptable in the main project.
|
into packs) is acceptable in the platform project.
|
||||||
|
|
||||||
- General compatibility features should be *disabled by default*. Having things
|
- General compatibility features should be *disabled by default*. Having things
|
||||||
auto-injected causes unpredictable behaviour that is annoying to diagnose.
|
auto-injected causes unpredictable behaviour that is annoying to diagnose.
|
||||||
@@ -365,8 +368,9 @@ into packs) is acceptable in the main project.
|
|||||||
|
|
||||||
#### Specific Compatibility
|
#### Specific Compatibility
|
||||||
|
|
||||||
Specific compatibility should *not* be put in the main project. (Example: Adding
|
Specific compatibility should *not* be put in the platform project. (Example:
|
||||||
the ability to generate TechCraft v7's doo-dads with a TerraScript function)
|
Adding the ability to generate TechCraft v7's doo-dads with a TerraScript
|
||||||
|
function)
|
||||||
|
|
||||||
Having specific compatibilities leads to tons of extra dependencies to keep
|
Having specific compatibilities leads to tons of extra dependencies to keep
|
||||||
track of, as well as adding lots of additional stuff to maintain. It quickly
|
track of, as well as adding lots of additional stuff to maintain. It quickly
|
||||||
|
|||||||
@@ -1,674 +1,21 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
MIT License
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
Copyright (c) 2020-2021 Polyhedral Development
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this license document, but changing it is not allowed.
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
Preamble
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
The GNU General Public License is a free, copyleft license for
|
furnished to do so, subject to the following conditions:
|
||||||
software and other kinds of works.
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
The licenses for most software and other practical works are designed
|
copies or substantial portions of the Software.
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
share and change all versions of a program--to make sure it remains free
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
GNU General Public License for most of our software; it applies also to
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
any other work released this way by its authors. You can apply it to
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
your programs, too.
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
||||||
@@ -1,15 +1,30 @@
|
|||||||
|
<img align="left" width="64" height="64" src="https://raw.githubusercontent.com/wiki/PolyhedralDev/Terra/images/terra_logo.png" alt="Terra Logo">
|
||||||
|
|
||||||
# Terra
|
# Terra
|
||||||
|
|
||||||
Terra is an incredibly powerful free & open-source data-driven,
|
Terra is a modern world generation modding platform, primarily for Minecraft.
|
||||||
platform-agnostic world generator. It allows you to create a world exactly to
|
Terra allows complete customization of world generation with an advanced API,
|
||||||
your specifications, with no knowledge of Java required.
|
tightly integrated with a powerful configuration system.
|
||||||
|
|
||||||
|
Terra consists of several parts:
|
||||||
|
|
||||||
|
* A voxel world generation API with emphasis on configuration and extensibility
|
||||||
|
* Several platform implementations, the layer between the API and the platform
|
||||||
|
it's running on.
|
||||||
|
* An addon loader, which allows addons to interface with the Terra API in a
|
||||||
|
platform-agnostic setting
|
||||||
|
* Several "core addons," which implement the "default" configurations of Terra.
|
||||||
|
These addons can be thought of as the config "standard library"
|
||||||
|
|
||||||
|
Terra currently officially supports the Fabric mod loader and the Bukkit API
|
||||||
|
(Paper and friends). We welcome Pull Requests implementing additional platforms!
|
||||||
|
|
||||||
## Downloads:
|
## Downloads:
|
||||||
|
|
||||||
* Paper+ servers (Paper, Tuinity, Purpur,
|
|
||||||
etc): [SpigotMC](https://www.spigotmc.org/resources/85151/)
|
|
||||||
* Fabric: [Modrinth](https://modrinth.com/mod/terra)
|
* Fabric: [Modrinth](https://modrinth.com/mod/terra)
|
||||||
/ [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
/ [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
||||||
|
* Paper+ servers (Paper, Tuinity, Purpur,
|
||||||
|
etc): [SpigotMC](https://www.spigotmc.org/resources/85151/)
|
||||||
|
|
||||||
## Building and Running Terra
|
## Building and Running Terra
|
||||||
|
|
||||||
@@ -32,19 +47,11 @@ JARs are produced in `platforms/<platform>/build/libs`.
|
|||||||
To run Minecraft with Terra in the IDE (for testing) use the following tasks:
|
To run Minecraft with Terra in the IDE (for testing) use the following tasks:
|
||||||
|
|
||||||
* Bukkit
|
* Bukkit
|
||||||
* `installPaper` - Install a [Paper](https://github.com/PaperMC/Paper) test
|
* `runServer` - Run the Paper test server with Terra installed.
|
||||||
server. (Only needs to be run once).
|
|
||||||
* `installPurpur` - Install a [Purpur](https://github.com/pl3xgaming/Purpur)
|
|
||||||
test server. (Only needs to be run once).
|
|
||||||
* `runPaper` - Run the Paper test server with Terra (`installPaper` must
|
|
||||||
have been run previously).
|
|
||||||
* `runPurpur` - Run the Purpur test server with Terra (`installPurpur` must
|
|
||||||
have been run previously).
|
|
||||||
* Fabric
|
* Fabric
|
||||||
* `runClient` - Run a Minecraft Fabric client with Terra installed.
|
* `runClient` - Run a Minecraft Fabric client with Terra installed.
|
||||||
* `runServer` - Run a Minecraft Fabric server with Terra installed.
|
* `runServer` - Run a Minecraft Fabric server with Terra installed.
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are welcome! If you want to see a feature in Terra, please, open
|
Contributions are welcome! If you want to see a feature in Terra, please, open
|
||||||
@@ -52,7 +59,43 @@ an issue, or implement it yourself and submit a PR!
|
|||||||
Join the discord [here](https://discord.gg/PXUEbbF) if you would like to talk
|
Join the discord [here](https://discord.gg/PXUEbbF) if you would like to talk
|
||||||
more about the project!
|
more about the project!
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
Parts of Terra are licensed under either the MIT License or the GNU General
|
||||||
|
Public License, version 3.0.
|
||||||
|
|
||||||
|
* Our API is licensed under the [MIT License](LICENSE), to ensure that everyone
|
||||||
|
is able to freely use it however they want.
|
||||||
|
* Our core addons are also licensed under the [MIT License](LICENSE), to ensure
|
||||||
|
that people can freely use code from them to learn and make their own addons,
|
||||||
|
without worrying about GPL infection.
|
||||||
|
* Our platform-agnostic implementations and platform implementations are
|
||||||
|
licensed under
|
||||||
|
the [GNU General Public License, version 3.0](common/implementation/LICENSE),
|
||||||
|
to ensure that they remain free software wherever they are used.
|
||||||
|
|
||||||
|
If you're not sure which license a particular file is under, check:
|
||||||
|
|
||||||
|
* The file's header
|
||||||
|
* The LICENSE file in the closest parent folder of the file in question
|
||||||
|
|
||||||
## Beta
|
## Beta
|
||||||
|
|
||||||
Terra is still in beta! While it is stable, it is not feature-complete. There is
|
Terra is still in beta! While it is stable, it is not feature-complete. There is
|
||||||
a lot to be added!
|
a lot to be added!
|
||||||
|
|
||||||
|
## Special Thanks
|
||||||
|
|
||||||
|
[](https://www.yourkit.com/)
|
||||||
|
|
||||||
|
YourKit has granted Polyhedral Development an open-source license to their
|
||||||
|
outstanding Java profiler, allowing us to make our software as performant as it
|
||||||
|
can be!
|
||||||
|
|
||||||
|
YourKit supports open source projects with innovative and intelligent tools for
|
||||||
|
monitoring and profiling Java and .NET applications. YourKit is the creator of
|
||||||
|
the
|
||||||
|
[YourKit Java Profiler](https://www.yourkit.com/java/profiler/),
|
||||||
|
[YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/),
|
||||||
|
and [YourKit YouMonitor](https://www.yourkit.com/youmonitor/).
|
||||||
|
|
||||||
|
|||||||
+29
-24
@@ -1,17 +1,15 @@
|
|||||||
import com.dfsek.terra.configureCompilation
|
preRelease(true)
|
||||||
import com.dfsek.terra.configureDependencies
|
|
||||||
import com.dfsek.terra.configureDistribution
|
versionProjects(":common:api", version("6.4.0"))
|
||||||
import com.dfsek.terra.configurePublishing
|
versionProjects(":common:implementation", version("6.4.0"))
|
||||||
import com.dfsek.terra.getGitHash
|
versionProjects(":platforms", version("6.4.0"))
|
||||||
|
|
||||||
val versionObj = Version("6", "0", "0", true)
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
version = versionObj
|
|
||||||
group = "com.dfsek.terra"
|
group = "com.dfsek.terra"
|
||||||
|
|
||||||
configureDependencies()
|
|
||||||
configureCompilation()
|
configureCompilation()
|
||||||
|
configureDependencies()
|
||||||
configurePublishing()
|
configurePublishing()
|
||||||
|
|
||||||
tasks.withType<JavaCompile>().configureEach {
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
@@ -30,24 +28,31 @@ allprojects {
|
|||||||
reports.html.required.set(false)
|
reports.html.required.set(false)
|
||||||
reports.junitXml.required.set(false)
|
reports.junitXml.required.set(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<Copy>().configureEach {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Jar>().configureEach {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
project(":platforms").subprojects.forEach { // Platform projects are where distribution happens
|
forImmediateSubProjects(":platforms") {
|
||||||
it.configureDistribution()
|
configureDistribution()
|
||||||
}
|
}
|
||||||
}
|
project(":platforms:bukkit:common").configureDistribution()
|
||||||
|
forSubProjects(":common:addons") {
|
||||||
/**
|
apply(plugin = "com.github.johnrengelman.shadow")
|
||||||
* Version class that does version stuff.
|
|
||||||
*/
|
tasks.named("build") {
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
finalizedBy(tasks.named("shadowJar"))
|
||||||
class Version(val major: String, val minor: String, val revision: String, val preRelease: Boolean = false) {
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
dependencies {
|
||||||
return if (!preRelease)
|
"compileOnly"(project(":common:api"))
|
||||||
"$major.$minor.$revision"
|
"testImplementation"(project(":common:api"))
|
||||||
else //Only use git hash if it's a prerelease.
|
}
|
||||||
"$major.$minor.$revision-BETA+${getGitHash()}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,21 @@ plugins {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
|
maven("https://repo.codemc.org/repository/maven-public") {
|
||||||
|
name = "CodeMC"
|
||||||
|
}
|
||||||
|
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||||
|
name = "PaperMC"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"implementation"("com.github.jengelman.gradle.plugins:shadow:+")
|
//TODO Allow pulling from Versions.kt
|
||||||
"implementation"("org.yaml:snakeyaml:1.27")
|
implementation("com.github.johnrengelman", "shadow", "8.1.1")
|
||||||
|
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin","1.5.6")
|
||||||
|
|
||||||
|
implementation("org.ow2.asm", "asm", "9.5")
|
||||||
|
implementation("org.ow2.asm", "asm-tree", "9.5")
|
||||||
|
implementation("com.dfsek.tectonic", "common", "4.2.0")
|
||||||
|
implementation("org.yaml", "snakeyaml", "2.2")
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
|
import java.io.File
|
||||||
|
import java.util.function.Predicate
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.Task
|
||||||
|
import org.gradle.kotlin.dsl.extra
|
||||||
|
import kotlin.streams.asStream
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a directory where addons will be put.
|
||||||
|
*/
|
||||||
|
fun Project.addonDir(dir: File, task: Task) {
|
||||||
|
val moveAddons = tasks.register("moveAddons" + task.name) {
|
||||||
|
dependsOn("compileAddons")
|
||||||
|
doLast {
|
||||||
|
dir.parentFile.mkdirs()
|
||||||
|
matchingAddons(dir) {
|
||||||
|
it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon.
|
||||||
|
}.forEach {
|
||||||
|
println("Deleting old addon: " + it.absolutePath)
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
forSubProjects(":common:addons") {
|
||||||
|
val jar = tasks.named("shadowJar").get() as ShadowJar
|
||||||
|
|
||||||
|
val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else ""
|
||||||
|
val target = File(dir, boot + jar.archiveFileName.get())
|
||||||
|
|
||||||
|
val base = "${jar.archiveBaseName.get()}-${version}"
|
||||||
|
|
||||||
|
println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base")
|
||||||
|
|
||||||
|
jar.archiveFile.orNull?.asFile?.copyTo(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
task.dependsOn(moveAddons)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun matchingAddons(dir: File, matcher: Predicate<File>): Set<File> {
|
||||||
|
val matching = HashSet<File>()
|
||||||
|
dir.walk().asStream().filter(matcher).forEach(matching::add)
|
||||||
|
return matching
|
||||||
|
}
|
||||||
+23
-12
@@ -1,5 +1,5 @@
|
|||||||
package com.dfsek.terra
|
import com.dfsek.terra.tectonicdoc.TectonicDocPlugin
|
||||||
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
import org.gradle.api.JavaVersion
|
import org.gradle.api.JavaVersion
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.JavaPluginExtension
|
import org.gradle.api.plugins.JavaPluginExtension
|
||||||
@@ -19,10 +19,11 @@ fun Project.configureCompilation() {
|
|||||||
apply(plugin = "java")
|
apply(plugin = "java")
|
||||||
apply(plugin = "java-library")
|
apply(plugin = "java-library")
|
||||||
apply(plugin = "idea")
|
apply(plugin = "idea")
|
||||||
|
apply<TectonicDocPlugin>()
|
||||||
|
|
||||||
configure<JavaPluginExtension> {
|
configure<JavaPluginExtension> {
|
||||||
sourceCompatibility = JavaVersion.VERSION_16
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
targetCompatibility = JavaVersion.VERSION_16
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<JavaCompile> {
|
tasks.withType<JavaCompile> {
|
||||||
@@ -34,16 +35,26 @@ fun Project.configureCompilation() {
|
|||||||
|
|
||||||
tasks.withType<ProcessResources> {
|
tasks.withType<ProcessResources> {
|
||||||
include("**/*.*")
|
include("**/*.*")
|
||||||
filter<org.apache.tools.ant.filters.ReplaceTokens>(
|
filter<ReplaceTokens>(
|
||||||
"tokens" to mapOf(
|
"tokens" to mapOf(
|
||||||
"VERSION" to project.version.toString(),
|
"DESCRIPTION" to properties["terra.description"],
|
||||||
"DESCRIPTION" to project.properties["terra.description"],
|
"WIKI" to properties["terra.wiki"],
|
||||||
"WIKI" to project.properties["terra.wiki"],
|
"SOURCE" to properties["terra.source"],
|
||||||
"SOURCE" to project.properties["terra.source"],
|
"ISSUES" to properties["terra.issues"],
|
||||||
"ISSUES" to project.properties["terra.issues"],
|
"LICENSE" to properties["terra.license"]
|
||||||
"LICENSE" to project.properties["terra.license"]
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
tasks.withType<ProcessResources> {
|
||||||
|
include("**/*.*")
|
||||||
|
filter<ReplaceTokens>(
|
||||||
|
"tokens" to mapOf(
|
||||||
|
"VERSION" to version.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Javadoc> {
|
tasks.withType<Javadoc> {
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.kotlin.dsl.creating
|
||||||
|
import org.gradle.kotlin.dsl.dependencies
|
||||||
|
import org.gradle.kotlin.dsl.getValue
|
||||||
|
import org.gradle.kotlin.dsl.getting
|
||||||
|
import org.gradle.kotlin.dsl.maven
|
||||||
|
import org.gradle.kotlin.dsl.repositories
|
||||||
|
|
||||||
|
fun Project.configureDependencies() {
|
||||||
|
val testImplementation by configurations.getting
|
||||||
|
val compileOnly by configurations.getting
|
||||||
|
|
||||||
|
val api by configurations.getting
|
||||||
|
val implementation by configurations.getting
|
||||||
|
|
||||||
|
val shaded by configurations.creating
|
||||||
|
|
||||||
|
@Suppress("UNUSED_VARIABLE")
|
||||||
|
val shadedApi by configurations.creating {
|
||||||
|
shaded.extendsFrom(this)
|
||||||
|
api.extendsFrom(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNUSED_VARIABLE")
|
||||||
|
val shadedImplementation by configurations.creating {
|
||||||
|
shaded.extendsFrom(this)
|
||||||
|
implementation.extendsFrom(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven("https://maven.fabricmc.net/") {
|
||||||
|
name = "FabricMC"
|
||||||
|
}
|
||||||
|
maven("https://repo.codemc.org/repository/maven-public") {
|
||||||
|
name = "CodeMC"
|
||||||
|
}
|
||||||
|
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||||
|
name = "PaperMC"
|
||||||
|
}
|
||||||
|
maven("https://files.minecraftforge.net/maven/") {
|
||||||
|
name = "Forge"
|
||||||
|
}
|
||||||
|
maven("https://maven.quiltmc.org/repository/release/") {
|
||||||
|
name = "Quilt"
|
||||||
|
}
|
||||||
|
maven("https://jitpack.io") {
|
||||||
|
name = "JitPack"
|
||||||
|
}
|
||||||
|
maven("https://nexuslite.gcnt.net/repos/other/") {
|
||||||
|
name = "GCNT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||||
|
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||||
|
|
||||||
|
compileOnly("com.google.guava:guava:30.0-jre")
|
||||||
|
testImplementation("com.google.guava:guava:30.0-jre")
|
||||||
|
}
|
||||||
|
}
|
||||||
+58
-47
@@ -1,24 +1,24 @@
|
|||||||
package com.dfsek.terra
|
|
||||||
|
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.FileWriter
|
import java.io.FileWriter
|
||||||
|
import java.net.URI
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.zip.ZipEntry
|
import java.nio.file.FileSystems
|
||||||
import java.util.zip.ZipOutputStream
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.BasePluginExtension
|
import org.gradle.api.plugins.BasePluginExtension
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.kotlin.dsl.TaskContainerScope
|
||||||
import org.gradle.kotlin.dsl.apply
|
import org.gradle.kotlin.dsl.apply
|
||||||
import org.gradle.kotlin.dsl.configure
|
import org.gradle.kotlin.dsl.configure
|
||||||
|
import org.gradle.kotlin.dsl.extra
|
||||||
import org.gradle.kotlin.dsl.get
|
import org.gradle.kotlin.dsl.get
|
||||||
import org.gradle.kotlin.dsl.named
|
import org.gradle.kotlin.dsl.named
|
||||||
import org.yaml.snakeyaml.DumperOptions
|
import org.yaml.snakeyaml.DumperOptions
|
||||||
import org.yaml.snakeyaml.Yaml
|
import org.yaml.snakeyaml.Yaml
|
||||||
|
|
||||||
|
|
||||||
fun Project.configureDistribution() {
|
fun Project.configureDistribution() {
|
||||||
apply(plugin = "com.github.johnrengelman.shadow")
|
apply(plugin = "com.github.johnrengelman.shadow")
|
||||||
|
|
||||||
@@ -26,53 +26,50 @@ fun Project.configureDistribution() {
|
|||||||
group = "terra"
|
group = "terra"
|
||||||
doFirst {
|
doFirst {
|
||||||
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
||||||
|
val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/latest/default.zip")
|
||||||
val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/default.zip")
|
|
||||||
downloadPack(defaultPackUrl, project)
|
downloadPack(defaultPackUrl, project)
|
||||||
val netherPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/nether.zip")
|
}
|
||||||
downloadPack(netherPackUrl, project)
|
}
|
||||||
|
|
||||||
|
val compileAddons = tasks.create("compileAddons") {
|
||||||
|
forSubProjects(":common:addons") {
|
||||||
|
afterEvaluate {
|
||||||
|
dependsOn(getJarTask())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val installAddons = tasks.create("installAddons") {
|
val installAddons = tasks.create("installAddons") {
|
||||||
group = "terra"
|
group = "terra"
|
||||||
project(":common:addons").subprojects.forEach {
|
dependsOn(compileAddons)
|
||||||
it.afterEvaluate {
|
|
||||||
dependsOn(it.tasks.getByName("build")) // Depend on addon JARs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doFirst {
|
doLast {
|
||||||
// The addons are copied into a JAR because of a ShadowJar bug
|
|
||||||
// which expands *all* JARs, even resource ones, into the fat JAR.
|
|
||||||
// To get around this, we copy all addon JARs into a *new* JAR,
|
|
||||||
// then, ShadowJar expands the newly created JAR, putting the original
|
|
||||||
// JARs where they should go.
|
|
||||||
//
|
|
||||||
// https://github.com/johnrengelman/shadow/issues/111
|
// https://github.com/johnrengelman/shadow/issues/111
|
||||||
val dest = File(buildDir, "/resources/main/addons.jar")
|
val dest = URI.create("jar:" + tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().asFile.toURI())
|
||||||
dest.parentFile.mkdirs()
|
|
||||||
|
|
||||||
val zip = ZipOutputStream(FileOutputStream(dest))
|
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
|
||||||
|
forSubProjects(":common:addons") {
|
||||||
project(":common:addons").subprojects.forEach { addonProject ->
|
val jar = getJarTask()
|
||||||
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
|
||||||
println("Packaging addon ${jar.archiveFileName.get()} to ${dest.absolutePath}.")
|
println("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB")
|
||||||
|
|
||||||
val entry = ZipEntry("addons/${jar.archiveFileName.get()}")
|
val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else ""
|
||||||
zip.putNextEntry(entry)
|
val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}")
|
||||||
FileInputStream(jar.archiveFile.get().asFile).copyTo(zip)
|
|
||||||
zip.closeEntry()
|
if (!Files.exists(addonPath)) {
|
||||||
|
Files.createDirectories(addonPath.parent)
|
||||||
|
Files.createFile(addonPath)
|
||||||
|
Files.copy(jar.archiveFile.get().asFile.toPath(), addonPath, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
zip.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val generateResourceManifest = tasks.create("generateResourceManifest") {
|
val generateResourceManifest = tasks.create("generateResourceManifest") {
|
||||||
group = "terra"
|
group = "terra"
|
||||||
dependsOn(downloadDefaultPacks)
|
doLast {
|
||||||
dependsOn(installAddons)
|
|
||||||
doFirst {
|
|
||||||
val resources = HashMap<String, MutableList<String>>()
|
val resources = HashMap<String, MutableList<String>>()
|
||||||
val packsDir = File("${project.buildDir}/resources/main/packs/")
|
val packsDir = File("${project.buildDir}/resources/main/packs/")
|
||||||
|
|
||||||
@@ -88,9 +85,11 @@ fun Project.configureDistribution() {
|
|||||||
resources.computeIfAbsent("lang") { ArrayList() }.add(it.name)
|
resources.computeIfAbsent("lang") { ArrayList() }.add(it.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
project(":common:addons").subprojects.forEach { addonProject ->
|
forSubProjects(":common:addons") {
|
||||||
val jar = (addonProject.tasks.named("jar").get() as Jar).archiveFileName.get()
|
val jar = getJarTask().archiveFileName.get()
|
||||||
resources.computeIfAbsent("addons") { ArrayList() }.add(jar)
|
resources.computeIfAbsent(
|
||||||
|
if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "addons/bootstrap"
|
||||||
|
else "addons") { ArrayList() }.add(jar)
|
||||||
}
|
}
|
||||||
|
|
||||||
val options = DumperOptions()
|
val options = DumperOptions()
|
||||||
@@ -106,25 +105,35 @@ fun Project.configureDistribution() {
|
|||||||
val manifest = File("${project.buildDir}/resources/main/resources.yml")
|
val manifest = File("${project.buildDir}/resources/main/resources.yml")
|
||||||
|
|
||||||
if (manifest.exists()) manifest.delete()
|
if (manifest.exists()) manifest.delete()
|
||||||
|
manifest.parentFile.mkdirs()
|
||||||
manifest.createNewFile()
|
manifest.createNewFile()
|
||||||
yaml.dump(resources, FileWriter(manifest))
|
FileWriter(manifest).use {
|
||||||
|
yaml.dump(resources, it)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks["processResources"].dependsOn(generateResourceManifest)
|
tasks.named("processResources") {
|
||||||
|
generateResourceManifest.mustRunAfter(downloadDefaultPacks)
|
||||||
|
finalizedBy(downloadDefaultPacks)
|
||||||
|
finalizedBy(generateResourceManifest)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
tasks.named<ShadowJar>("shadowJar") {
|
tasks.named<ShadowJar>("shadowJar") {
|
||||||
// Tell shadow to download the packs
|
// Tell shadow to download the packs
|
||||||
dependsOn(downloadDefaultPacks)
|
dependsOn(downloadDefaultPacks)
|
||||||
|
|
||||||
configurations = listOf(project.configurations["shaded"])
|
configurations = listOf(project.configurations["shaded"])
|
||||||
|
|
||||||
archiveClassifier.set("shaded")
|
archiveClassifier.set("shaded")
|
||||||
setVersion(project.version)
|
setVersion(project.version)
|
||||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||||
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
|
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
|
||||||
|
relocate("com.dfsek.paralithic", "com.dfsek.terra.lib.paralithic")
|
||||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||||
|
|
||||||
|
finalizedBy(installAddons)
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<BasePluginExtension> {
|
configure<BasePluginExtension> {
|
||||||
@@ -141,4 +150,6 @@ fun downloadPack(packUrl: URL, project: Project) {
|
|||||||
val file = File("${project.buildDir}/resources/main/packs/${fileName}")
|
val file = File("${project.buildDir}/resources/main/packs/${fileName}")
|
||||||
file.parentFile.mkdirs()
|
file.parentFile.mkdirs()
|
||||||
file.outputStream().write(packUrl.readBytes())
|
file.outputStream().write(packUrl.readBytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Project.getJarTask() = tasks.named("shadowJar").get() as ShadowJar
|
||||||
+1
-4
@@ -1,5 +1,3 @@
|
|||||||
package com.dfsek.terra
|
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.publish.PublishingExtension
|
import org.gradle.api.publish.PublishingExtension
|
||||||
import org.gradle.api.publish.maven.MavenPublication
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
@@ -13,8 +11,7 @@ fun Project.configurePublishing() {
|
|||||||
configure<PublishingExtension> {
|
configure<PublishingExtension> {
|
||||||
publications {
|
publications {
|
||||||
create<MavenPublication>("mavenJava") {
|
create<MavenPublication>("mavenJava") {
|
||||||
artifact(tasks["sourcesJar"])
|
from(components["java"])
|
||||||
artifact(tasks["jar"])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import org.gradle.api.Action
|
||||||
|
import org.gradle.api.Project
|
||||||
|
|
||||||
|
|
||||||
|
var isPrerelease = false
|
||||||
|
|
||||||
|
|
||||||
|
fun Project.getGitHash(): String {
|
||||||
|
val stdout = ByteArrayOutputStream()
|
||||||
|
exec {
|
||||||
|
commandLine = mutableListOf("git", "rev-parse", "--short", "HEAD")
|
||||||
|
standardOutput = stdout
|
||||||
|
}
|
||||||
|
return stdout.toString().trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Project.gitClone(name: String) {
|
||||||
|
val stdout = ByteArrayOutputStream()
|
||||||
|
exec {
|
||||||
|
commandLine = mutableListOf("git", "clone", name)
|
||||||
|
standardOutput = stdout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Project.forSubProjects(project: String, action: Action<Project>) {
|
||||||
|
project(project).subprojects.forEach {
|
||||||
|
action.execute(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Project.forImmediateSubProjects(project: String, action: Action<Project>) {
|
||||||
|
project(project).childProjects.forEach {
|
||||||
|
action.execute(it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun preRelease(preRelease: Boolean) {
|
||||||
|
isPrerelease = preRelease
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Project.versionProjects(project: String, version: String) {
|
||||||
|
forSubProjects(project) {
|
||||||
|
this.version = version
|
||||||
|
println("Setting version of $path to $version")
|
||||||
|
}
|
||||||
|
project(project).version = version
|
||||||
|
println("Setting version of $project to $version")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Project.version(version: String): String {
|
||||||
|
return if (!isPrerelease)
|
||||||
|
version
|
||||||
|
else //Only use git hash if it's a prerelease.
|
||||||
|
"$version-BETA+${getGitHash()}"
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
object Versions {
|
||||||
|
object Libraries {
|
||||||
|
const val tectonic = "4.2.1"
|
||||||
|
const val paralithic = "0.7.1"
|
||||||
|
const val strata = "1.3.2"
|
||||||
|
|
||||||
|
const val cloud = "1.8.4"
|
||||||
|
|
||||||
|
const val slf4j = "2.0.9"
|
||||||
|
const val log4j_slf4j_impl = "2.20.0"
|
||||||
|
|
||||||
|
object Internal {
|
||||||
|
const val shadow = "8.1.1"
|
||||||
|
const val apacheText = "1.10.0"
|
||||||
|
const val jafama = "2.3.2"
|
||||||
|
const val apacheIO = "2.14.0"
|
||||||
|
const val guava = "32.1.3-jre"
|
||||||
|
const val asm = "9.5"
|
||||||
|
const val snakeYml = "2.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Fabric {
|
||||||
|
const val fabricAPI = "0.90.0+${Mod.minecraft}"
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// object Quilt {
|
||||||
|
// const val quiltLoader = "0.20.2"
|
||||||
|
// const val fabricApi = "7.3.1+0.89.3-1.20.1"
|
||||||
|
// }
|
||||||
|
|
||||||
|
object Mod {
|
||||||
|
const val mixin = "0.12.5+mixin.0.8.5"
|
||||||
|
|
||||||
|
const val minecraft = "1.20.2"
|
||||||
|
const val yarn = "$minecraft+build.4"
|
||||||
|
const val fabricLoader = "0.14.23"
|
||||||
|
|
||||||
|
const val architecuryLoom = "1.3.357"
|
||||||
|
const val architecturyPlugin = "3.4.146"
|
||||||
|
|
||||||
|
const val loomVineflower = "1.11.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
object Forge {
|
||||||
|
const val forge = "${Mod.minecraft}-48.0.13"
|
||||||
|
const val burningwave = "12.63.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
object Bukkit {
|
||||||
|
const val paper = "1.18.2-R0.1-SNAPSHOT"
|
||||||
|
const val paperLib = "1.0.5"
|
||||||
|
const val foliaLib = "0.2.5"
|
||||||
|
const val minecraft = "1.20.2"
|
||||||
|
const val reflectionRemapper = "0.1.0-SNAPSHOT"
|
||||||
|
const val paperDevBundle = "1.20.2-R0.1-SNAPSHOT"
|
||||||
|
const val runPaper = "2.2.0"
|
||||||
|
const val paperWeight = "1.5.6"
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// object Sponge {
|
||||||
|
// const val sponge = "9.0.0-SNAPSHOT"
|
||||||
|
// const val mixin = "0.8.2"
|
||||||
|
// const val minecraft = "1.17.1"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
object CLI {
|
||||||
|
const val nbt = "6.1"
|
||||||
|
const val logback = "1.4.11"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package com.dfsek.terra
|
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
import java.util.function.Predicate
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.Task
|
|
||||||
import org.gradle.jvm.tasks.Jar
|
|
||||||
import kotlin.streams.asStream
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures a directory where addons will be put.
|
|
||||||
*/
|
|
||||||
fun Project.addonDir(dir: File, task: Task) {
|
|
||||||
task.doFirst {
|
|
||||||
dir.parentFile.mkdirs()
|
|
||||||
matchingAddons(dir) {
|
|
||||||
it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon.
|
|
||||||
}.forEach {
|
|
||||||
println("Deleting old addon: " + it.absolutePath)
|
|
||||||
it.delete()
|
|
||||||
}
|
|
||||||
project(":common:addons").subprojects.forEach { addonProject ->
|
|
||||||
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
|
||||||
|
|
||||||
val target = File(dir, jar.archiveFileName.get())
|
|
||||||
|
|
||||||
val base = "${jar.archiveBaseName.get()}-${project.version}"
|
|
||||||
|
|
||||||
println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base")
|
|
||||||
|
|
||||||
jar.archiveFile.orNull?.asFile?.copyTo(target)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun matchingAddons(dir: File, matcher: Predicate<File>): Set<File> {
|
|
||||||
val matching = HashSet<File>()
|
|
||||||
dir.walk().maxDepth(1).asStream().filter(matcher).forEach(matching::add)
|
|
||||||
return matching
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package com.dfsek.terra
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import org.gradle.api.Project
|
|
||||||
|
|
||||||
fun Project.getGitHash(): String {
|
|
||||||
val stdout = ByteArrayOutputStream()
|
|
||||||
exec {
|
|
||||||
commandLine = mutableListOf("git", "rev-parse", "--short", "HEAD")
|
|
||||||
standardOutput = stdout
|
|
||||||
}
|
|
||||||
return stdout.toString().trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Project.gitClone(name: String) {
|
|
||||||
val stdout = ByteArrayOutputStream()
|
|
||||||
exec {
|
|
||||||
commandLine = mutableListOf("git", "clone", name)
|
|
||||||
standardOutput = stdout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package com.dfsek.terra
|
|
||||||
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.kotlin.dsl.apply
|
|
||||||
import org.gradle.kotlin.dsl.dependencies
|
|
||||||
import org.gradle.kotlin.dsl.invoke
|
|
||||||
import org.gradle.kotlin.dsl.project
|
|
||||||
import org.gradle.kotlin.dsl.repositories
|
|
||||||
|
|
||||||
fun Project.configureDependencies() {
|
|
||||||
apply(plugin = "java")
|
|
||||||
apply(plugin = "java-library")
|
|
||||||
|
|
||||||
configurations {
|
|
||||||
val shaded = create("shaded")
|
|
||||||
val shadedApi = create("shadedApi")
|
|
||||||
shaded.extendsFrom(shadedApi)
|
|
||||||
getByName("api").extendsFrom(shadedApi)
|
|
||||||
val shadedImplementation = create("shadedImplementation")
|
|
||||||
shaded.extendsFrom(shadedImplementation)
|
|
||||||
getByName("implementation").extendsFrom(shadedImplementation)
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven { url = uri("https://maven.enginehub.org/repo/") }
|
|
||||||
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
|
||||||
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
|
|
||||||
maven { url = uri("https://maven.fabricmc.net/") }
|
|
||||||
gradlePluginPortal()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
|
||||||
"testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
|
||||||
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
|
||||||
|
|
||||||
"compileOnly"("com.google.guava:guava:30.0-jre")
|
|
||||||
"testImplementation"("com.google.guava:guava:30.0-jre")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project(":common:addons").subprojects.contains(this)) { // If this is an addon project, depend on the API.
|
|
||||||
dependencies {
|
|
||||||
"compileOnly"(project(":common:api"))
|
|
||||||
"testImplementation"(project(":common:api"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.dfsek.terra.tectonicdoc
|
||||||
|
|
||||||
|
class DocumentedTemplate(private val name: String) {
|
||||||
|
private val template = HashMap<String, String>()
|
||||||
|
|
||||||
|
fun add(name: String, content: String) {
|
||||||
|
template[name] = content
|
||||||
|
}
|
||||||
|
|
||||||
|
fun format(): String {
|
||||||
|
val builder = StringBuilder("# ").append(name).append("\n\n")
|
||||||
|
template.forEach { name, content ->
|
||||||
|
builder
|
||||||
|
.append("### $name\n\n")
|
||||||
|
.append(content)
|
||||||
|
.append("\n\n")
|
||||||
|
}
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package com.dfsek.terra.tectonicdoc
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Description
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Final
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.InputStream
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.plugins.JavaPluginExtension
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.objectweb.asm.ClassReader
|
||||||
|
import org.objectweb.asm.tree.ClassNode
|
||||||
|
import org.objectweb.asm.tree.FieldNode
|
||||||
|
|
||||||
|
|
||||||
|
abstract class GenerateDocsTask : DefaultTask() {
|
||||||
|
@TaskAction
|
||||||
|
fun generateDocs() {
|
||||||
|
project.extensions.getByType(JavaPluginExtension::class.java).sourceSets.forEach { sources ->
|
||||||
|
val classes = HashMap<String, ClassNode>()
|
||||||
|
sources.java.classesDirectory.get().asFileTree.forEach { file ->
|
||||||
|
if (file.name.endsWith(".class")) {
|
||||||
|
val node = createClassNode(FileInputStream(file))
|
||||||
|
if (node.fields.stream().anyMatch { field ->
|
||||||
|
field.visibleAnnotations?.stream()?.anyMatch {
|
||||||
|
it.desc.equals(descriptor(Value::class.java.canonicalName))
|
||||||
|
} == true
|
||||||
|
}) {
|
||||||
|
var name = sources
|
||||||
|
.java
|
||||||
|
.classesDirectory
|
||||||
|
.get()
|
||||||
|
.asFile
|
||||||
|
.toPath()
|
||||||
|
.relativize(file.toPath())
|
||||||
|
.toString()
|
||||||
|
.substringBeforeLast('.')
|
||||||
|
if (name.endsWith("Template")) {
|
||||||
|
name = name.substringBeforeLast("Template")
|
||||||
|
}
|
||||||
|
classes[name] = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val docsDir = File(project.buildDir, "tectonic")
|
||||||
|
docsDir.mkdirs()
|
||||||
|
|
||||||
|
classes.forEach { (name, clazz) ->
|
||||||
|
val template = DocumentedTemplate(name.substringAfterLast('/'))
|
||||||
|
clazz.fields
|
||||||
|
.stream()
|
||||||
|
.filter { field ->
|
||||||
|
field.visibleAnnotations?.stream()?.anyMatch {
|
||||||
|
it.desc.equals(descriptor(Value::class.java.canonicalName))
|
||||||
|
} == true
|
||||||
|
}.forEach { field ->
|
||||||
|
val annotations = field.visibleAnnotations
|
||||||
|
|
||||||
|
val description = StringBuilder()
|
||||||
|
|
||||||
|
annotations.stream().filter {
|
||||||
|
it.desc.equals(descriptor(Description::class.java.canonicalName))
|
||||||
|
}.forEach {
|
||||||
|
description.append(it.values[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
val keyName = StringBuilder()
|
||||||
|
|
||||||
|
if (annotations.stream().anyMatch { it.desc.equals(descriptor(Final::class.java.canonicalName)) }) {
|
||||||
|
keyName.append("final ")
|
||||||
|
}
|
||||||
|
|
||||||
|
keyName.append(getType(field))
|
||||||
|
.append(" ")
|
||||||
|
|
||||||
|
annotations.stream().filter {
|
||||||
|
it.desc.equals(descriptor(Value::class.java.canonicalName))
|
||||||
|
}.forEach {
|
||||||
|
keyName.append(it.values[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
template.add(keyName.toString(), description.toString().ifBlank {
|
||||||
|
println("No description provided for field " + field.name + " in class " + name)
|
||||||
|
"*No description provided.*"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val save = File(docsDir, "$name.md")
|
||||||
|
if (save.exists()) save.delete()
|
||||||
|
save.parentFile.mkdirs()
|
||||||
|
save.createNewFile()
|
||||||
|
save.writeText(template.format())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getType(node: FieldNode): String {
|
||||||
|
if (node.signature != null) {
|
||||||
|
return generic(node.signature)
|
||||||
|
}
|
||||||
|
return descriptorToHumanReadable(node.desc).substringAfterLast('.')
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generic(type: String): String {
|
||||||
|
val clean = descriptorToHumanReadable(type)
|
||||||
|
|
||||||
|
if (clean.contains('<')) {
|
||||||
|
val typeIndex = clean.indexOf('<')
|
||||||
|
return clean.substring(0, typeIndex + 1).substringAfterLast('.') + generic(clean.substring(typeIndex + 1)) + "\\>"
|
||||||
|
}
|
||||||
|
|
||||||
|
return clean.substringAfterLast('.')
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createClassNode(input: InputStream): ClassNode {
|
||||||
|
val reader = ClassReader(input)
|
||||||
|
val node = ClassNode()
|
||||||
|
try {
|
||||||
|
reader.accept(node, ClassReader.EXPAND_FRAMES)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
reader.accept(node, ClassReader.SKIP_FRAMES or ClassReader.SKIP_DEBUG)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun descriptorToHumanReadable(descriptor: String): String {
|
||||||
|
if (descriptor.startsWith('L')) {
|
||||||
|
return descriptor.substring(1).substringBeforeLast(';').replace('/', '.')
|
||||||
|
}
|
||||||
|
if (descriptor.startsWith("[")) {
|
||||||
|
return "${descriptorToHumanReadable(descriptor.substring(1))}[]"
|
||||||
|
}
|
||||||
|
return when (descriptor) {
|
||||||
|
"B" -> "byte"
|
||||||
|
"C" -> "char"
|
||||||
|
"I" -> "int"
|
||||||
|
"D" -> "double"
|
||||||
|
"F" -> "float"
|
||||||
|
"J" -> "long"
|
||||||
|
"S" -> "short"
|
||||||
|
"Z" -> "boolean"
|
||||||
|
else -> descriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun descriptor(name: String): String = "L${name.replace('.', '/')};"
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.dfsek.terra.tectonicdoc
|
||||||
|
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
|
||||||
|
class TectonicDocPlugin : Plugin<Project> {
|
||||||
|
override fun apply(project: Project) {
|
||||||
|
project.tasks.create("generateDocs", GenerateDocsTask::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# api addon loader
|
||||||
|
|
||||||
|
Loads dependencies as addons
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
version = version("0.1.0")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Jar> {
|
||||||
|
manifest {
|
||||||
|
attributes("Terra-Bootstrap-Addon-Entry-Point" to "com.dfsek.terra.addon.loader.ApiAddonLoader")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.extra.set("bootstrap", true)
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package com.dfsek.terra.addon.loader;
|
||||||
|
|
||||||
|
import ca.solostudios.strata.version.Version;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
|
|
||||||
|
|
||||||
|
public class ApiAddon implements BaseAddon {
|
||||||
|
private final Version version;
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
public ApiAddon(Version version, String id) {
|
||||||
|
this.version = version;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Version getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addon.loader;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
|
||||||
|
public class ApiAddonClassLoader extends URLClassLoader {
|
||||||
|
static {
|
||||||
|
ClassLoader.registerAsParallelCapable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiAddonClassLoader(URL[] urls, ClassLoader parent) {
|
||||||
|
super(urls, parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addon.loader;
|
||||||
|
|
||||||
|
import ca.solostudios.strata.Versions;
|
||||||
|
import ca.solostudios.strata.version.Version;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
|
import com.dfsek.terra.api.addon.bootstrap.BootstrapAddonClassLoader;
|
||||||
|
import com.dfsek.terra.api.addon.bootstrap.BootstrapBaseAddon;
|
||||||
|
|
||||||
|
|
||||||
|
public class ApiAddonLoader implements BootstrapBaseAddon<BaseAddon> {
|
||||||
|
private static final Version VERSION = Versions.getVersion(1, 0, 0);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<BaseAddon> loadAddons(Path addonsFolder, BootstrapAddonClassLoader parent) {
|
||||||
|
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return "API";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Version getVersion() {
|
||||||
|
return VERSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# api-features
|
|
||||||
|
|
||||||
Contains the API for feature generation.
|
|
||||||
|
|
||||||
This API implemented in:
|
|
||||||
|
|
||||||
* `config-feature`
|
|
||||||
* `generation-stage-feature`
|
|
||||||
* `config-locators`
|
|
||||||
* `config-distributors`
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
dependencies {
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
version = version("1.0.0")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||||
|
compileOnlyApi(project(":common:addons:biome-query-api"))
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.Column;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
class BaseBiomeColumn implements Column<Biome> {
|
||||||
|
private final BiomeExtrusionProvider biomeProvider;
|
||||||
|
private final Biome base;
|
||||||
|
private final int min;
|
||||||
|
private final int max;
|
||||||
|
|
||||||
|
private final int x;
|
||||||
|
private final int z;
|
||||||
|
private final long seed;
|
||||||
|
|
||||||
|
protected BaseBiomeColumn(BiomeExtrusionProvider biomeProvider, Biome base, int min, int max, int x, int z, long seed) {
|
||||||
|
this.biomeProvider = biomeProvider;
|
||||||
|
this.base = base;
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinY() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxY() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome get(int y) {
|
||||||
|
return biomeProvider.extrude(base, x, y, z, seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.config.BiomeExtrusionTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.config.ReplaceableBiomeLoader;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.config.extrusions.ReplaceExtrusionTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.config.extrusions.SetExtrusionTemplate;
|
||||||
|
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||||
|
import com.dfsek.terra.api.Platform;
|
||||||
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
|
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
|
import com.dfsek.terra.api.inject.annotations.Inject;
|
||||||
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomeExtrusionAddon implements AddonInitializer {
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<Extrusion>>> EXTRUSION_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Platform platform;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BaseAddon addon;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
platform.getEventManager()
|
||||||
|
.getHandler(FunctionalEventHandler.class)
|
||||||
|
.register(addon, ConfigPackPreLoadEvent.class)
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry =
|
||||||
|
event.getPack()
|
||||||
|
.getOrCreateRegistry(PROVIDER_REGISTRY_KEY);
|
||||||
|
providerRegistry.register(addon.key("EXTRUSION"), BiomeExtrusionTemplate::new);
|
||||||
|
})
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<Extrusion>>> extrusionRegistry = event.getPack().getOrCreateRegistry(
|
||||||
|
EXTRUSION_REGISTRY_KEY);
|
||||||
|
extrusionRegistry.register(addon.key("SET"), SetExtrusionTemplate::new);
|
||||||
|
extrusionRegistry.register(addon.key("REPLACE"), ReplaceExtrusionTemplate::new);
|
||||||
|
})
|
||||||
|
.failThrough();
|
||||||
|
|
||||||
|
platform.getEventManager()
|
||||||
|
.getHandler(FunctionalEventHandler.class)
|
||||||
|
.register(addon, ConfigPackPostLoadEvent.class)
|
||||||
|
.then(event -> {
|
||||||
|
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
|
||||||
|
event.getPack().applyLoader(ReplaceableBiome.class, new ReplaceableBiomeLoader(biomeRegistry));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.api.util.Column;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomeExtrusionProvider implements BiomeProvider {
|
||||||
|
private final BiomeProvider delegate;
|
||||||
|
private final Set<Biome> biomes;
|
||||||
|
private final List<Extrusion> extrusions;
|
||||||
|
private final int resolution;
|
||||||
|
|
||||||
|
public BiomeExtrusionProvider(BiomeProvider delegate, List<Extrusion> extrusions, int resolution) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.biomes = delegate.stream().collect(Collectors.toSet());
|
||||||
|
extrusions.forEach(e -> biomes.addAll(e.getBiomes()));
|
||||||
|
this.extrusions = extrusions;
|
||||||
|
this.resolution = resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome(int x, int y, int z, long seed) {
|
||||||
|
Biome delegated = delegate.getBiome(x, y, z, seed);
|
||||||
|
|
||||||
|
return extrude(delegated, x, y, z, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Biome extrude(Biome original, int x, int y, int z, long seed) {
|
||||||
|
for(Extrusion extrusion : extrusions) {
|
||||||
|
original = extrusion.extrude(original, x, y, z, seed);
|
||||||
|
}
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
|
||||||
|
return delegate.getBaseBiome(x, z, seed)
|
||||||
|
.map(base -> (Column<Biome>) new BaseBiomeColumn(this, base, min, max, x, z, seed))
|
||||||
|
.orElseGet(() -> BiomeProvider.super.getColumn(x, z, seed, min, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||||
|
return delegate.getBaseBiome(x, z, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Biome> getBiomes() {
|
||||||
|
return biomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int resolution() {
|
||||||
|
return resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeProvider getDelegate() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.api;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public interface Extrusion {
|
||||||
|
Biome extrude(Biome original, int x, int y, int z, long seed);
|
||||||
|
|
||||||
|
Collection<Biome> getBiomes();
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.api;
|
||||||
|
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
final class PresentBiome implements ReplaceableBiome {
|
||||||
|
private final Biome biome;
|
||||||
|
|
||||||
|
PresentBiome(Biome biome) {
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome get(Biome existing) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelf() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.api;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basically just a specialised implementation of {@link Optional} for biomes where a biome may be a "self" reference.
|
||||||
|
*/
|
||||||
|
public sealed interface ReplaceableBiome permits PresentBiome, SelfBiome {
|
||||||
|
static ReplaceableBiome of(Biome biome) {
|
||||||
|
return new PresentBiome(biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ReplaceableBiome self() {
|
||||||
|
return SelfBiome.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Biome get(Biome existing);
|
||||||
|
|
||||||
|
default Biome get() {
|
||||||
|
if(isSelf()) {
|
||||||
|
throw new IllegalStateException("Cannot get() self biome!");
|
||||||
|
}
|
||||||
|
return get(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isSelf();
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.api;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
final class SelfBiome implements ReplaceableBiome {
|
||||||
|
public static final SelfBiome INSTANCE = new SelfBiome();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome get(Biome existing) {
|
||||||
|
return Objects.requireNonNull(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelf() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.BiomeExtrusionProvider;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomeExtrusionTemplate implements ObjectTemplate<BiomeProvider> {
|
||||||
|
@Value("provider")
|
||||||
|
private @Meta BiomeProvider provider;
|
||||||
|
|
||||||
|
@Value("resolution")
|
||||||
|
@Default
|
||||||
|
private @Meta int resolution = 4;
|
||||||
|
|
||||||
|
@Value("extrusions")
|
||||||
|
private @Meta List<@Meta Extrusion> extrusions;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProvider get() {
|
||||||
|
return new BiomeExtrusionProvider(provider, extrusions, resolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||||
|
import com.dfsek.tectonic.api.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.api.loader.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||||
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReplaceableBiomeLoader implements TypeLoader<ReplaceableBiome> {
|
||||||
|
private final Registry<Biome> biomeRegistry;
|
||||||
|
|
||||||
|
public ReplaceableBiomeLoader(Registry<Biome> biomeRegistry) {
|
||||||
|
this.biomeRegistry = biomeRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReplaceableBiome load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
|
||||||
|
throws LoadException {
|
||||||
|
if(c.equals("SELF")) return ReplaceableBiome.self();
|
||||||
|
return biomeRegistry
|
||||||
|
.getByID((String) c)
|
||||||
|
.map(ReplaceableBiome::of)
|
||||||
|
.orElseThrow(() -> new LoadException("No such biome: " + c, depthTracker));
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.config.extrusions;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.extrusions.ReplaceExtrusion;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReplaceExtrusionTemplate extends SamplerExtrusionTemplate {
|
||||||
|
@Value("to")
|
||||||
|
private @Meta ProbabilityCollection<@Meta ReplaceableBiome> biomes;
|
||||||
|
|
||||||
|
@Value("from")
|
||||||
|
private @Meta String fromTag;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Extrusion get() {
|
||||||
|
return new ReplaceExtrusion(sampler, range, biomes, fromTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.config.extrusions;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.Range;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class SamplerExtrusionTemplate implements ObjectTemplate<Extrusion> {
|
||||||
|
@Value("sampler")
|
||||||
|
protected @Meta NoiseSampler sampler;
|
||||||
|
|
||||||
|
@Value("range")
|
||||||
|
protected @Meta Range range;
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.config.extrusions;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.extrusions.SetExtrusion;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
public class SetExtrusionTemplate extends SamplerExtrusionTemplate {
|
||||||
|
@Value("to")
|
||||||
|
private @Meta ProbabilityCollection<@Meta ReplaceableBiome> biomes;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Extrusion get() {
|
||||||
|
return new SetExtrusion(sampler, range, biomes);
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.extrusions;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.query.api.BiomeQueries;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.Range;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets biomes at locations based on a sampler.
|
||||||
|
*/
|
||||||
|
public class ReplaceExtrusion implements Extrusion {
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
|
private final Range range;
|
||||||
|
|
||||||
|
private final ProbabilityCollection<ReplaceableBiome> biomes;
|
||||||
|
|
||||||
|
private final Predicate<Biome> hasTag;
|
||||||
|
|
||||||
|
public ReplaceExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) {
|
||||||
|
this.sampler = sampler;
|
||||||
|
this.range = range;
|
||||||
|
this.biomes = biomes;
|
||||||
|
this.hasTag = BiomeQueries.has(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome extrude(Biome original, int x, int y, int z, long seed) {
|
||||||
|
if(hasTag.test(original)) {
|
||||||
|
return range.ifInRange(y, () -> biomes.get(sampler, x, y, z, seed).get(original), original);
|
||||||
|
}
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Biome> getBiomes() {
|
||||||
|
return biomes
|
||||||
|
.getContents()
|
||||||
|
.stream()
|
||||||
|
.filter(Predicate.not(ReplaceableBiome::isSelf))
|
||||||
|
.map(ReplaceableBiome::get)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.extrusion.extrusions;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||||
|
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.Range;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets biomes at locations based on a sampler.
|
||||||
|
*/
|
||||||
|
public class SetExtrusion implements Extrusion {
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
|
private final Range range;
|
||||||
|
|
||||||
|
private final ProbabilityCollection<ReplaceableBiome> biomes;
|
||||||
|
|
||||||
|
public SetExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes) {
|
||||||
|
this.sampler = sampler;
|
||||||
|
this.range = range;
|
||||||
|
this.biomes = biomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome extrude(Biome original, int x, int y, int z, long seed) {
|
||||||
|
return range.ifInRange(y, () -> biomes.get(sampler, x, y, z, seed).get(original), original);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Biome> getBiomes() {
|
||||||
|
return biomes
|
||||||
|
.getContents()
|
||||||
|
.stream()
|
||||||
|
.filter(Predicate.not(ReplaceableBiome::isSelf))
|
||||||
|
.map(ReplaceableBiome::get)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
schema-version: 1
|
||||||
|
contributors:
|
||||||
|
- Terra contributors
|
||||||
|
id: biome-provider-extrusion
|
||||||
|
version: @VERSION@
|
||||||
|
entrypoints:
|
||||||
|
- "com.dfsek.terra.addons.biome.extrusion.BiomeExtrusionAddon"
|
||||||
|
website:
|
||||||
|
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||||
|
source: https://github.com/PolyhedralDev/Terra
|
||||||
|
docs: https://terra.polydev.org
|
||||||
|
license: MIT License
|
||||||
|
depends:
|
||||||
|
biome-query-api: "1.+"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# biome-provider-image-v2
|
||||||
|
|
||||||
|
Implements and registers the `IMAGE` biome provider, which
|
||||||
|
utilizes various config types provided by the `library-image` addon to
|
||||||
|
distribute biomes based on images.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
version = version("1.0.0")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||||
|
compileOnlyApi(project(":common:addons:library-image"))
|
||||||
|
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
|
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
|
||||||
|
relocate("net.jafama", "com.dfsek.terra.addons.biome.image.lib.jafama")
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.image.v2;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||||
|
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class ImageBiomeProvider implements BiomeProvider {
|
||||||
|
private final int resolution;
|
||||||
|
|
||||||
|
private final ColorConverter<Biome> colorConverter;
|
||||||
|
|
||||||
|
private final ColorSampler colorSampler;
|
||||||
|
|
||||||
|
public ImageBiomeProvider(ColorConverter<Biome> colorConverter, ColorSampler colorSampler, int resolution) {
|
||||||
|
this.resolution = resolution;
|
||||||
|
this.colorConverter = colorConverter;
|
||||||
|
this.colorSampler = colorSampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome(int x, int y, int z, long seed) {
|
||||||
|
return getBiome(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Biome getBiome(int x, int z) {
|
||||||
|
x /= resolution;
|
||||||
|
z /= resolution;
|
||||||
|
return colorConverter.apply(colorSampler.apply(x, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||||
|
return Optional.of(getBiome(x, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Biome> getBiomes() {
|
||||||
|
return colorConverter.getEntries();
|
||||||
|
}
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.image.v2;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.image.v2.config.ImageProviderTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.image.v2.config.converter.ClosestBiomeColorConverterTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.image.v2.config.converter.ExactBiomeColorConverterTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.image.v2.config.converter.mapping.DefinedBiomeColorMappingTemplate;
|
||||||
|
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||||
|
import com.dfsek.terra.addons.image.converter.mapping.BiomeDefinedColorMapping;
|
||||||
|
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
|
||||||
|
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||||
|
import com.dfsek.terra.api.Platform;
|
||||||
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
|
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
|
import com.dfsek.terra.api.inject.annotations.Inject;
|
||||||
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class ImageBiomeProviderAddon implements AddonInitializer {
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<ColorConverter<Biome>>>> BIOME_COLOR_CONVERTER_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<Biome>>>> BIOME_COLOR_MAPPING_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Platform platform;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BaseAddon addon;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
platform.getEventManager()
|
||||||
|
.getHandler(FunctionalEventHandler.class)
|
||||||
|
.register(addon, ConfigPackPreLoadEvent.class)
|
||||||
|
.priority(501)
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||||
|
PROVIDER_REGISTRY_KEY);
|
||||||
|
providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new);
|
||||||
|
})
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry = event.getPack().getOrCreateRegistry(
|
||||||
|
BIOME_COLOR_CONVERTER_REGISTRY_KEY);
|
||||||
|
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new);
|
||||||
|
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new);
|
||||||
|
})
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry = event.getPack().getOrCreateRegistry(
|
||||||
|
BIOME_COLOR_MAPPING_REGISTRY_KEY);
|
||||||
|
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"), () -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class), b -> b));
|
||||||
|
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new);
|
||||||
|
})
|
||||||
|
.failThrough();
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.image.v2.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.image.v2.ImageBiomeProvider;
|
||||||
|
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||||
|
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
|
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||||
|
|
||||||
|
@Value("resolution")
|
||||||
|
@Default
|
||||||
|
@Description("Sets the resolution at which to sample the image.")
|
||||||
|
private int resolution = 1;
|
||||||
|
|
||||||
|
@Value("color-sampler")
|
||||||
|
private ColorSampler colorSampler;
|
||||||
|
|
||||||
|
@Value("color-conversion")
|
||||||
|
private ColorConverter<Biome> colorConverter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProvider get() {
|
||||||
|
return new ImageBiomeProvider(colorConverter, colorSampler, resolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.image.v2.config.converter;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.image.config.converter.ClosestColorConverterTemplate;
|
||||||
|
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public class ClosestBiomeColorConverterTemplate extends ClosestColorConverterTemplate<Biome> {
|
||||||
|
|
||||||
|
@Value("match")
|
||||||
|
private ColorMapping<Biome> match;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ColorMapping<Biome> getMapping() {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.image.v2.config.converter;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.image.config.converter.ExactColorConverterTemplate;
|
||||||
|
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public class ExactBiomeColorConverterTemplate extends ExactColorConverterTemplate<Biome> {
|
||||||
|
|
||||||
|
@Value("match")
|
||||||
|
private ColorMapping<Biome> match;
|
||||||
|
|
||||||
|
@Value("else")
|
||||||
|
private Biome fallback;
|
||||||
|
|
||||||
|
@Value("ignore-alpha")
|
||||||
|
@Default
|
||||||
|
private boolean ignoreAlpha = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ColorMapping<Biome> getMapping() {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Biome getFallback() {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean ignoreAlpha() {
|
||||||
|
return ignoreAlpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.image.v2.config.converter.mapping;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.image.config.ColorLoader.ColorString;
|
||||||
|
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
|
||||||
|
import com.dfsek.terra.addons.image.util.MapUtil;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public class DefinedBiomeColorMappingTemplate implements ObjectTemplate<ColorMapping<Biome>> {
|
||||||
|
|
||||||
|
@Value("map")
|
||||||
|
Map<ColorString, Biome> map;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ColorMapping<Biome> get() {
|
||||||
|
var map = MapUtil.mapKeys(this.map, ColorString::getColor);
|
||||||
|
return () -> map;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
schema-version: 1
|
||||||
|
contributors:
|
||||||
|
- Terra contributors
|
||||||
|
id: biome-provider-image-v2
|
||||||
|
version: @VERSION@
|
||||||
|
entrypoints:
|
||||||
|
- "com.dfsek.terra.addons.biome.image.v2.ImageBiomeProviderAddon"
|
||||||
|
website:
|
||||||
|
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||||
|
source: https://github.com/PolyhedralDev/Terra
|
||||||
|
docs: https://terra.polydev.org
|
||||||
|
license: MIT License
|
||||||
|
depends:
|
||||||
|
library-image: "1.+"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -1,2 +1,11 @@
|
|||||||
|
version = version("1.0.0")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||||
|
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
|
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
|
||||||
|
relocate("net.jafama", "com.dfsek.terra.addons.biome.image.lib.jafama")
|
||||||
|
}
|
||||||
+26
-4
@@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
package com.dfsek.terra.addons.biome.image;
|
package com.dfsek.terra.addons.biome.image;
|
||||||
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
@@ -6,19 +13,20 @@ import java.awt.Color;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
public class ImageBiomeProvider implements BiomeProvider {
|
public class ImageBiomeProvider implements BiomeProvider {
|
||||||
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
|
private final Map<Color, Biome> colorBiomeMap = new HashMap<>();
|
||||||
private final BufferedImage image;
|
private final BufferedImage image;
|
||||||
private final int resolution;
|
private final int resolution;
|
||||||
private final Align align;
|
private final Align align;
|
||||||
|
|
||||||
public ImageBiomeProvider(Set<TerraBiome> registry, BufferedImage image, int resolution, Align align) {
|
public ImageBiomeProvider(Set<Biome> registry, BufferedImage image, int resolution, Align align) {
|
||||||
this.image = image;
|
this.image = image;
|
||||||
this.resolution = resolution;
|
this.resolution = resolution;
|
||||||
this.align = align;
|
this.align = align;
|
||||||
@@ -30,7 +38,11 @@ public class ImageBiomeProvider implements BiomeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBiome(int x, int z, long seed) {
|
public Biome getBiome(int x, int y, int z, long seed) {
|
||||||
|
return getBiome(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Biome getBiome(int x, int z) {
|
||||||
x /= resolution;
|
x /= resolution;
|
||||||
z /= resolution;
|
z /= resolution;
|
||||||
Color color = align.getColor(image, x, z);
|
Color color = align.getColor(image, x, z);
|
||||||
@@ -44,6 +56,16 @@ public class ImageBiomeProvider implements BiomeProvider {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||||
|
return Optional.of(getBiome(x, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Biome> getBiomes() {
|
||||||
|
return colorBiomeMap.values();
|
||||||
|
}
|
||||||
|
|
||||||
public enum Align {
|
public enum Align {
|
||||||
CENTER {
|
CENTER {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+35
-22
@@ -1,43 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
package com.dfsek.terra.addons.biome.image;
|
package com.dfsek.terra.addons.biome.image;
|
||||||
|
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||||
import com.dfsek.terra.api.addon.TerraAddon;
|
import com.dfsek.terra.api.Platform;
|
||||||
import com.dfsek.terra.api.addon.annotations.Addon;
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
import com.dfsek.terra.api.addon.annotations.Author;
|
|
||||||
import com.dfsek.terra.api.addon.annotations.Version;
|
|
||||||
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.inject.annotations.Inject;
|
||||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
@Addon("biome-provider-image")
|
public class ImageBiomeProviderAddon implements AddonInitializer {
|
||||||
@Author("Terra")
|
|
||||||
@Version("1.0.0")
|
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
|
||||||
public class ImageBiomeProviderAddon extends TerraAddon {
|
|
||||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private Platform platform;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BaseAddon addon;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
main.getEventManager()
|
platform.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigPackPreLoadEvent.class)
|
.register(addon, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||||
PROVIDER_REGISTRY_KEY);
|
PROVIDER_REGISTRY_KEY);
|
||||||
providerRegistry.register("IMAGE", () -> new ImageProviderTemplate(event.getPack().getRegistry(TerraBiome.class)));
|
providerRegistry.register(addon.key("IMAGE"),
|
||||||
})
|
() -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
|
||||||
.failThrough();
|
})
|
||||||
|
.failThrough();
|
||||||
|
if(platform.getTerraConfig().isDebugLog())
|
||||||
|
logger.warn("The biome-provider-image addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the biome-provider-image-v2 addon for future pack development instead.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-7
@@ -1,28 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
package com.dfsek.terra.addons.biome.image;
|
package com.dfsek.terra.addons.biome.image;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import com.dfsek.terra.api.registry.Registry;
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldMayBeFinal")
|
||||||
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||||
private final Registry<TerraBiome> biomes;
|
private final Registry<Biome> biomes;
|
||||||
@Value("resolution")
|
@Value("resolution")
|
||||||
@Default
|
@Default
|
||||||
private final int resolution = 1;
|
@Description("Sets the resolution at which to sample the image.")
|
||||||
|
private int resolution = 1;
|
||||||
@Value("image.name")
|
@Value("image.name")
|
||||||
|
@Description("Sets the location of the image on the filesystem, relative to the pack root.")
|
||||||
private BufferedImage image;
|
private BufferedImage image;
|
||||||
@Value("image.align")
|
@Value("image.align")
|
||||||
|
@Description("Sets the alignment style to use for the image.")
|
||||||
private ImageBiomeProvider.Align align;
|
private ImageBiomeProvider.Align align;
|
||||||
|
|
||||||
public ImageProviderTemplate(Registry<TerraBiome> set) {
|
public ImageProviderTemplate(Registry<Biome> set) {
|
||||||
this.biomes = set;
|
this.biomes = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
schema-version: 1
|
||||||
|
contributors:
|
||||||
|
- Terra contributors
|
||||||
|
id: biome-provider-image
|
||||||
|
version: @VERSION@
|
||||||
|
entrypoints:
|
||||||
|
- "com.dfsek.terra.addons.biome.image.ImageBiomeProviderAddon"
|
||||||
|
website:
|
||||||
|
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||||
|
source: https://github.com/PolyhedralDev/Terra
|
||||||
|
docs: https://terra.polydev.org
|
||||||
|
license: MIT License
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# biome-provider-pipeline-2
|
||||||
|
|
||||||
|
The second version of the Biome Pipeline, a procedural biome provider that uses a series
|
||||||
|
of "stages" to apply "mutations" to a 2D grid of biomes.
|
||||||
|
|
||||||
|
Version 2 is a re-implementation of the original addon with the primary goal of providing
|
||||||
|
consistent scaling for noise relative to the world
|
||||||
|
(See https://github.com/PolyhedralDev/Terra/issues/264 for more details), and has been
|
||||||
|
included as a separate addon to maintain parity with packs utilizing the first version.
|
||||||
|
|
||||||
|
This addon registers the `PIPELINE` biome provider type, and all associated
|
||||||
|
configurations.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
version = version("1.0.0")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||||
|
|
||||||
|
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
|
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
|
||||||
|
relocate("net.jafama", "com.dfsek.terra.addons.biome.pipeline.lib.jafama")
|
||||||
|
}
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.BiomePipelineTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.PipelineBiomeLoader;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.source.SamplerSourceTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander.ExpanderStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderListStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceListStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.SmoothStageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||||
|
import com.dfsek.terra.api.Platform;
|
||||||
|
import com.dfsek.terra.api.addon.BaseAddon;
|
||||||
|
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||||
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
|
import com.dfsek.terra.api.inject.annotations.Inject;
|
||||||
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomePipelineAddon implements AddonInitializer {
|
||||||
|
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<Source>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
@Inject
|
||||||
|
private Platform platform;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BaseAddon addon;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
platform.getEventManager()
|
||||||
|
.getHandler(FunctionalEventHandler.class)
|
||||||
|
.register(addon, ConfigPackPreLoadEvent.class)
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||||
|
PROVIDER_REGISTRY_KEY);
|
||||||
|
providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new);
|
||||||
|
})
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry(
|
||||||
|
SOURCE_REGISTRY_KEY);
|
||||||
|
sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new);
|
||||||
|
})
|
||||||
|
.then(event -> {
|
||||||
|
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
|
||||||
|
STAGE_REGISTRY_KEY);
|
||||||
|
stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
|
||||||
|
stageRegistry.register(addon.key("SMOOTH"), SmoothStageTemplate::new);
|
||||||
|
stageRegistry.register(addon.key("REPLACE"), ReplaceStageTemplate::new);
|
||||||
|
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListStageTemplate::new);
|
||||||
|
stageRegistry.register(addon.key("BORDER"), BorderStageTemplate::new);
|
||||||
|
stageRegistry.register(addon.key("BORDER_LIST"), BorderListStageTemplate::new);
|
||||||
|
})
|
||||||
|
.failThrough();
|
||||||
|
platform.getEventManager()
|
||||||
|
.getHandler(FunctionalEventHandler.class)
|
||||||
|
.register(addon, ConfigPackPostLoadEvent.class)
|
||||||
|
.then(event -> {
|
||||||
|
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
|
||||||
|
event.getPack().applyLoader(PipelineBiome.class, new PipelineBiomeLoader(biomeRegistry));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+71
@@ -0,0 +1,71 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.Column;
|
||||||
|
import com.dfsek.terra.api.util.function.IntIntObjConsumer;
|
||||||
|
import com.dfsek.terra.api.util.function.IntObjConsumer;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomePipelineColumn implements Column<Biome> {
|
||||||
|
private final int min;
|
||||||
|
private final int max;
|
||||||
|
|
||||||
|
private final int x;
|
||||||
|
private final int z;
|
||||||
|
private final Biome biome;
|
||||||
|
|
||||||
|
protected BiomePipelineColumn(BiomeProvider biomeProvider, int min, int max, int x, int z, long seed) {
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
this.biome = biomeProvider.getBiome(x, 0, z, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinY() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxY() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome get(int y) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forRanges(int resolution, IntIntObjConsumer<Biome> consumer) {
|
||||||
|
consumer.accept(min, max, biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEach(Consumer<Biome> consumer) {
|
||||||
|
for(int y = min; y < max; y++) {
|
||||||
|
consumer.accept(biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEach(IntObjConsumer<Biome> consumer) {
|
||||||
|
for(int y = min; y < max; y++) {
|
||||||
|
consumer.accept(y, biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+115
@@ -0,0 +1,115 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.registry.key.StringIdentifiable;
|
||||||
|
import com.dfsek.terra.api.util.Column;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class PipelineBiomeProvider implements BiomeProvider {
|
||||||
|
|
||||||
|
private final LoadingCache<SeededVector, BiomeChunk> biomeChunkCache;
|
||||||
|
private final int chunkSize;
|
||||||
|
private final int resolution;
|
||||||
|
private final NoiseSampler mutator;
|
||||||
|
private final double noiseAmp;
|
||||||
|
private final Set<Biome> biomes;
|
||||||
|
|
||||||
|
public PipelineBiomeProvider(Pipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
|
||||||
|
this.resolution = resolution;
|
||||||
|
this.mutator = mutator;
|
||||||
|
this.noiseAmp = noiseAmp;
|
||||||
|
this.chunkSize = pipeline.getChunkSize();
|
||||||
|
this.biomeChunkCache = Caffeine.newBuilder()
|
||||||
|
.maximumSize(64)
|
||||||
|
.build(pipeline::generateChunk);
|
||||||
|
|
||||||
|
Set<PipelineBiome> biomeSet = new HashSet<>();
|
||||||
|
pipeline.getSource().getBiomes().forEach(biomeSet::add);
|
||||||
|
Iterable<PipelineBiome> result = biomeSet;
|
||||||
|
for(Stage stage : pipeline.getStages()) {
|
||||||
|
result = stage.getBiomes(result);
|
||||||
|
}
|
||||||
|
this.biomes = new HashSet<>();
|
||||||
|
Iterable<PipelineBiome> finalResult = result;
|
||||||
|
result.forEach(pipelineBiome -> {
|
||||||
|
if(pipelineBiome.isPlaceholder()) {
|
||||||
|
|
||||||
|
StringBuilder biomeList = new StringBuilder("\n");
|
||||||
|
StreamSupport.stream(finalResult.spliterator(), false)
|
||||||
|
.sorted(Comparator.comparing(StringIdentifiable::getID))
|
||||||
|
.forEach(delegate -> biomeList
|
||||||
|
.append(" - ")
|
||||||
|
.append(delegate.getID())
|
||||||
|
.append(':')
|
||||||
|
.append(delegate.getClass().getCanonicalName())
|
||||||
|
.append('\n'));
|
||||||
|
throw new IllegalArgumentException("Biome Pipeline leaks placeholder biome \"" + pipelineBiome.getID() +
|
||||||
|
"\". Ensure there is a stage to guarantee replacement of the placeholder biome. Biomes: " +
|
||||||
|
biomeList);
|
||||||
|
}
|
||||||
|
this.biomes.add(pipelineBiome.getBiome());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome(int x, int y, int z, long seed) {
|
||||||
|
return getBiome(x, z, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Biome getBiome(int x, int z, long seed) {
|
||||||
|
|
||||||
|
x += mutator.noise(seed + 1, x, z) * noiseAmp;
|
||||||
|
z += mutator.noise(seed + 2, x, z) * noiseAmp;
|
||||||
|
|
||||||
|
x /= resolution;
|
||||||
|
z /= resolution;
|
||||||
|
|
||||||
|
int chunkX = FastMath.floorDiv(x, chunkSize);
|
||||||
|
int chunkZ = FastMath.floorDiv(z, chunkSize);
|
||||||
|
|
||||||
|
int chunkWorldX = chunkX * chunkSize;
|
||||||
|
int chunkWorldZ = chunkZ * chunkSize;
|
||||||
|
|
||||||
|
int xInChunk = x - chunkWorldX;
|
||||||
|
int zInChunk = z - chunkWorldZ;
|
||||||
|
|
||||||
|
return biomeChunkCache.get(new SeededVector(seed, chunkWorldX, chunkWorldZ)).get(xInChunk, zInChunk).getBiome();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Biome> getBiomes() {
|
||||||
|
return biomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||||
|
return Optional.of(getBiome(x, z, seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
|
||||||
|
return new BiomePipelineColumn(this, min, max, x, z, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int resolution() {
|
||||||
|
return resolution;
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||||
|
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
|
||||||
|
|
||||||
|
public interface BiomeChunk {
|
||||||
|
|
||||||
|
PipelineBiome get(int xInChunk, int zInChunk);
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the internal grid of a BiomeChunk when applied, serves the purpose of
|
||||||
|
* filling in null biomes as a result of this resizing.
|
||||||
|
*/
|
||||||
|
public interface Expander extends Stage {
|
||||||
|
|
||||||
|
PipelineBiome fillBiome(ViewPoint viewPoint);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int maxRelativeReadDistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default PipelineBiome apply(ViewPoint viewPoint) {
|
||||||
|
PipelineBiome currentBiome = viewPoint.getBiome();
|
||||||
|
if(currentBiome == null) {
|
||||||
|
return fillBiome(viewPoint);
|
||||||
|
} else {
|
||||||
|
return currentBiome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
public interface Pipeline {
|
||||||
|
BiomeChunk generateChunk(SeededVector worldCoordinates);
|
||||||
|
|
||||||
|
int getChunkSize();
|
||||||
|
|
||||||
|
Source getSource();
|
||||||
|
|
||||||
|
List<Stage> getStages();
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||||
|
|
||||||
|
public record SeededVector(long seed, int x, int z) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(obj instanceof SeededVector that) {
|
||||||
|
return this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int code = x;
|
||||||
|
code = 31 * code + z;
|
||||||
|
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||||
|
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
|
||||||
|
|
||||||
|
public interface Source {
|
||||||
|
PipelineBiome get(long seed, int x, int z);
|
||||||
|
|
||||||
|
Iterable<PipelineBiome> getBiomes();
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
|
||||||
|
|
||||||
|
public interface Stage {
|
||||||
|
PipelineBiome apply(ViewPoint viewPoint);
|
||||||
|
|
||||||
|
int maxRelativeReadDistance();
|
||||||
|
|
||||||
|
default Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
|
||||||
|
return biomes;
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public final class DelegatedPipelineBiome implements PipelineBiome {
|
||||||
|
private final Biome biome;
|
||||||
|
|
||||||
|
public DelegatedPipelineBiome(Biome biome) {
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome() {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return biome.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(!(obj instanceof DelegatedPipelineBiome that)) return false;
|
||||||
|
return that.biome.equals(this.biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return biome.getTags();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return biome.getID();
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.registry.key.StringIdentifiable;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public interface PipelineBiome extends StringIdentifiable {
|
||||||
|
Biome getBiome();
|
||||||
|
|
||||||
|
static PipelineBiome placeholder(String id) {
|
||||||
|
return new PlaceholderPipelineBiome(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PipelineBiome from(Biome biome) {
|
||||||
|
return new DelegatedPipelineBiome(biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PipelineBiome self() {
|
||||||
|
return SelfPipelineBiome.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> getTags();
|
||||||
|
|
||||||
|
default boolean isPlaceholder() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isSelf() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
final class PlaceholderPipelineBiome implements PipelineBiome {
|
||||||
|
private final Set<String> tags;
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
public PlaceholderPipelineBiome(String id) {
|
||||||
|
this.id = id;
|
||||||
|
tags = new HashSet<>();
|
||||||
|
tags.add(id);
|
||||||
|
tags.add("ALL");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome() {
|
||||||
|
throw new UnsupportedOperationException("Cannot get raw biome from placeholder pipeline biome");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlaceholder() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(!(obj instanceof PlaceholderPipelineBiome that)) return false;
|
||||||
|
|
||||||
|
return this.id.equals(that.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
final class SelfPipelineBiome implements PipelineBiome {
|
||||||
|
public static final SelfPipelineBiome INSTANCE = new SelfPipelineBiome();
|
||||||
|
|
||||||
|
private SelfPipelineBiome() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getBiome() {
|
||||||
|
throw new UnsupportedOperationException("Cannot get biome from self delegate");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelf() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlaceholder() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return "SELF";
|
||||||
|
}
|
||||||
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.PipelineBiomeProvider;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.PipelineImpl;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
|
||||||
|
public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
|
||||||
|
@Value("resolution")
|
||||||
|
@Default
|
||||||
|
@Description("""
|
||||||
|
The resolution at which to sample biomes.
|
||||||
|
|
||||||
|
Larger values are quadratically faster, but produce lower quality results.
|
||||||
|
For example, a value of 3 would sample every 3 blocks.""")
|
||||||
|
protected @Meta int resolution = 1;
|
||||||
|
|
||||||
|
@Value("pipeline.source")
|
||||||
|
@Description("The Biome Source to use for initial population of biomes.")
|
||||||
|
private @Meta Source source;
|
||||||
|
|
||||||
|
@Value("pipeline.stages")
|
||||||
|
@Description("A list of pipeline stages to apply to the result of #source")
|
||||||
|
private @Meta List<@Meta Stage> stages;
|
||||||
|
|
||||||
|
@Value("blend.sampler")
|
||||||
|
@Default
|
||||||
|
@Description("A sampler to use for blending the edges of biomes via domain warping.")
|
||||||
|
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
|
||||||
|
|
||||||
|
@Value("blend.amplitude")
|
||||||
|
@Default
|
||||||
|
@Description("The amplitude at which to perform blending.")
|
||||||
|
protected @Meta double blendAmplitude = 0d;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeProvider get() {
|
||||||
|
return new PipelineBiomeProvider(new PipelineImpl(source, stages, resolution, 128), resolution, blendSampler, blendAmplitude);
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||||
|
import com.dfsek.tectonic.api.exception.LoadException;
|
||||||
|
import com.dfsek.tectonic.api.loader.ConfigLoader;
|
||||||
|
import com.dfsek.tectonic.api.loader.type.TypeLoader;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
|
|
||||||
|
|
||||||
|
public class PipelineBiomeLoader implements TypeLoader<PipelineBiome> {
|
||||||
|
private final Registry<Biome> biomeRegistry;
|
||||||
|
|
||||||
|
public PipelineBiomeLoader(Registry<Biome> biomeRegistry) {
|
||||||
|
this.biomeRegistry = biomeRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
|
||||||
|
throws LoadException {
|
||||||
|
if(c.equals("SELF")) return PipelineBiome.self();
|
||||||
|
return biomeRegistry
|
||||||
|
.getByID((String) c)
|
||||||
|
.map(PipelineBiome::from)
|
||||||
|
.orElseGet(() -> PipelineBiome.placeholder((String) c));
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.source;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.source.SamplerSource;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
public class SamplerSourceTemplate extends SourceTemplate {
|
||||||
|
@Value("sampler")
|
||||||
|
@Description("The sampler used to distribute biomes.")
|
||||||
|
private @Meta NoiseSampler noise;
|
||||||
|
|
||||||
|
@Value("biomes")
|
||||||
|
@Description("The biomes to be distributed.")
|
||||||
|
private @Meta ProbabilityCollection<@Meta PipelineBiome> biomes;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Source get() {
|
||||||
|
return new SamplerSource(biomes, noise);
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.source;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class SourceTemplate implements ObjectTemplate<Source> {
|
||||||
|
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class StageTemplate implements ObjectTemplate<Stage> {
|
||||||
|
@Value("sampler")
|
||||||
|
@Description("Sampler to use for stage distribution.")
|
||||||
|
protected @Meta NoiseSampler noise;
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.stage.expander.FractalExpander;
|
||||||
|
|
||||||
|
|
||||||
|
public class ExpanderStageTemplate extends StageTemplate {
|
||||||
|
@Override
|
||||||
|
public Expander get() {
|
||||||
|
return new FractalExpander(noise);
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.BorderListStage;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class BorderListStageTemplate extends StageTemplate {
|
||||||
|
@Value("from")
|
||||||
|
private @Meta String from;
|
||||||
|
|
||||||
|
@Value("default-replace")
|
||||||
|
private @Meta String defaultReplace;
|
||||||
|
|
||||||
|
@Value("default-to")
|
||||||
|
private @Meta ProbabilityCollection<@Meta PipelineBiome> defaultTo;
|
||||||
|
|
||||||
|
@Value("replace")
|
||||||
|
private @Meta Map<@Meta PipelineBiome, @Meta ProbabilityCollection<@Meta PipelineBiome>> replace;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stage get() {
|
||||||
|
return new BorderListStage(replace, from, defaultReplace, noise, defaultTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.BorderStage;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class BorderStageTemplate extends StageTemplate {
|
||||||
|
@Value("from")
|
||||||
|
private @Meta String from;
|
||||||
|
|
||||||
|
@Value("replace")
|
||||||
|
private @Meta String replace;
|
||||||
|
|
||||||
|
@Value("to")
|
||||||
|
private @Meta ProbabilityCollection<@Meta PipelineBiome> to;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stage get() {
|
||||||
|
return new BorderStage(from, replace, noise, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.ReplaceListStage;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ReplaceListStageTemplate extends StageTemplate {
|
||||||
|
@Value("default-from")
|
||||||
|
private @Meta String defaultFrom;
|
||||||
|
|
||||||
|
@Value("default-to")
|
||||||
|
private @Meta ProbabilityCollection<@Meta PipelineBiome> defaultTo;
|
||||||
|
|
||||||
|
@Value("to")
|
||||||
|
private @Meta Map<@Meta PipelineBiome, @Meta ProbabilityCollection<@Meta PipelineBiome>> replace;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stage get() {
|
||||||
|
return new ReplaceListStage(replace, defaultFrom, defaultTo, noise);
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.ReplaceStage;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class ReplaceStageTemplate extends StageTemplate {
|
||||||
|
@Value("from")
|
||||||
|
private @Meta String from;
|
||||||
|
|
||||||
|
@Value("to")
|
||||||
|
private @Meta ProbabilityCollection<@Meta PipelineBiome> to;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stage get() {
|
||||||
|
return new ReplaceStage(from, to, noise);
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.SmoothStage;
|
||||||
|
|
||||||
|
|
||||||
|
public class SmoothStageTemplate extends StageTemplate {
|
||||||
|
@Override
|
||||||
|
public Stage get() {
|
||||||
|
return new SmoothStage(noise);
|
||||||
|
}
|
||||||
|
}
|
||||||
+217
@@ -0,0 +1,217 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
public class BiomeChunkImpl implements BiomeChunk {
|
||||||
|
|
||||||
|
private PipelineBiome[][] biomes;
|
||||||
|
private final SeededVector worldOrigin;
|
||||||
|
private final int chunkOriginArrayIndex;
|
||||||
|
private final int worldCoordinateScale;
|
||||||
|
|
||||||
|
public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) {
|
||||||
|
|
||||||
|
this.worldOrigin = worldOrigin;
|
||||||
|
this.chunkOriginArrayIndex = pipeline.getChunkOriginArrayIndex();
|
||||||
|
this.worldCoordinateScale = pipeline.getResolution();
|
||||||
|
|
||||||
|
int size = pipeline.getArraySize();
|
||||||
|
|
||||||
|
int expanderCount = pipeline.getExpanderCount();
|
||||||
|
int expansionsApplied = 0;
|
||||||
|
|
||||||
|
// Allocate working arrays
|
||||||
|
this.biomes = new PipelineBiome[size][size];
|
||||||
|
PipelineBiome[][] lookupArray = new PipelineBiome[size][size];
|
||||||
|
// A second lookup array is required such that stage application doesn't affect lookups, otherwise application may cascade
|
||||||
|
|
||||||
|
// Construct working grid
|
||||||
|
int gridOrigin = 0;
|
||||||
|
int gridInterval = calculateGridInterval(expanderCount, expansionsApplied);
|
||||||
|
int gridSize = (size / gridInterval);
|
||||||
|
gridSize += expanderCount > 0 ? 1 : 0; // Add an extra border if expansion occurs
|
||||||
|
|
||||||
|
// Fill working grid with initial cells
|
||||||
|
for(int gridX = 0; gridX < gridSize; gridX++) {
|
||||||
|
for(int gridZ = 0; gridZ < gridSize; gridZ++) {
|
||||||
|
int xIndex = gridOrigin + gridX * gridInterval;
|
||||||
|
int zIndex = gridOrigin + gridZ * gridInterval;
|
||||||
|
biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex), zIndexToWorldCoordinate(zIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Stage stage : pipeline.getStages()) {
|
||||||
|
if(stage instanceof Expander) {
|
||||||
|
// Shrink working grid size, the expander will fill in null cells (as a result of shrinking the grid) during mutation
|
||||||
|
expansionsApplied++;
|
||||||
|
gridInterval = calculateGridInterval(expanderCount, expansionsApplied);
|
||||||
|
gridSize = expandSize(gridSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
int stageReadDistance = stage.maxRelativeReadDistance();
|
||||||
|
if(stageReadDistance > 0) {
|
||||||
|
// Discard edges such that adjacent lookups are only ran on valid cells
|
||||||
|
gridSize = contractBordersFromSize(gridSize, stageReadDistance);
|
||||||
|
gridOrigin += stageReadDistance * gridInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycle arrays, the previously populated array is swapped to be used for lookups, and the result of the stage application
|
||||||
|
// overwrites the previous lookup array. This saves having to allocate a new array copy each time
|
||||||
|
PipelineBiome[][] tempArray = biomes;
|
||||||
|
biomes = lookupArray;
|
||||||
|
lookupArray = tempArray;
|
||||||
|
|
||||||
|
// Apply stage to working grid
|
||||||
|
for(int gridZ = 0; gridZ < gridSize; gridZ = gridZ + 1) {
|
||||||
|
for(int gridX = 0; gridX < gridSize; gridX = gridX + 1) {
|
||||||
|
int xIndex = gridOrigin + gridX * gridInterval;
|
||||||
|
int zIndex = gridOrigin + gridZ * gridInterval;
|
||||||
|
biomes[xIndex][zIndex] = stage.apply(new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome get(int xInChunk, int zInChunk) {
|
||||||
|
int xIndex = xInChunk + chunkOriginArrayIndex;
|
||||||
|
int zIndex = zInChunk + chunkOriginArrayIndex;
|
||||||
|
return biomes[xIndex][zIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
private int xIndexToWorldCoordinate(int xIndex) {
|
||||||
|
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int zIndexToWorldCoordinate(int zIndex) {
|
||||||
|
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int initialSizeToArraySize(int expanderCount, int initialSize) {
|
||||||
|
int size = initialSize;
|
||||||
|
for(int i = 0; i < expanderCount; i++) {
|
||||||
|
size = expandSize(size);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int calculateChunkOriginArrayIndex(int totalExpanderCount, List<Stage> stages) {
|
||||||
|
int finalGridOrigin = calculateFinalGridOrigin(totalExpanderCount, stages);
|
||||||
|
int initialGridInterval = calculateGridInterval(totalExpanderCount, 0);
|
||||||
|
|
||||||
|
// Round the final grid origin up to the nearest multiple of initialGridInterval, such that each
|
||||||
|
// chunk samples points on the same overall grid.
|
||||||
|
// Without this, shared chunk borders (required because of adjacent cell reads) will not be identical
|
||||||
|
// because points would be sampled on grids at different offsets, resulting in artifacts at borders.
|
||||||
|
return FastMath.ceilToInt((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) {
|
||||||
|
int gridOrigin = 0;
|
||||||
|
int expansionsApplied = 0;
|
||||||
|
int gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
|
||||||
|
for (Stage stage : stages) {
|
||||||
|
if (stage instanceof Expander) {
|
||||||
|
expansionsApplied++;
|
||||||
|
gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
|
||||||
|
}
|
||||||
|
gridOrigin += stage.maxRelativeReadDistance() * gridInterval;
|
||||||
|
}
|
||||||
|
return gridOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int calculateChunkSize(int arraySize, int chunkOriginArrayIndex, int totalExpanderCount) {
|
||||||
|
return contractBordersFromSize(arraySize, chunkOriginArrayIndex) - (totalExpanderCount > 0 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int expandSize(int size) {
|
||||||
|
return size * 2 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int contractBordersFromSize(int size, int border) {
|
||||||
|
return size - border * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int calculateGridInterval(int totalExpansions, int expansionsApplied) {
|
||||||
|
return 1 << (totalExpansions - expansionsApplied);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SeededVector getOrigin() {
|
||||||
|
return worldOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a point on the operating grid within the biomes array
|
||||||
|
*/
|
||||||
|
public static class ViewPoint {
|
||||||
|
private final BiomeChunkImpl chunk;
|
||||||
|
private final PipelineBiome biome;
|
||||||
|
private final int gridInterval;
|
||||||
|
private final int gridX;
|
||||||
|
private final int gridZ;
|
||||||
|
private final int xIndex;
|
||||||
|
private final int zIndex;
|
||||||
|
private final PipelineBiome[][] lookupArray;
|
||||||
|
|
||||||
|
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex, PipelineBiome[][] lookupArray) {
|
||||||
|
this.chunk = chunk;
|
||||||
|
this.gridInterval = gridInterval;
|
||||||
|
this.gridX = gridX;
|
||||||
|
this.gridZ = gridZ;
|
||||||
|
this.xIndex = xIndex;
|
||||||
|
this.zIndex = zIndex;
|
||||||
|
this.lookupArray = lookupArray;
|
||||||
|
this.biome = lookupArray[xIndex][zIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
public PipelineBiome getRelativeBiome(int x, int z) {
|
||||||
|
int lookupXIndex = this.xIndex + x * gridInterval;
|
||||||
|
int lookupZIndex = this.zIndex + z * gridInterval;
|
||||||
|
return lookupArray[lookupXIndex][lookupZIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
public PipelineBiome getBiome() {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return X position of the point relative to the operating grid
|
||||||
|
*/
|
||||||
|
public int gridX() {
|
||||||
|
return gridX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Z position of the point relative to the operating grid
|
||||||
|
*/
|
||||||
|
public int gridZ() {
|
||||||
|
return gridZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return X position of the point in the world
|
||||||
|
*/
|
||||||
|
public int worldX() {
|
||||||
|
return chunk.xIndexToWorldCoordinate(xIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Z position of the point in the world
|
||||||
|
*/
|
||||||
|
public int worldZ() {
|
||||||
|
return chunk.zIndexToWorldCoordinate(zIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long worldSeed() {
|
||||||
|
return chunk.getOrigin().seed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+92
@@ -0,0 +1,92 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
|
||||||
|
|
||||||
|
public class PipelineImpl implements Pipeline {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PipelineImpl.class);
|
||||||
|
|
||||||
|
private final Source source;
|
||||||
|
private final List<Stage> stages;
|
||||||
|
private final int chunkSize;
|
||||||
|
private final int expanderCount;
|
||||||
|
private final int arraySize;
|
||||||
|
private final int chunkOriginArrayIndex;
|
||||||
|
private final int resolution;
|
||||||
|
|
||||||
|
public PipelineImpl(Source source, List<Stage> stages, int resolution, int idealChunkArraySize) {
|
||||||
|
this.source = source;
|
||||||
|
this.stages = stages;
|
||||||
|
this.resolution = resolution;
|
||||||
|
this.expanderCount = (int) stages.stream().filter(s -> s instanceof Expander).count();
|
||||||
|
|
||||||
|
// Optimize for the ideal array size
|
||||||
|
int arraySize;
|
||||||
|
int chunkOriginArrayIndex;
|
||||||
|
int chunkSize;
|
||||||
|
int initialSize = 1;
|
||||||
|
while (true) {
|
||||||
|
arraySize = BiomeChunkImpl.initialSizeToArraySize(expanderCount, initialSize);
|
||||||
|
chunkOriginArrayIndex = BiomeChunkImpl.calculateChunkOriginArrayIndex(expanderCount, stages);
|
||||||
|
chunkSize = BiomeChunkImpl.calculateChunkSize(arraySize, chunkOriginArrayIndex, expanderCount);
|
||||||
|
if (chunkSize > 1 && arraySize >= idealChunkArraySize) break;
|
||||||
|
initialSize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.arraySize = arraySize;
|
||||||
|
this.chunkOriginArrayIndex = chunkOriginArrayIndex;
|
||||||
|
this.chunkSize = chunkSize;
|
||||||
|
|
||||||
|
logger.debug("Initialized a new biome pipeline:");
|
||||||
|
logger.debug("Array size: {} (Target: {})", arraySize, idealChunkArraySize);
|
||||||
|
logger.debug("Internal array origin: {}", chunkOriginArrayIndex);
|
||||||
|
logger.debug("Chunk size: {}", chunkSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeChunk generateChunk(SeededVector worldCoordinates) {
|
||||||
|
return new BiomeChunkImpl(worldCoordinates, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getChunkSize() {
|
||||||
|
return chunkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Source getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Stage> getStages() {
|
||||||
|
return stages;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getExpanderCount() {
|
||||||
|
return expanderCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getArraySize() {
|
||||||
|
return arraySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getChunkOriginArrayIndex() {
|
||||||
|
return chunkOriginArrayIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getResolution() {
|
||||||
|
return resolution;
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.source;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
public class SamplerSource implements Source {
|
||||||
|
private final ProbabilityCollection<PipelineBiome> biomes;
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
|
public SamplerSource(ProbabilityCollection<PipelineBiome> biomes, NoiseSampler sampler) {
|
||||||
|
this.biomes = biomes;
|
||||||
|
this.sampler = sampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome get(long seed, int x, int z) {
|
||||||
|
return biomes.get(sampler, x, z, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<PipelineBiome> getBiomes() {
|
||||||
|
return biomes.getContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.source;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||||
|
|
||||||
|
|
||||||
|
public class SingleSource implements Source {
|
||||||
|
|
||||||
|
private final PipelineBiome biome;
|
||||||
|
|
||||||
|
public SingleSource(PipelineBiome biome) {
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome get(long seed, int x, int z) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<PipelineBiome> getBiomes() {
|
||||||
|
return Collections.singleton(biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.stage.expander;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
|
public class FractalExpander implements Expander {
|
||||||
|
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
|
public FractalExpander(NoiseSampler sampler) {
|
||||||
|
this.sampler = sampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome fillBiome(BiomeChunkImpl.ViewPoint viewPoint) {
|
||||||
|
|
||||||
|
int xMod2 = viewPoint.gridX() % 2;
|
||||||
|
int zMod2 = viewPoint.gridZ() % 2;
|
||||||
|
|
||||||
|
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
|
||||||
|
|
||||||
|
if (xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly
|
||||||
|
return roll > 0 ? viewPoint.getRelativeBiome(-1, 0) : viewPoint.getRelativeBiome(1, 0);
|
||||||
|
|
||||||
|
} else if (xMod2 == 0 && zMod2 == 1) { // Pick one of 2 neighbors on Z axis randomly
|
||||||
|
return roll > 0 ? viewPoint.getRelativeBiome(0, -1) : viewPoint.getRelativeBiome(0, 1);
|
||||||
|
|
||||||
|
} else { // Pick one of 4 corners randomly
|
||||||
|
return roll > 0 ?
|
||||||
|
roll > 0.25 ? viewPoint.getRelativeBiome(-1, 1) : viewPoint.getRelativeBiome(1, 1) :
|
||||||
|
roll > -0.25 ? viewPoint.getRelativeBiome(-1, -1) : viewPoint.getRelativeBiome(1, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.util.vector.Vector2Int;
|
||||||
|
|
||||||
|
|
||||||
|
public class BorderListStage implements Stage {
|
||||||
|
private final String border;
|
||||||
|
private final NoiseSampler noiseSampler;
|
||||||
|
private final ProbabilityCollection<PipelineBiome> replaceDefault;
|
||||||
|
private final String defaultReplace;
|
||||||
|
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
|
||||||
|
|
||||||
|
private final Vector2Int[] borderPoints;
|
||||||
|
|
||||||
|
public BorderListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String border, String defaultReplace,
|
||||||
|
NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replaceDefault) {
|
||||||
|
this.border = border;
|
||||||
|
this.noiseSampler = noiseSampler;
|
||||||
|
this.replaceDefault = replaceDefault;
|
||||||
|
this.defaultReplace = defaultReplace;
|
||||||
|
this.replace = replace;
|
||||||
|
|
||||||
|
List<Vector2Int> points = new ArrayList<>();
|
||||||
|
for(int x = -1; x <= 1; x++) {
|
||||||
|
for(int z = -1; z <= 1; z++) {
|
||||||
|
if(x == 0 && z == 0) continue;
|
||||||
|
points.add(Vector2Int.of(x, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.borderPoints = points.toArray(new Vector2Int[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
|
||||||
|
Set<PipelineBiome> biomeSet = new HashSet<>();
|
||||||
|
biomes.forEach(biomeSet::add);
|
||||||
|
biomeSet.addAll(replaceDefault.getContents().stream().filter(Predicate.not(PipelineBiome::isSelf)).toList());
|
||||||
|
replace.forEach((biome, collection) -> biomeSet.addAll(collection.getContents()));
|
||||||
|
return biomeSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
|
||||||
|
PipelineBiome center = viewPoint.getBiome();
|
||||||
|
if(center.getTags().contains(defaultReplace)) {
|
||||||
|
for(Vector2Int point : borderPoints) {
|
||||||
|
PipelineBiome current = viewPoint.getRelativeBiome(point.getX(), point.getZ());
|
||||||
|
if(current != null && current.getTags().contains(border)) {
|
||||||
|
if(replace.containsKey(center)) {
|
||||||
|
PipelineBiome replacement = replace.get(center).get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
|
||||||
|
viewPoint.worldSeed());
|
||||||
|
return replacement.isSelf() ? center : replacement;
|
||||||
|
}
|
||||||
|
PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
|
||||||
|
return replacement.isSelf() ? center : replacement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxRelativeReadDistance() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
import com.dfsek.terra.api.util.vector.Vector2Int;
|
||||||
|
|
||||||
|
|
||||||
|
public class BorderStage implements Stage {
|
||||||
|
private final String border;
|
||||||
|
private final NoiseSampler noiseSampler;
|
||||||
|
private final ProbabilityCollection<PipelineBiome> replace;
|
||||||
|
private final String replaceTag;
|
||||||
|
private final Vector2Int[] borderPoints;
|
||||||
|
|
||||||
|
public BorderStage(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replace) {
|
||||||
|
this.border = border;
|
||||||
|
this.noiseSampler = noiseSampler;
|
||||||
|
this.replace = replace;
|
||||||
|
this.replaceTag = replaceTag;
|
||||||
|
List<Vector2Int> points = new ArrayList<>();
|
||||||
|
for(int x = -1; x <= 1; x++) {
|
||||||
|
for(int z = -1; z <= 1; z++) {
|
||||||
|
if(x == 0 && z == 0) continue;
|
||||||
|
points.add(Vector2Int.of(x, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.borderPoints = points.toArray(new Vector2Int[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
|
||||||
|
PipelineBiome center = viewPoint.getBiome();
|
||||||
|
if(center.getTags().contains(replaceTag)) {
|
||||||
|
for(Vector2Int point : borderPoints) {
|
||||||
|
PipelineBiome current = viewPoint.getRelativeBiome(point.getX(), point.getZ());
|
||||||
|
if(current != null && current.getTags().contains(border)) {
|
||||||
|
PipelineBiome replacement = replace.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
|
||||||
|
return replacement.isSelf() ? center : replacement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
|
||||||
|
Set<PipelineBiome> biomeSet = new HashSet<>();
|
||||||
|
biomes.forEach(biomeSet::add);
|
||||||
|
biomeSet.addAll(
|
||||||
|
replace
|
||||||
|
.getContents()
|
||||||
|
.stream()
|
||||||
|
.filter(
|
||||||
|
Predicate.not(PipelineBiome::isSelf)
|
||||||
|
)
|
||||||
|
.toList()
|
||||||
|
);
|
||||||
|
return biomeSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxRelativeReadDistance() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
+78
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReplaceListStage implements Stage {
|
||||||
|
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
private final ProbabilityCollection<PipelineBiome> replaceDefault;
|
||||||
|
private final String defaultTag;
|
||||||
|
|
||||||
|
public ReplaceListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String defaultTag,
|
||||||
|
ProbabilityCollection<PipelineBiome> replaceDefault, NoiseSampler sampler) {
|
||||||
|
this.replace = replace;
|
||||||
|
this.sampler = sampler;
|
||||||
|
this.defaultTag = defaultTag;
|
||||||
|
this.replaceDefault = replaceDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
|
||||||
|
PipelineBiome center = viewPoint.getBiome();
|
||||||
|
if(replace.containsKey(center)) {
|
||||||
|
PipelineBiome biome = replace.get(center).get(sampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
|
||||||
|
return biome.isSelf() ? viewPoint.getBiome() : biome;
|
||||||
|
}
|
||||||
|
if(viewPoint.getBiome().getTags().contains(defaultTag)) {
|
||||||
|
PipelineBiome biome = replaceDefault.get(sampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
|
||||||
|
return biome.isSelf() ? viewPoint.getBiome() : biome;
|
||||||
|
}
|
||||||
|
return center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxRelativeReadDistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
|
||||||
|
Set<PipelineBiome> biomeSet = new HashSet<>();
|
||||||
|
|
||||||
|
Set<PipelineBiome> reject = new HashSet<>();
|
||||||
|
|
||||||
|
biomes.forEach(biome -> {
|
||||||
|
if(!biome.getTags().contains(defaultTag) && !replace.containsKey(biome)) {
|
||||||
|
biomeSet.add(biome);
|
||||||
|
} else {
|
||||||
|
reject.add(biome);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
biomeSet.addAll(replaceDefault.getContents().stream().flatMap(terraBiome -> {
|
||||||
|
if(terraBiome.isSelf()) return reject.stream();
|
||||||
|
return Stream.of(terraBiome);
|
||||||
|
}).toList());
|
||||||
|
replace.forEach((biome, collection) -> biomeSet.addAll(collection.getContents().stream().map(terraBiome -> {
|
||||||
|
if(terraBiome.isSelf()) return biome;
|
||||||
|
return terraBiome;
|
||||||
|
}).toList()));
|
||||||
|
return biomeSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReplaceStage implements Stage {
|
||||||
|
private final String replaceableTag;
|
||||||
|
private final ProbabilityCollection<PipelineBiome> replace;
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
|
public ReplaceStage(String replaceable, ProbabilityCollection<PipelineBiome> replace, NoiseSampler sampler) {
|
||||||
|
this.replaceableTag = replaceable;
|
||||||
|
this.replace = replace;
|
||||||
|
this.sampler = sampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
|
||||||
|
if(viewPoint.getBiome().getTags().contains(replaceableTag)) {
|
||||||
|
PipelineBiome biome = replace.get(sampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
|
||||||
|
return biome.isSelf() ? viewPoint.getBiome() : biome;
|
||||||
|
}
|
||||||
|
return viewPoint.getBiome();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int maxRelativeReadDistance() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
|
||||||
|
Set<PipelineBiome> biomeSet = new HashSet<>();
|
||||||
|
Set<PipelineBiome> reject = new HashSet<>();
|
||||||
|
biomes.forEach(biome -> {
|
||||||
|
if(!biome.getTags().contains(replaceableTag)) {
|
||||||
|
biomeSet.add(biome);
|
||||||
|
} else {
|
||||||
|
reject.add(biome);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
biomeSet.addAll(replace.getContents().stream().flatMap(terraBiome -> {
|
||||||
|
if(terraBiome.isSelf()) return reject.stream();
|
||||||
|
return Stream.of(terraBiome);
|
||||||
|
}).toList());
|
||||||
|
return biomeSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user