mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 08:40:26 +00:00
Compare commits
598 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0efb0916e6 | |||
| 82fbf796da | |||
| 94bf67d09d | |||
| f86d4bae32 | |||
| c7cecaebe6 | |||
| 866d527d35 | |||
| 4f706f5502 | |||
| fe954a7b2b | |||
| 15e72bae35 | |||
| 513c2df9f9 | |||
| aec00d9169 | |||
| 540552d301 | |||
| 4dfe2054e9 | |||
| 16e61098d9 | |||
| 8aecf6b97f | |||
| 4788483139 | |||
| 9e8aefe7f7 | |||
| 272556ed81 | |||
| fd0c4df04c | |||
| 1c3ee86376 | |||
| defd775f13 | |||
| a73fda7d04 | |||
| b8586135b8 | |||
| 4065cfea53 | |||
| a117db40be | |||
| 72e0974cc5 | |||
| d8938c5519 | |||
| acf79f5c53 | |||
| 839bc23a5a | |||
| 852cf0321b | |||
| 89d497d500 | |||
| 0df940d688 | |||
| dd7bebb27f | |||
| 72649d5cf7 | |||
| 7cf87de463 | |||
| 020033f839 | |||
| b3ef4ac79c | |||
| 3f9f2bdce4 | |||
| 0ab463f34f | |||
| 0b1d67b533 | |||
| c4f665ffc5 | |||
| c00753b0fc | |||
| 77812545df | |||
| ad9bc7f67c | |||
| 81a96d6b76 | |||
| d696e4fd24 | |||
| c98d39c5d7 | |||
| a6fe268f79 | |||
| 648da95e7d | |||
| 5829112a74 | |||
| c41bf55b7b | |||
| 5d12a560f1 | |||
| 6f08908bb4 | |||
| 9292d3de17 | |||
| 0149a29b04 | |||
| cd8605850f | |||
| 148b8dfe35 | |||
| 3f485b1825 | |||
| cb6ecff113 | |||
| e30bcbf1ba | |||
| 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 | |||
| 70b1c3bbf3 | |||
| e9b145b6c3 | |||
| 99d848b394 | |||
| 4828d51da4 | |||
| 8e0d64dccd | |||
| 23f47de10a | |||
| 89651597c2 | |||
| 5c0c833b70 | |||
| 33d654dc8e | |||
| f0c602d7e7 | |||
| 0e37a839fe | |||
| 3f9ead0d66 | |||
| 5eeb5af6c4 | |||
| 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 | |||
| d07f9fe341 | |||
| 9c9487ced6 | |||
| 9d131a8992 | |||
| cd57a32f31 |
+7
-7
@@ -8,7 +8,7 @@ indent_style = space
|
||||
insert_final_newline = false
|
||||
max_line_length = 140
|
||||
tab_width = 4
|
||||
ij_continuation_indent_size = 8
|
||||
ij_continuation_indent_size = 4
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = false
|
||||
@@ -25,12 +25,12 @@ ij_java_align_multiline_annotation_parameters = true
|
||||
ij_java_align_multiline_array_initializer_expression = true
|
||||
ij_java_align_multiline_assignment = true
|
||||
ij_java_align_multiline_binary_operation = true
|
||||
ij_java_align_multiline_chained_methods = true
|
||||
ij_java_align_multiline_chained_methods = false
|
||||
ij_java_align_multiline_extends_list = true
|
||||
ij_java_align_multiline_for = true
|
||||
ij_java_align_multiline_method_parentheses = true
|
||||
ij_java_align_multiline_method_parentheses = false
|
||||
ij_java_align_multiline_parameters = true
|
||||
ij_java_align_multiline_parameters_in_calls = true
|
||||
ij_java_align_multiline_parameters_in_calls = false
|
||||
ij_java_align_multiline_parenthesized_expression = true
|
||||
ij_java_align_multiline_records = true
|
||||
ij_java_align_multiline_resources = true
|
||||
@@ -127,7 +127,7 @@ ij_java_keep_blank_lines_in_declarations = 2
|
||||
ij_java_keep_builder_methods_indents = true
|
||||
ij_java_keep_control_statement_in_one_line = true
|
||||
ij_java_keep_first_column_comment = false
|
||||
ij_java_keep_indents_on_empty_lines = true
|
||||
ij_java_keep_indents_on_empty_lines = false
|
||||
ij_java_keep_line_breaks = true
|
||||
ij_java_keep_multiple_expressions_in_one_line = false
|
||||
ij_java_keep_simple_blocks_in_one_line = true
|
||||
@@ -577,14 +577,14 @@ ij_properties_keep_blank_lines = false
|
||||
ij_properties_key_value_delimiter = equals
|
||||
ij_properties_spaces_around_key_value_delimiter = false
|
||||
|
||||
[{*.yaml, *.yml}]
|
||||
[{*.yml, *.yaml}]
|
||||
indent_size = 2
|
||||
ij_visual_guides = none
|
||||
ij_yaml_align_values_properties = do_not_align
|
||||
ij_yaml_autoinsert_sequence_marker = true
|
||||
ij_yaml_block_mapping_on_new_line = false
|
||||
ij_yaml_indent_sequence_value = true
|
||||
ij_yaml_keep_indents_on_empty_lines = true
|
||||
ij_yaml_keep_indents_on_empty_lines = false
|
||||
ij_yaml_keep_line_breaks = true
|
||||
ij_yaml_sequence_on_new_line = false
|
||||
ij_yaml_space_before_colon = false
|
||||
|
||||
@@ -43,7 +43,7 @@ assignees: ""
|
||||
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/TerraDefaultConfig/issues/new -->
|
||||
<!-- 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 filled out and provided all the appropriate information.
|
||||
|
||||
@@ -51,13 +51,13 @@ assignees: ""
|
||||
|
||||
<!-- You can fill out the different items by putting the correct value beside each cell. -->
|
||||
|
||||
| Name | Value |
|
||||
|------------------------------|-------|
|
||||
| Terra Version | <!-- Put your Terra version here. (remove the comment) -->
|
||||
| Platform / Platform Version | <!-- Put your platform and platform version here. (remove the comment) (eg. Spigot, Fabric, Paper, etc.) (If you are using the Region generator, put that here instead) -->
|
||||
| Any External Plugins or Mods | <!-- Put a list of all the plugins or mods you have installed here. (remove the comment) (Make sure to NOT include any new lines) -->
|
||||
| Terra Packs In Use | <!-- Put a list of all the Terra packs you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te packs may be used to get a list) -->
|
||||
| Terra Addons In Use | <!-- Put a list of all the Terra addons you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te addons may be used to get a list) -->
|
||||
| Name | Value |
|
||||
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Terra Version | <!-- Put your Terra version here. (remove the comment) -->
|
||||
| Platform / Platform Version | <!-- Put your platform and platform version here. (remove the comment) (eg. Spigot, Fabric, Paper, etc.) (If you are using the Region generator, put that here instead) -->
|
||||
| Any External Plugins or Mods | <!-- Put a list of all the plugins or mods you have installed here. (remove the comment) (Make sure to NOT include any new lines) -->
|
||||
| Terra Packs In Use | <!-- Put a list of all the Terra packs you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te packs may be used to get a list) -->
|
||||
| Terra Addons In Use | <!-- Put a list of all the Terra addons you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te addons may be used to get a list) -->
|
||||
|
||||
## Issue Description
|
||||
|
||||
|
||||
@@ -1,58 +1,19 @@
|
||||
# Pull Request
|
||||
|
||||
## Brief description.
|
||||
## Description
|
||||
|
||||
<!-- Please provide a brief description of the goals of your PR -->
|
||||
<!-- Include a description of the PR here -->
|
||||
|
||||
<!--
|
||||
###########################################################################
|
||||
## WARNING! ##
|
||||
## IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN YOUR PR BEING CLOSED ##
|
||||
###########################################################################
|
||||
-->
|
||||
<!--
|
||||
Please go through this checklist item by item and make sure you have successfully completed each of these steps.
|
||||
- Your pull request MUST be either on the latest version of Terra, or on a branch for a future release.
|
||||
- Make sure that there are no already existing PRs that fix this. If so, it will be closed as a duplicate.
|
||||
- Make sure that this change is actually within the scope of Terra and is something a terrain generator should be doing.
|
||||
- Make sure that this is not an issue with a specific Terra *pack*, and instead applies to all of Terra.
|
||||
- Make sure that you have filled out all the required information and given descriptions of everything.
|
||||
-->
|
||||
<!-- You can erase any parts of this template not applicable to your Pull Request. -->
|
||||
|
||||
### What Issues Does This Fix?
|
||||
|
||||
<!--
|
||||
Put Fix #XXXX or Closes #XXXX here if there are any open issues that this PR fixes.
|
||||
This is to automatically close the relevant issues.
|
||||
You may remove this if there is no issue for this PR.
|
||||
But unless this is a very small change, you should make an issue for it.
|
||||
If applicable, include 'Fixes #XXXX' or 'Closes #XXXX' for any related open issues.
|
||||
This helps us relate, track, and close the relevant issues.
|
||||
-->
|
||||
|
||||
## Licensing
|
||||
|
||||
<!-- 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 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.
|
||||
NOTE: for compatible licenses, you must make sure to add the included license somewhere in the program, if so required.
|
||||
(And even if it's not required, it's still nice to do it. Also add attribution somewhere.)
|
||||
-->
|
||||
|
||||
## Goal of the PR
|
||||
### Changelog
|
||||
|
||||
<!--
|
||||
What is the goal of the PR?
|
||||
Put a checklist here of what has been done
|
||||
(and what *hasn't*, but you plan to do),
|
||||
so we can easily know what was changed.
|
||||
Note: this is only required for PRs that add new features.
|
||||
If your PR is not adding new features, only fixing bugs or adding translations, then you may delete this section.
|
||||
Fill out a changelog below of what has been done, and what might be planned to be done.
|
||||
You may delete this if your PR is not adding new features, only fixing bugs or adding translations.
|
||||
-->
|
||||
|
||||
- [ ] <!-- First thing -->
|
||||
@@ -61,51 +22,58 @@
|
||||
- [ ] <!-- Second thing -->
|
||||
- [ ] <!-- etc. -->
|
||||
|
||||
## Affects of the PR
|
||||
## Checklist
|
||||
|
||||
<!---
|
||||
What types of changes does your code introduce? (Select any that apply. You may select multiple.)
|
||||
You must put an x in all the boxes that it applies to. (Like this: [x])
|
||||
<!--
|
||||
Select the options below that apply.
|
||||
You must put an x in all the boxes that it applies to. (Like this: [x])
|
||||
-->
|
||||
|
||||
#### Mandatory checks
|
||||
|
||||
- [ ] The base branch of this PR is an unreleased version branch (that has a `ver/` prefix)
|
||||
or is a branch that is intended to be merged into a version branch.
|
||||
<!--
|
||||
This is not applicable if the PR is a version branch itself.
|
||||
PRs for new versions should use the `master` branch instead.
|
||||
-->
|
||||
- [ ] There are no already existing PRs that provide the same changes.
|
||||
<!-- If this is not applicable, the PR will be removed as a duplicate. -->
|
||||
- [ ] The PR is within the scope of Terra (i.e. is something a configurable terrain generator should be doing).
|
||||
- [ ] Changes follow 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. -->
|
||||
- [ ] I have read the [`CONTRIBUTING.md`](https://github.com/PolyhedralDev/Terra/blob/master/CONTRIBUTING.md)
|
||||
document in the root of the git repository.
|
||||
|
||||
#### Types of changes
|
||||
|
||||
- [ ] Bug Fix <!-- Anything which fixes an issue in Terra. -->
|
||||
- [ ] Build system <!-- Anything which pretain to the build system. -->
|
||||
- [ ]
|
||||
Documentation <!-- Anything which adds or improves documentation for existing features. -->
|
||||
- [ ] New Feature <!-- Anything which adds new functionality to Terra. -->
|
||||
- [ ] Performance <!-- Anything which is imrpoves the performance of Terra. -->
|
||||
- [ ]
|
||||
Refactoring <!-- Anything which does not add any new code, only moves code around. -->
|
||||
- [ ]
|
||||
Repository <!-- Anything which affects the repository. Eg. changes to the `README.md` file. -->
|
||||
- [ ] Revert <!-- Anything which reverts previous commits. -->
|
||||
- [ ] Style <!-- Anything which updates style. -->
|
||||
- [ ] Tests <!-- Anything which adds or updates tests. -->
|
||||
- [ ]
|
||||
Translation <!-- Anything which is internationalizing the Terra program to other languages. -->
|
||||
- [ ] Bug Fix <!-- Changes include bug fixes. -->
|
||||
- [ ] Build system <!-- Changes the build system. -->
|
||||
- [ ] Documentation <!-- Changes add to or improve documentation. -->
|
||||
- [ ] New Feature <!-- Changes add new functionality to Terra. -->
|
||||
- [ ] Performance <!-- Changes improve the performance of Terra. -->
|
||||
- [ ] Refactoring <!-- Changes do not add any new code, only moves code around. -->
|
||||
- [ ] Repository <!-- Changes affect the repository. E.g. changes to the `README.md` file. -->
|
||||
- [ ] Revert <!-- Changes revert previous commits. -->
|
||||
- [ ] Style <!-- Changes update style, namely the .editorconfig file. -->
|
||||
- [ ] Tests <!-- Changes add or update tests. -->
|
||||
- [ ] Translation <!-- Changes include translations to other languages for Terra. -->
|
||||
|
||||
#### Compatiblity
|
||||
#### Compatibility
|
||||
|
||||
- [ ] Breaking
|
||||
change <!-- A fix, or a feature, that breaks some previous functionality to Terra. -->
|
||||
- [ ] Non-Breaking change.
|
||||
<!--
|
||||
A change which does not break *any* previous functionality of Terra.
|
||||
(ie. is backwards compatible and will work with *any* previously existing supported features.
|
||||
Note: if a feature is annotated with @Incubating, @Preview, @Experimental,
|
||||
or is in a package called something similar to the previous annotations,
|
||||
then you may push breaking changes to only THOSE parts of Terra.)
|
||||
-->
|
||||
<!-- The following options determine if the PR pertains to a major, minor, or patch version bump -->
|
||||
|
||||
#### Contribution Guidelines.
|
||||
|
||||
- [ ] I have read
|
||||
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
|
||||
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. -->
|
||||
- [ ] Introduces a breaking change
|
||||
<!--
|
||||
Breaking changes are any fix or feature that breaks some previous functionality to Terra / is not backwards compatible.
|
||||
Breaking changes do not include:
|
||||
- changes that are backwards compatible and will work with *any* previously existing supported features.
|
||||
- changes to code marked as in a pre-release
|
||||
state (annotated with @Incubating, @Preview, @Experimental
|
||||
or in a package called something similar to the previous annotations)
|
||||
-->
|
||||
- [ ] Introduces new functionality in a backwards compatible way.
|
||||
- [ ] Introduces bug fixes
|
||||
|
||||
#### Documentation
|
||||
|
||||
@@ -116,7 +84,21 @@
|
||||
|
||||
- [ ] I have added tests to cover my changes.
|
||||
- [ ] All new and existing tests passed.
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!--
|
||||
Tests are typically not necessary for small changes.
|
||||
Including *some* testing is recommended for large changes where applicable.
|
||||
-->
|
||||
|
||||
#### Licensing
|
||||
|
||||
<!-- 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 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.
|
||||
NOTE: for compatible licenses, you must make sure to add the included license somewhere in the program, if so required.
|
||||
(And even if it's not required, it's still nice to do it. Also add attribution somewhere.)
|
||||
-->
|
||||
|
||||
+4
-1
@@ -245,4 +245,7 @@ nbdist/
|
||||
|
||||
/run/
|
||||
|
||||
**/testDir/
|
||||
**/testDir/
|
||||
|
||||
platforms/**/run/**
|
||||
|
||||
|
||||
+14
-34
@@ -315,19 +315,15 @@ Terra has a global moderation team which is currently comprised of the following
|
||||
members:
|
||||
|
||||
- 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)
|
||||
-
|
||||
email: [solonovamax@12oclockpoint.com](mailto:solonovamax@12oclockpoint.com)
|
||||
- email: [solonovamax@12oclockpoint.com](mailto:solonovamax@12oclockpoint.com)
|
||||
- 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)
|
||||
- email: [dfsek@protonmail.com](mailto:dfsek@protonmail.com)
|
||||
- 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)
|
||||
- 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
|
||||
|
||||
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
|
||||
[Mozilla's Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/)
|
||||
, which were adapted from:
|
||||
These guidelines have been adapted with modifications from the following sources:
|
||||
|
||||
- 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)
|
||||
-
|
||||
|
||||
Mozilla's [View Source Conference Code of Conduct](https://viewsourceconf.org/berlin-2016/code-of-conduct/)
|
||||
|
||||
- And
|
||||
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.
|
||||
- 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)
|
||||
- The [Stumptown Syndicate's Citizen Code of Conduct](http://citizencodeofconduct.org/)
|
||||
- The [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html)
|
||||
- The [WisCon code of conduct](http://wiscon.net/policies/anti-harassment/code-of-conduct/)
|
||||
|
||||
## Notes
|
||||
|
||||
@@ -443,7 +424,6 @@ people are not comfortable
|
||||
using [neopronouns](https://www.mypronouns.org/neopronouns). But if someone
|
||||
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 '
|
||||
acab/acabself', 'that/bitch', 'ur/mom', or
|
||||
'dream/dreamself' (pronouns related to real people, eg. the minecraft youtuber '
|
||||
dreamwastaken'). Doing so will be considered mockery of individuals who use
|
||||
acab/acabself', 'that/bitch', 'ur/mom', or anything else that may be considered
|
||||
disrectful. Doing so will be considered mockery of individuals who use
|
||||
non-standard pronouns and is very disrespectful.
|
||||
+5
-2
@@ -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!!!
|
||||
|
||||
> **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
|
||||
|
||||
@@ -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)
|
||||
.
|
||||
|
||||
> **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
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2021 Polyhedral Development
|
||||
Copyright (c) 2020-2023 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
|
||||
|
||||
@@ -47,14 +47,7 @@ JARs are produced in `platforms/<platform>/build/libs`.
|
||||
To run Minecraft with Terra in the IDE (for testing) use the following tasks:
|
||||
|
||||
* Bukkit
|
||||
* `installPaper` - Install a [Paper](https://github.com/PaperMC/Paper) test
|
||||
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).
|
||||
* `runServer` - Run the Paper test server with Terra installed.
|
||||
* Fabric
|
||||
* `runClient` - Run a Minecraft Fabric client with Terra installed.
|
||||
* `runServer` - Run a Minecraft Fabric server with Terra installed.
|
||||
|
||||
+13
-12
@@ -1,38 +1,38 @@
|
||||
preRelease(true)
|
||||
|
||||
versionProjects(":common:api", version("6.0.0"))
|
||||
versionProjects(":common:implementation", version("6.0.0"))
|
||||
versionProjects(":platforms", version("6.0.0"))
|
||||
versionProjects(":common:api", version("6.5.0"))
|
||||
versionProjects(":common:implementation", version("6.5.0"))
|
||||
versionProjects(":platforms", version("6.5.0"))
|
||||
|
||||
|
||||
allprojects {
|
||||
group = "com.dfsek.terra"
|
||||
|
||||
|
||||
configureCompilation()
|
||||
configureDependencies()
|
||||
configurePublishing()
|
||||
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.isFork = true
|
||||
options.isIncremental = true
|
||||
}
|
||||
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
|
||||
|
||||
maxHeapSize = "2G"
|
||||
ignoreFailures = false
|
||||
failFast = true
|
||||
maxParallelForks = (Runtime.getRuntime().availableProcessors() - 1).takeIf { it > 0 } ?: 1
|
||||
|
||||
|
||||
reports.html.required.set(false)
|
||||
reports.junitXml.required.set(false)
|
||||
}
|
||||
|
||||
|
||||
tasks.withType<Copy>().configureEach {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
|
||||
tasks.withType<Jar>().configureEach {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
@@ -42,13 +42,14 @@ afterEvaluate {
|
||||
forImmediateSubProjects(":platforms") {
|
||||
configureDistribution()
|
||||
}
|
||||
project(":platforms:bukkit:common").configureDistribution()
|
||||
forSubProjects(":common:addons") {
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
|
||||
|
||||
tasks.named("build") {
|
||||
finalizedBy(tasks.named("shadowJar"))
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
"compileOnly"(project(":common:api"))
|
||||
"testImplementation"(project(":common:api"))
|
||||
|
||||
@@ -6,13 +6,21 @@ plugins {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
||||
maven("https://repo.codemc.org/repository/maven-public") {
|
||||
name = "CodeMC"
|
||||
}
|
||||
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||
name = "PaperMC"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:+")
|
||||
implementation("org.ow2.asm:asm:9.2")
|
||||
implementation("org.ow2.asm:asm-tree:9.2")
|
||||
implementation("com.dfsek.tectonic:common:4.2.0")
|
||||
implementation("org.yaml:snakeyaml:1.27")
|
||||
//TODO Allow pulling from Versions.kt
|
||||
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")
|
||||
}
|
||||
@@ -3,7 +3,6 @@ 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 org.gradle.kotlin.dsl.extra
|
||||
import kotlin.streams.asStream
|
||||
|
||||
@@ -12,27 +11,33 @@ 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()
|
||||
}
|
||||
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)
|
||||
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> {
|
||||
|
||||
@@ -30,10 +30,27 @@ fun Project.configureDependencies() {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.fabricmc.net/")
|
||||
maven("https://repo.codemc.org/repository/maven-public")
|
||||
maven("https://repo.codemc.io/repository/nms/")
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
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 {
|
||||
@@ -44,4 +61,4 @@ fun Project.configureDependencies() {
|
||||
compileOnly("com.google.guava:guava:30.0-jre")
|
||||
testImplementation("com.google.guava:guava:30.0-jre")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import io.papermc.paperweight.util.path
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.net.URL
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.BasePluginExtension
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
@@ -16,6 +14,11 @@ import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.yaml.snakeyaml.DumperOptions
|
||||
import org.yaml.snakeyaml.Yaml
|
||||
import kotlin.io.path.copyTo
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.createFile
|
||||
import kotlin.io.path.exists
|
||||
|
||||
|
||||
fun Project.configureDistribution() {
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
@@ -29,33 +32,38 @@ fun Project.configureDistribution() {
|
||||
}
|
||||
}
|
||||
|
||||
val installAddons = tasks.create("installAddons") {
|
||||
group = "terra"
|
||||
val compileAddons = tasks.create("compileAddons") {
|
||||
forSubProjects(":common:addons") {
|
||||
afterEvaluate {
|
||||
dependsOn(getJarTask())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installAddons = tasks.create("installAddons") {
|
||||
group = "terra"
|
||||
dependsOn(compileAddons)
|
||||
|
||||
doLast {
|
||||
// https://github.com/johnrengelman/shadow/issues/111
|
||||
val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().asFile.toPath()
|
||||
val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().path
|
||||
|
||||
|
||||
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
|
||||
forSubProjects(":common:addons") {
|
||||
val jar = getJarTask()
|
||||
|
||||
|
||||
println("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB")
|
||||
|
||||
|
||||
val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else ""
|
||||
val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}");
|
||||
|
||||
if(!Files.exists(addonPath)) {
|
||||
Files.createDirectories(addonPath.parent)
|
||||
Files.createFile(addonPath)
|
||||
Files.copy(jar.archiveFile.get().asFile.toPath(), addonPath, StandardCopyOption.REPLACE_EXISTING)
|
||||
val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}")
|
||||
|
||||
if (!addonPath.exists()) {
|
||||
addonPath.parent.createDirectories()
|
||||
addonPath.createFile()
|
||||
jar.archiveFile.get().asFile.toPath().copyTo(addonPath, overwrite = true)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +71,6 @@ fun Project.configureDistribution() {
|
||||
|
||||
val generateResourceManifest = tasks.create("generateResourceManifest") {
|
||||
group = "terra"
|
||||
dependsOn(downloadDefaultPacks)
|
||||
doLast {
|
||||
val resources = HashMap<String, MutableList<String>>()
|
||||
val packsDir = File("${project.buildDir}/resources/main/packs/")
|
||||
@@ -101,12 +108,20 @@ fun Project.configureDistribution() {
|
||||
val manifest = File("${project.buildDir}/resources/main/resources.yml")
|
||||
|
||||
if (manifest.exists()) manifest.delete()
|
||||
manifest.parentFile.mkdirs()
|
||||
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") {
|
||||
@@ -114,13 +129,13 @@ fun Project.configureDistribution() {
|
||||
dependsOn(downloadDefaultPacks)
|
||||
configurations = listOf(project.configurations["shaded"])
|
||||
archiveClassifier.set("shaded")
|
||||
setVersion(project.version)
|
||||
version = project.version
|
||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||
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.yaml", "com.dfsek.terra.lib.yaml")
|
||||
|
||||
|
||||
finalizedBy(installAddons)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,71 @@
|
||||
object Versions {
|
||||
object Libraries {
|
||||
const val tectonic = "4.2.0"
|
||||
const val paralithic = "0.7.0"
|
||||
const val strata = "1.1.1"
|
||||
const val tectonic = "4.2.1"
|
||||
const val paralithic = "0.7.1"
|
||||
const val strata = "1.3.2"
|
||||
|
||||
const val cloud = "1.6.2"
|
||||
const val cloud = "1.8.4"
|
||||
|
||||
const val slf4j = "1.7.36"
|
||||
const val log4j_slf4j_impl = "2.14.1"
|
||||
const val slf4j = "2.0.9"
|
||||
const val log4j_slf4j_impl = "2.20.0"
|
||||
|
||||
object Internal {
|
||||
const val apacheText = "1.9"
|
||||
const val jafama = "2.3.2"
|
||||
const val apacheIO = "2.6"
|
||||
const val fastutil = "8.5.6"
|
||||
const val shadow = "8.1.1"
|
||||
const val apacheText = "1.10.0"
|
||||
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 fabricLoader = "0.14.2"
|
||||
const val fabricAPI = "0.53.4+1.18.2"
|
||||
const val minecraft = "1.18.2"
|
||||
const val yarn = "$minecraft+build.3"
|
||||
const val permissionsAPI = "0.1-SNAPSHOT"
|
||||
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-R0.1-SNAPSHOT"
|
||||
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 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,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2021 Polyhedral Development
|
||||
Copyright (c) 2020-2023 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
|
||||
|
||||
+3
-3
@@ -8,17 +8,17 @@ 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;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -15,7 +15,7 @@ public class ApiAddonClassLoader extends URLClassLoader {
|
||||
static {
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
|
||||
public ApiAddonClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -20,18 +20,18 @@ 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;
|
||||
|
||||
@@ -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 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;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* 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-2023 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,8 @@
|
||||
version = version("1.0.1")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
compileOnlyApi(project(":common:addons:library-image"))
|
||||
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 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.terra.addons.image.colorsampler.ColorSampler;
|
||||
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 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-2023 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.colorsampler.ColorSampler;
|
||||
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||
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.+"
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2021 Polyhedral Development
|
||||
Copyright (c) 2020-2023 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
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
version = version("1.0.0")
|
||||
version = version("1.0.1")
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+28
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -7,12 +7,11 @@
|
||||
|
||||
package com.dfsek.terra.addons.biome.image;
|
||||
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
@@ -24,53 +23,62 @@ public class ImageBiomeProvider implements BiomeProvider {
|
||||
private final BufferedImage image;
|
||||
private final int resolution;
|
||||
private final Align align;
|
||||
|
||||
|
||||
public ImageBiomeProvider(Set<Biome> registry, BufferedImage image, int resolution, Align align) {
|
||||
this.image = image;
|
||||
this.resolution = resolution;
|
||||
this.align = align;
|
||||
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
|
||||
}
|
||||
|
||||
|
||||
private static int distance(Color a, Color b) {
|
||||
return FastMath.abs(a.getRed() - b.getRed()) + FastMath.abs(a.getGreen() - b.getGreen()) + FastMath.abs(a.getBlue() - b.getBlue());
|
||||
return Math.abs(a.getRed() - b.getRed()) + Math.abs(a.getGreen() - b.getGreen()) + Math.abs(a.getBlue() - b.getBlue());
|
||||
}
|
||||
|
||||
|
||||
@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;
|
||||
Color color = align.getColor(image, x, z);
|
||||
return colorBiomeMap.get(colorBiomeMap.keySet()
|
||||
.stream()
|
||||
.reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new),
|
||||
(running, element) -> {
|
||||
int d1 = distance(color, running);
|
||||
int d2 = distance(color, element);
|
||||
return d1 < d2 ? running : element;
|
||||
}));
|
||||
.stream()
|
||||
.reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new),
|
||||
(running, element) -> {
|
||||
int d1 = distance(color, running);
|
||||
int d2 = distance(color, element);
|
||||
return d1 < d2 ? running : element;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@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 {
|
||||
CENTER {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()),
|
||||
FastMath.floorMod(z - image.getHeight() / 2, image.getHeight())));
|
||||
return new Color(image.getRGB(Math.floorMod(x - image.getWidth() / 2, image.getWidth()),
|
||||
Math.floorMod(z - image.getHeight() / 2, image.getHeight())));
|
||||
}
|
||||
},
|
||||
NONE {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(FastMath.floorMod(x, image.getWidth()), FastMath.floorMod(z, image.getHeight())));
|
||||
return new Color(image.getRGB(Math.floorMod(x, image.getWidth()), Math.floorMod(z, image.getHeight())));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public abstract Color getColor(BufferedImage image, int x, int z);
|
||||
}
|
||||
}
|
||||
|
||||
+20
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -8,6 +8,8 @@
|
||||
package com.dfsek.terra.addons.biome.image;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -24,26 +26,31 @@ 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<>() {
|
||||
};
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
|
||||
@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("IMAGE"),
|
||||
() -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
|
||||
})
|
||||
.failThrough();
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||
PROVIDER_REGISTRY_KEY);
|
||||
providerRegistry.register(addon.key("IMAGE"),
|
||||
() -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
|
||||
})
|
||||
.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.");
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -33,11 +33,11 @@ public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
@Value("image.align")
|
||||
@Description("Sets the alignment style to use for the image.")
|
||||
private ImageBiomeProvider.Align align;
|
||||
|
||||
|
||||
public ImageProviderTemplate(Registry<Biome> set) {
|
||||
this.biomes = set;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeProvider get() {
|
||||
return new ImageBiomeProvider(new HashSet<>(biomes.entries()), image, resolution, align);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 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,5 @@
|
||||
version = version("1.0.1")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 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.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.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.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.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
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.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.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 = Math.floorDiv(x, chunkSize);
|
||||
int chunkZ = Math.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.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
|
||||
|
||||
|
||||
/**
|
||||
* 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.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
|
||||
|
||||
|
||||
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 {
|
||||
static PipelineBiome placeholder(String id) {
|
||||
return new PlaceholderPipelineBiome(id);
|
||||
}
|
||||
|
||||
static PipelineBiome from(Biome biome) {
|
||||
return new DelegatedPipelineBiome(biome);
|
||||
}
|
||||
|
||||
static PipelineBiome self() {
|
||||
return SelfPipelineBiome.INSTANCE;
|
||||
}
|
||||
|
||||
Biome getBiome();
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 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.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.PipelineImpl;
|
||||
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("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;
|
||||
@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;
|
||||
|
||||
@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-2023 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-2023 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-2023 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-2023 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.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
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-2023 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.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
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-2023 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.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
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-2023 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.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
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-2023 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.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
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-2023 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.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.SmoothStage;
|
||||
|
||||
|
||||
public class SmoothStageTemplate extends StageTemplate {
|
||||
@Override
|
||||
public Stage get() {
|
||||
return new SmoothStage(noise);
|
||||
}
|
||||
}
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline;
|
||||
|
||||
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.SeededVector;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
public class BiomeChunkImpl implements BiomeChunk {
|
||||
|
||||
private final SeededVector worldOrigin;
|
||||
private final int chunkOriginArrayIndex;
|
||||
private final int worldCoordinateScale;
|
||||
private PipelineBiome[][] biomes;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (int) Math.ceil((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);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
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.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 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-2023 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-2023 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-2023 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;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 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.Objects;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public class SmoothStage implements Stage {
|
||||
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
public SmoothStage(NoiseSampler sampler) {
|
||||
this.sampler = sampler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
|
||||
PipelineBiome top = viewPoint.getRelativeBiome(1, 0);
|
||||
PipelineBiome bottom = viewPoint.getRelativeBiome(-1, 0);
|
||||
PipelineBiome left = viewPoint.getRelativeBiome(0, 1);
|
||||
PipelineBiome right = viewPoint.getRelativeBiome(0, -1);
|
||||
|
||||
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
|
||||
|
||||
boolean vert = Objects.equals(top, bottom);
|
||||
boolean horiz = Objects.equals(left, right);
|
||||
|
||||
if(vert && horiz) {
|
||||
return roll > 0 ?
|
||||
roll > 0.25 ? left : right :
|
||||
roll > -0.25 ? top : bottom;
|
||||
}
|
||||
if(vert) {
|
||||
return roll > 0 ? top : bottom;
|
||||
}
|
||||
if(horiz) {
|
||||
return roll > 0 ? left : right;
|
||||
}
|
||||
return viewPoint.getBiome();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxRelativeReadDistance() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
schema-version: 1
|
||||
contributors:
|
||||
- Terra contributors
|
||||
id: biome-provider-pipeline-v2
|
||||
version: @VERSION@
|
||||
entrypoints:
|
||||
- "com.dfsek.terra.addons.biome.pipeline.v2.BiomePipelineAddon"
|
||||
website:
|
||||
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||
source: https://github.com/PolyhedralDev/Terra
|
||||
docs: https://terra.polydev.org
|
||||
license: MIT License
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2021 Polyhedral Development
|
||||
Copyright (c) 2020-2023 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
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
version = version("1.0.0")
|
||||
version = version("1.0.2")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
implementation("com.github.ben-manes.caffeine:caffeine:3.1.0")
|
||||
|
||||
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("com.github.benmanes.caffeine", "com.dfsek.terra.addons.biome.pipeline.lib.caffeine")
|
||||
relocate("net.jafama", "com.dfsek.terra.addons.biome.pipeline.lib.jafama")
|
||||
}
|
||||
+13
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -20,7 +20,7 @@ public class BiomeHolderImpl implements BiomeHolder {
|
||||
private final int width;
|
||||
private final int offset;
|
||||
private BiomeDelegate[][] biomes;
|
||||
|
||||
|
||||
public BiomeHolderImpl(int width, Vector2.Mutable origin) {
|
||||
width += 4;
|
||||
this.width = width;
|
||||
@@ -28,38 +28,38 @@ public class BiomeHolderImpl implements BiomeHolder {
|
||||
this.origin = origin;
|
||||
this.offset = 2;
|
||||
}
|
||||
|
||||
|
||||
private BiomeHolderImpl(BiomeDelegate[][] biomes, Vector2.Mutable origin, int width, int offset) {
|
||||
this.biomes = biomes;
|
||||
this.origin = origin;
|
||||
this.width = width;
|
||||
this.offset = 2 * offset;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeHolder expand(BiomeExpander expander, long seed) {
|
||||
BiomeDelegate[][] old = biomes;
|
||||
int newWidth = width * 2 - 1;
|
||||
|
||||
|
||||
biomes = new BiomeDelegate[newWidth][newWidth];
|
||||
|
||||
|
||||
for(int x = 0; x < width; x++) {
|
||||
for(int z = 0; z < width; z++) {
|
||||
biomes[x * 2][z * 2] = old[x][z];
|
||||
if(z != width - 1)
|
||||
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
|
||||
old[x][z + 1]);
|
||||
old[x][z + 1]);
|
||||
if(x != width - 1)
|
||||
biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), seed, old[x][z],
|
||||
old[x + 1][z]);
|
||||
old[x + 1][z]);
|
||||
if(x != width - 1 && z != width - 1)
|
||||
biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(x + 1 + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
|
||||
old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
|
||||
old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
|
||||
}
|
||||
}
|
||||
return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mutate(BiomeMutator mutator, long seed) {
|
||||
for(int x = 0; x < width; x++) {
|
||||
@@ -69,7 +69,7 @@ public class BiomeHolderImpl implements BiomeHolder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void fill(BiomeSource source, long seed) {
|
||||
for(int x = 0; x < width; x++) {
|
||||
@@ -78,14 +78,14 @@ public class BiomeHolderImpl implements BiomeHolder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeDelegate getBiome(int x, int z) {
|
||||
x += offset;
|
||||
z += offset;
|
||||
return getBiomeRaw(x, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeDelegate getBiomeRaw(int x, int z) {
|
||||
if(x >= width || z >= width || x < 0 || z < 0) return null;
|
||||
|
||||
+11
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -22,14 +22,14 @@ public class BiomePipeline {
|
||||
private final List<Stage> stages;
|
||||
private final int size;
|
||||
private final int init;
|
||||
|
||||
|
||||
private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) {
|
||||
this.source = source;
|
||||
this.stages = stages;
|
||||
this.size = size;
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get biomes in a chunk
|
||||
*
|
||||
@@ -44,37 +44,37 @@ public class BiomePipeline {
|
||||
for(Stage stage : stages) holder = stage.apply(holder, seed);
|
||||
return holder;
|
||||
}
|
||||
|
||||
|
||||
public BiomeSource getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
public List<Stage> getStages() {
|
||||
return Collections.unmodifiableList(stages);
|
||||
}
|
||||
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
public static final class BiomePipelineBuilder {
|
||||
private final int init;
|
||||
private final List<Stage> stages = new ArrayList<>();
|
||||
private int expand;
|
||||
|
||||
|
||||
public BiomePipelineBuilder(int init) {
|
||||
this.init = init;
|
||||
expand = init;
|
||||
}
|
||||
|
||||
|
||||
public BiomePipeline build(BiomeSource source) {
|
||||
for(Stage stage : stages) {
|
||||
if(stage.isExpansion()) expand = expand * 2 - 1;
|
||||
}
|
||||
|
||||
|
||||
return new BiomePipeline(source, stages, expand, init);
|
||||
}
|
||||
|
||||
|
||||
public BiomePipelineBuilder addStage(Stage stage) {
|
||||
stages.add(stage);
|
||||
return this;
|
||||
|
||||
+41
-34
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -8,6 +8,8 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -38,52 +40,57 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class BiomePipelineAddon implements AddonInitializer {
|
||||
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> 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<>() {
|
||||
};
|
||||
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
|
||||
@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<BiomeSource>>> 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"), SmoothMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE"), ReplaceMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER"), BorderMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER_LIST"), BorderListMutatorTemplate::new);
|
||||
})
|
||||
.failThrough();
|
||||
.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<BiomeSource>>> 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"), SmoothMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE"), ReplaceMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER"), BorderMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER_LIST"), BorderListMutatorTemplate::new);
|
||||
})
|
||||
.failThrough();
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPostLoadEvent.class)
|
||||
.then(event -> {
|
||||
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
|
||||
event.getPack().applyLoader(BiomeDelegate.class, new BiomeDelegateLoader(biomeRegistry));
|
||||
});
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPostLoadEvent.class)
|
||||
.then(event -> {
|
||||
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
|
||||
event.getPack().applyLoader(BiomeDelegate.class, new BiomeDelegateLoader(biomeRegistry));
|
||||
});
|
||||
|
||||
if(platform.getTerraConfig().isDebugLog())
|
||||
logger.warn(
|
||||
"The biome-provider-pipeline addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the" +
|
||||
" biome-provider-pipeline-v2 addon for future pack development instead.");
|
||||
}
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -9,10 +9,10 @@ package com.dfsek.terra.addons.biome.pipeline;
|
||||
|
||||
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;
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
|
||||
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;
|
||||
|
||||
@@ -31,18 +32,18 @@ public class BiomePipelineProvider implements BiomeProvider {
|
||||
private final int resolution;
|
||||
private final NoiseSampler mutator;
|
||||
private final double noiseAmp;
|
||||
|
||||
|
||||
private final Set<Biome> biomes;
|
||||
|
||||
|
||||
public BiomePipelineProvider(BiomePipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
|
||||
this.resolution = resolution;
|
||||
this.mutator = mutator;
|
||||
this.noiseAmp = noiseAmp;
|
||||
holderCache = Caffeine.newBuilder()
|
||||
.maximumSize(1024)
|
||||
.build(key -> pipeline.getBiomes(key.x, key.z, key.seed));
|
||||
.maximumSize(1024)
|
||||
.build(key -> pipeline.getBiomes(key.x, key.z, key.seed));
|
||||
this.pipeline = pipeline;
|
||||
|
||||
|
||||
Set<BiomeDelegate> biomeSet = new HashSet<>();
|
||||
pipeline.getSource().getBiomes().forEach(biomeSet::add);
|
||||
Iterable<BiomeDelegate> result = biomeSet;
|
||||
@@ -53,16 +54,16 @@ public class BiomePipelineProvider implements BiomeProvider {
|
||||
Iterable<BiomeDelegate> finalResult = result;
|
||||
result.forEach(biomeDelegate -> {
|
||||
if(biomeDelegate.isEphemeral()) {
|
||||
|
||||
|
||||
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'));
|
||||
.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 ephemeral biome \"" + biomeDelegate.getID() +
|
||||
"\". Ensure there is a stage to guarantee replacement of the ephemeral biome. Biomes: " +
|
||||
biomeList);
|
||||
@@ -70,28 +71,60 @@ public class BiomePipelineProvider implements BiomeProvider {
|
||||
this.biomes.add(biomeDelegate.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 = FastMath.floorToInt(FastMath.floorDiv(x, resolution));
|
||||
|
||||
z = FastMath.floorToInt(FastMath.floorDiv(z, resolution));
|
||||
|
||||
int fdX = FastMath.floorDiv(x, pipeline.getSize());
|
||||
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
||||
|
||||
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
|
||||
int fdX = Math.floorDiv(x, pipeline.getSize());
|
||||
int fdZ = Math.floorDiv(z, pipeline.getSize());
|
||||
return holderCache.get(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(),
|
||||
z - fdZ * pipeline.getSize()).getBiome();
|
||||
z - fdZ * pipeline.getSize()).getBiome();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||
return Optional.of(getBiome(x, z, seed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Biome> getBiomes() {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
private record SeededVector(int x, int z, long seed) {
|
||||
@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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -15,12 +15,12 @@ import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||
|
||||
public interface BiomeHolder {
|
||||
BiomeHolder expand(BiomeExpander expander, long seed);
|
||||
|
||||
|
||||
void mutate(BiomeMutator mutator, long seed);
|
||||
|
||||
|
||||
void fill(BiomeSource source, long seed);
|
||||
|
||||
|
||||
BiomeDelegate getBiome(int x, int z);
|
||||
|
||||
|
||||
BiomeDelegate getBiomeRaw(int x, int z);
|
||||
}
|
||||
|
||||
+8
-8
@@ -10,26 +10,26 @@ public interface BiomeDelegate extends StringIdentifiable {
|
||||
static BiomeDelegate ephemeral(String id) {
|
||||
return new EphemeralBiomeDelegate(id);
|
||||
}
|
||||
|
||||
|
||||
static BiomeDelegate from(Biome biome) {
|
||||
return new DelegatedBiome(biome);
|
||||
}
|
||||
|
||||
|
||||
static BiomeDelegate self() {
|
||||
return SelfDelegate.INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
Biome getBiome();
|
||||
|
||||
|
||||
Set<String> getTags();
|
||||
|
||||
|
||||
default boolean isEphemeral() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
default boolean isSelf() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+6
-6
@@ -7,32 +7,32 @@ import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
final class DelegatedBiome implements BiomeDelegate {
|
||||
private final Biome biome;
|
||||
|
||||
|
||||
public DelegatedBiome(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 DelegatedBiome that)) return false;
|
||||
return that.biome.equals(this.biome);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return biome.getTags();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return biome.getID();
|
||||
|
||||
+8
-8
@@ -9,43 +9,43 @@ import com.dfsek.terra.api.world.biome.Biome;
|
||||
final class EphemeralBiomeDelegate implements BiomeDelegate {
|
||||
private final Set<String> tags;
|
||||
private final String id;
|
||||
|
||||
|
||||
public EphemeralBiomeDelegate(String id) {
|
||||
this.id = id;
|
||||
tags = new HashSet<>();
|
||||
tags.add(id);
|
||||
tags.add("ALL");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
throw new UnsupportedOperationException("Cannot get biome from ephemeral delegate");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEphemeral() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof EphemeralBiomeDelegate that)) return false;
|
||||
|
||||
|
||||
return this.id.equals(that.id);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -8,31 +8,31 @@ import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
final class SelfDelegate implements BiomeDelegate {
|
||||
public static final SelfDelegate INSTANCE = new SelfDelegate();
|
||||
|
||||
|
||||
private SelfDelegate() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
throw new UnsupportedOperationException("Cannot get biome from self delegate");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSelf() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEphemeral() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "SELF";
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
* Copyright (c) 2020-2023 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.
|
||||
@@ -13,8 +13,8 @@ import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
|
||||
public interface Stage {
|
||||
BiomeHolder apply(BiomeHolder in, long seed);
|
||||
|
||||
|
||||
boolean isExpansion();
|
||||
|
||||
|
||||
Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user