Compare commits

...

112 Commits

Author SHA1 Message Date
Zoë Gidiere 734d4bfb94 reformat 2023-11-27 11:31:20 -07:00
Zoë Gidiere c82e015559 flatten array for pipeline biomes 2023-11-27 11:31:11 -07:00
Astrashh 3aef977384 Patch version 6.4.1 (#435)
* Bump version to 6.4.1

* fix fabric dev env

* Invert exposed ore logic (#433)

* Invert exposed ore logic

* Bump ore addon version

* Use logger in Gradle over println (#434)

* Log info instead of println in gradle scripts

* Missed buildSrc printlns

---------

Co-authored-by: Zoë <duplexsys@protonmail.com>
2023-11-25 01:02:45 +00:00
Zoë 6060ceae57 Merge pull request #432 from PolyhedralDev/dev/codeowners
update condeowners
2023-11-18 10:05:10 +00:00
Zoë Gidiere e499ddebd4 update condeowners 2023-11-17 13:34:56 -07:00
Zoë 4f706f5502 Merge pull request #430 from PolyhedralDev/ver/6.4.0
We've had one, yes. What about second build issue?
2023-11-17 19:12:52 +00:00
Zoë Gidiere fe954a7b2b We've had one, yes. What about second build issue? 2023-11-17 12:12:13 -07:00
Zoë 15e72bae35 Merge pull request #429 from PolyhedralDev/ver/6.4.0
fix building
2023-11-17 18:07:22 +00:00
Zoë Gidiere 513c2df9f9 fix building
for real this time
2023-11-17 11:06:41 -07:00
Zoë aec00d9169 Merge pull request #428 from PolyhedralDev/ver/6.4.0
Ver/6.4.0 2: Electric Boogaloo
2023-11-13 23:07:22 +00:00
Zoë Gidiere 540552d301 Partially Revert "Fix stupid build error and a couple gradle warnings"
This reverts commit 77812545df.
2023-11-13 15:22:09 -07:00
Zoë Gidiere 4dfe2054e9 Revert "Actually fix issue"
This reverts commit 0b1d67b533.
2023-11-13 15:21:17 -07:00
Zoë Gidiere 16e61098d9 depend on fabric api 2023-11-13 15:08:15 -07:00
Zoë Gidiere 8aecf6b97f don't include fabric api 2023-11-13 15:05:21 -07:00
Zoë Gidiere 4788483139 remove gc flags from build 2023-11-13 15:04:44 -07:00
Zoë 9e8aefe7f7 Merge pull request #420 from PolyhedralDev/ver/6.4.0
Terra Version 6.4.0
2023-11-13 04:55:02 +00:00
Zoë Gidiere 272556ed81 final reformat and import optimize 2023-11-12 21:45:47 -07:00
Zoë Gidiere fd0c4df04c Revert "add stub for not physics"
This reverts commit 839bc23a5a.
2023-11-12 21:18:27 -07:00
Astrashh 1c3ee86376 Simplify PR template (#427) 2023-11-13 00:57:27 +00:00
Astrashh defd775f13 Change Java whitespace handling in .editorconfig (#425)
* Change whitespace handling in .editorconfig

* Reformat code

* fix format error

* Reformat code

---------

Co-authored-by: Zoë Gidiere <duplexsys@protonmail.com>
2023-11-13 00:57:01 +00:00
Astrash a73fda7d04 Forgot @Meta 2023-11-13 11:48:06 +11:00
Astrash b8586135b8 Make RangeLoader inner class private
Also removes redundant suppression
2023-11-10 13:34:05 +11:00
Astrashh 4065cfea53 Fix YAML formatting (#426)
* Remove trailing whitespace in YAML formatting

* Reformat YAML files
2023-11-10 00:47:12 +00:00
Zoë Gidiere a117db40be change formatting 2023-11-09 12:47:48 -07:00
Zoë Gidiere 72e0974cc5 fix cli build 2023-11-09 11:40:19 -07:00
Zoë Gidiere d8938c5519 remove comments 2023-11-09 11:37:46 -07:00
Zoë Gidiere acf79f5c53 change class structure of LifecycleEntryPoint 2023-11-09 11:37:01 -07:00
Zoë Gidiere 839bc23a5a add stub for not physics 2023-11-09 11:29:09 -07:00
Zoë Gidiere 852cf0321b Merge remote-tracking branch 'origin/ver/6.4.0' into ver/6.4.0 2023-11-08 21:59:14 -07:00
Zoë Gidiere 89d497d500 Some requested changes 2023-11-08 21:58:57 -07:00
Zoë Gidiere 0df940d688 improve invSqrt formatting
Co-authored-by: solonovamax <solonovamax@12oclockpoint.com>

what the fuck?
2023-11-08 21:20:01 -07:00
Zoë Gidiere dd7bebb27f Update lerp usage and docs 2023-11-08 21:18:35 -07:00
solonovamax 72649d5cf7 Merge remote-tracking branch 'upstream/ver/6.4.0' into ver/6.4.0 2023-11-08 22:42:23 -05:00
solonovamax 7cf87de463 Add TODO to replace FoliaLib when we drop support for 1.18 and 1.19
Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
2023-11-08 22:42:14 -05:00
Zoë Gidiere 020033f839 add rsqrt ts function 2023-11-08 19:53:36 -07:00
Zoë Gidiere b3ef4ac79c optimized tan 2023-11-08 19:52:05 -07:00
solonovamax 3f9f2bdce4 Use kotlin's Path extensions rather than Files.whatever
Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
2023-11-08 20:38:25 -05:00
Zoë Gidiere 0ab463f34f bukkit clean up 2023-11-05 21:07:25 -07:00
Zoë Gidiere 0b1d67b533 Actually fix issue 2023-11-05 20:51:28 -07:00
Zoë Gidiere c4f665ffc5 fix format error 2023-11-05 20:13:04 -07:00
Zoë Gidiere c00753b0fc let reformat have another go at it 2023-11-05 20:12:57 -07:00
Zoë Gidiere 77812545df Fix stupid build error and a couple gradle warnings
thank you gradle .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } is clearly better than .capitalize()
2023-11-05 20:07:13 -07:00
Zoë Gidiere ad9bc7f67c fix format error 2023-11-02 18:47:45 -06:00
Zoë Gidiere 81a96d6b76 Reformat code 2023-11-02 18:47:36 -06:00
Zoë Gidiere d696e4fd24 Optimize imports 2023-11-02 18:45:13 -06:00
Zoë Gidiere c98d39c5d7 Update licence year 2023-11-02 18:42:51 -06:00
Zoë a6fe268f79 Merge pull request #422 from PolyhedralDev/dev/image-caching
Improve image caching
2023-11-03 00:10:52 +00:00
Zoë 648da95e7d Scattered ore (#424)
* Scattered Ore Impl

* remove break

* remove another break

* sphereCount -> blockCount

---------

Co-authored-by: Astrash <astrash@protonmail.com>
2023-10-29 17:33:50 -06:00
Zoë Gidiere 5829112a74 Merge branch 'ver/6.4.0' into dev/image-caching 2023-10-26 12:56:17 -06:00
Zoë Gidiere c41bf55b7b implement missing methods from last comit 2023-10-26 12:53:55 -06:00
Zoë Gidiere 5d12a560f1 add zero and unit vectors 2023-10-26 11:08:36 -06:00
Zoë Gidiere 6f08908bb4 merge ovre-v2 into ore(v1) 2023-10-26 10:43:13 -06:00
Zoë Gidiere 9292d3de17 Remove FastMath
hotspot has intrinsics for almost everything we use it for
2023-10-26 10:37:25 -06:00
Astrash 0149a29b04 Load correct path 2023-10-24 14:08:56 +11:00
Astrash cd8605850f Replace unload-on-timeout with timeout > 0 2023-10-24 13:47:25 +11:00
Astrash 148b8dfe35 Bump image lib patch version 2023-10-24 13:34:10 +11:00
Astrash 3f485b1825 Add to unload on timeout description 2023-10-24 13:30:09 +11:00
Astrash cb6ecff113 Remove sout 2023-10-24 13:29:53 +11:00
Astrash e30bcbf1ba Improve image caching options 2023-10-24 13:26:35 +11:00
Astrash 805f99f57a Make ore algorithm readable 2023-10-20 10:55:23 +11:00
Astrash 4e5b02ef42 Pass correct coords for ore block checks 2023-10-20 10:30:25 +11:00
Astrash e80e998cec Only log warnings with debug logging 2023-10-20 10:03:04 +11:00
Zoë fde29220af Merge pull request #419 from PolyhedralDev/dev/disable-quilt
Dev/disable quilt
2023-10-19 17:31:40 +00:00
Zoë Gidiere d3a9b57872 disable quilt 2023-10-18 19:53:59 -06:00
Zoë 4671ec5bd3 Merge pull request #417 from PolyhedralDev/dev/folia
Dev/folia
2023-10-19 01:18:45 +00:00
Zoë 9f4a8e06e1 Update DependencyConfig.kt 2023-10-17 21:00:28 -06:00
Zoë c8f2871aaa Update build.gradle.kts 2023-10-17 20:59:27 -06:00
Zoë 4a537a56aa Merge pull request #415 from PolyhedralDev/dev/ore-v2
Add updated ore-v2
2023-10-18 00:33:15 +00:00
Zoë 4917160123 Update README.md 2023-10-17 18:32:00 -06:00
Zoë b3f80dcb64 Merge pull request #410 from PolyhedralDev/dev/1.20.2
1.20.2 + update libs
2023-10-15 19:45:43 +00:00
Zoë Gidiere d49b9ccad5 Merge branch 'dev/1.20.2' into dev/folia 2023-10-14 16:02:54 -06:00
Zoë Gidiere a8387ce419 Merge remote-tracking branch 'origin/ver/6.4.0' into dev/1.20.2 2023-10-14 16:02:40 -06:00
Zoë Gidiere 94854f2bdb update versions 2023-10-14 15:55:43 -06:00
Astrashh 47f531089e Add slant locator (#413)
* Add slant locator addon

* Bump slant locator noise3d dependency version

* Fix slant locator dependency version range

* Actually fix slant locator dependency version range
2023-10-10 00:35:47 +00:00
Astrashh abd83e8278 Add number predicate addon (#412) 2023-10-10 00:35:26 +00:00
Astrash b5e7c7c112 Fix TOP locator 2023-10-10 09:44:53 +11:00
Zoë Gidiere d71f7d4c36 clarify value and change default 2023-10-03 21:03:44 -06:00
Zoë Gidiere 84898a7a6b fixes 2023-10-03 20:03:46 -06:00
Zoë Gidiere 0c1a6efc72 refractor classes 2023-10-03 19:42:15 -06:00
Zoë Gidiere 200281f140 dep orev1 2023-10-03 11:58:32 -06:00
Zoë Gidiere f1ea8074de config-ore-v2 2023-10-03 11:54:18 -06:00
Astrash f896a9a278 Bump noise3d addon minor version 2023-10-03 11:01:50 +11:00
Astrash 79b3b34669 Add slant API for noise3d 2023-10-03 09:51:39 +11:00
Zoë Gidiere ce2b964ce3 Merge branch 'dev/1.20.2' into dev/folia 2023-10-02 01:38:24 -06:00
Zoë Gidiere 0ee5f49972 quilt 2023-10-02 01:38:01 -06:00
Zoë Gidiere 3bc10cdb6a Merge branch 'dev/1.20.2' into dev/folia 2023-10-02 00:42:11 -06:00
Zoë Gidiere 86ba52850d update strata 2023-10-02 00:41:54 -06:00
Zoë Gidiere 27eebf6a47 Folia support
Co-authored-by: Janet Blackquill <uhhadd@gmail.com>
2023-10-02 00:23:19 -06:00
Zoë Gidiere 2d2bba20b6 found an untrue in read me 2023-10-01 23:22:44 -06:00
Zoë Gidiere eb3994005c fix me being fucking stupid 2023-10-01 22:46:41 -06:00
Zoë Gidiere 0a7cdb82a3 update deps + 1.20.2 2023-10-01 22:18:54 -06:00
Zoë 158deaa971 Merge pull request #408 from PolyhedralDev/dev/physics
Allows you to create a block with physics enabled
2023-10-01 19:07:15 -06:00
Astrash e51e025e9c Implement cubic spline sampler 2023-10-02 11:14:43 +11:00
Zoë Gidiere 8e0d64dccd Make bukkit work 2023-09-30 10:49:28 -06:00
Zoë Gidiere 23f47de10a fix pack loading error 2023-09-29 23:35:17 -06:00
Zoë Gidiere 89651597c2 default to info logging 2023-09-29 23:32:40 -06:00
Zoë 5c0c833b70 Update LifecycleEntryPoint.java 2023-09-29 23:09:41 -06:00
Zoë Gidiere 33d654dc8e impl fabric 2023-09-29 23:05:05 -06:00
Zoë Gidiere f0c602d7e7 implement physics on the api side
we will see if platform changes are needed
2023-09-29 22:10:03 -06:00
Zoë Gidiere 0e37a839fe We do a little commonifying 2023-09-29 21:44:12 -06:00
Astrash 3f9ead0d66 Remove repeated code in cellular sampler 2023-09-27 13:39:51 +10:00
David W 5eeb5af6c4 Add cell center offset return to CELLULAR sampler (#407)
* Add offset lookup return to cellular sampler

* bump noise function plugin version

* revert version to 1.1.0

* rename OffsetNoiseLookup, switch axis orientation

* rename return type aswell in cellcampler
2023-09-21 22:23:49 +00:00
Astrash 81e354f91c Use tectonic properly 2023-07-18 22:06:08 +10:00
Astrash aab28ff4f9 Bump version to 6.4.0 2023-07-18 14:32:12 +10:00
Astrash 0e3a756011 Bump config-noise-function to v1.1.0 2023-07-18 14:29:54 +10:00
Astrash 02198e1b88 Implement distance sampler 2023-07-18 14:29:28 +10:00
Astrash 00aeb98419 Implement translation sampler 2023-07-18 14:27:36 +10:00
Astrash 1a784b51ac Implement expression normalizer sampler 2023-07-18 14:25:07 +10:00
Astrash 34c0895c1f Make metalist injection error more user friendly 2023-07-16 22:46:23 +10:00
Astrash 379fa601a3 Meta annotate LINEAR_HEIGHTMAP sampler 2023-07-16 17:04:51 +10:00
Astrash fcbf51d80b Allow Range keys to be meta annotated 2023-07-16 11:51:51 +10:00
Astrash 9d83dfd164 Bump version to 6.3.2 2023-07-16 11:49:14 +10:00
948 changed files with 10612 additions and 9205 deletions
+7 -7
View File
@@ -8,7 +8,7 @@ indent_style = space
insert_final_newline = false insert_final_newline = false
max_line_length = 140 max_line_length = 140
tab_width = 4 tab_width = 4
ij_continuation_indent_size = 8 ij_continuation_indent_size = 4
ij_formatter_off_tag = @formatter:off ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = false 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_array_initializer_expression = true
ij_java_align_multiline_assignment = true ij_java_align_multiline_assignment = true
ij_java_align_multiline_binary_operation = 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_extends_list = true
ij_java_align_multiline_for = 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 = 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_parenthesized_expression = true
ij_java_align_multiline_records = true ij_java_align_multiline_records = true
ij_java_align_multiline_resources = 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_builder_methods_indents = true
ij_java_keep_control_statement_in_one_line = true ij_java_keep_control_statement_in_one_line = true
ij_java_keep_first_column_comment = false 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_line_breaks = true
ij_java_keep_multiple_expressions_in_one_line = false ij_java_keep_multiple_expressions_in_one_line = false
ij_java_keep_simple_blocks_in_one_line = true 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_key_value_delimiter = equals
ij_properties_spaces_around_key_value_delimiter = false ij_properties_spaces_around_key_value_delimiter = false
[{*.yaml, *.yml}] [{*.yml, *.yaml}]
indent_size = 2 indent_size = 2
ij_visual_guides = none ij_visual_guides = none
ij_yaml_align_values_properties = do_not_align ij_yaml_align_values_properties = do_not_align
ij_yaml_autoinsert_sequence_marker = true ij_yaml_autoinsert_sequence_marker = true
ij_yaml_block_mapping_on_new_line = false ij_yaml_block_mapping_on_new_line = false
ij_yaml_indent_sequence_value = true 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_keep_line_breaks = true
ij_yaml_sequence_on_new_line = false ij_yaml_sequence_on_new_line = false
ij_yaml_space_before_colon = false ij_yaml_space_before_colon = false
+6 -12
View File
@@ -1,19 +1,13 @@
# Global owners, automatically request review when pull request is submitted # Global owners, automatically request review when pull request is submitted
* @dfsek @solonovamax * @dfsek @solonovamax @duplexsystem @Astrashh @justaureus
# Platforms # Platforms
## dfsek wrote the majority of the platform impls /platforms/ @dfsek @solonovamax @duplexsystem @justaureus
/platforms/bukkit/ @dfsek
/platforms/fabric/ @dfsek
/platforms/forge/ @dfsek
/platforms/sponge/ @dfsek
## solonovamax is working on the region generator (unless duplexsystem takes it over)
/platforms/region/ @solonovamax
# Common # Common
/common/ @dfsek @solonovamax /common/ @dfsek @solonovamax @duplexsystem @Astrashh
# Gradle Stuff # Gradle Stuff
## Most gradle stuff was written by solonovamax /buildSrc/ @dfsek @solonovamax @duplexsystem
/buildSrc/ @solonovamax *.gradle.kts @dfsek @solonovamax @duplexsystem
*.gradle.kts @solonovamax /gradle/ @dfsek @solonovamax @duplexsystem
+7 -7
View File
@@ -51,13 +51,13 @@ assignees: ""
<!-- You can fill out the different items by putting the correct value beside each cell. --> <!-- You can fill out the different items by putting the correct value beside each cell. -->
| Name | Value | | Name | Value |
|------------------------------|-------| |------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Terra Version | <!-- Put your Terra version here. (remove the comment) --> | 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) --> | 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) --> | 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 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) --> | 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 ## Issue Description
+69 -83
View File
@@ -1,58 +1,19 @@
# Pull Request # Pull Request
## Brief description. ## Description
<!-- Please provide a brief description of the goals of your PR --> <!-- Include a description of the PR here -->
<!-- <!--
########################################################################### If applicable, include 'Fixes #XXXX' or 'Closes #XXXX' for any related open issues.
## WARNING! ## This helps us relate, track, and close the relevant issues.
## 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.
--> -->
## Licensing ### Changelog
<!-- 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
<!-- <!--
What is the goal of the PR? Fill out a changelog below of what has been done, and what might be planned to be done.
Put a checklist here of what has been done You may delete this if your PR is not adding new features, only fixing bugs or adding translations.
(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.
--> -->
- [ ] <!-- First thing --> - [ ] <!-- First thing -->
@@ -61,47 +22,58 @@
- [ ] <!-- Second thing --> - [ ] <!-- Second thing -->
- [ ] <!-- etc. --> - [ ] <!-- etc. -->
## Affects of the PR ## Checklist
<!--- <!--
What types of changes does your code introduce? (Select any that apply. You may select multiple.) Select the options below that apply.
You must put an x in all the boxes that it applies to. (Like this: [x]) 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 #### Types of changes
- [ ] Bug Fix <!-- Anything which fixes an issue in Terra. --> - [ ] Bug Fix <!-- Changes include bug fixes. -->
- [ ] Build system <!-- Anything which pretain to the build system. --> - [ ] Build system <!-- Changes the build system. -->
- [ ] Documentation <!-- Anything which adds or improves documentation for existing features. --> - [ ] Documentation <!-- Changes add to or improve documentation. -->
- [ ] New Feature <!-- Anything which adds new functionality to Terra. --> - [ ] New Feature <!-- Changes add new functionality to Terra. -->
- [ ] Performance <!-- Anything which is imrpoves the performance of Terra. --> - [ ] Performance <!-- Changes improve the performance of Terra. -->
- [ ] Refactoring <!-- Anything which does not add any new code, only moves code around. --> - [ ] Refactoring <!-- Changes do not add any new code, only moves code around. -->
- [ ] Repository <!-- Anything which affects the repository. Eg. changes to the `README.md` file. --> - [ ] Repository <!-- Changes affect the repository. E.g. changes to the `README.md` file. -->
- [ ] Revert <!-- Anything which reverts previous commits. --> - [ ] Revert <!-- Changes revert previous commits. -->
- [ ] Style <!-- Anything which updates style. --> - [ ] Style <!-- Changes update style, namely the .editorconfig file. -->
- [ ] Tests <!-- Anything which adds or updates tests. --> - [ ] Tests <!-- Changes add or update tests. -->
- [ ] Translation <!-- Anything which is internationalizing the Terra program to other languages. --> - [ ] Translation <!-- Changes include translations to other languages for Terra. -->
#### Compatiblity #### Compatibility
- [ ] Breaking <!-- The following options determine if the PR pertains to a major, minor, or patch version bump -->
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.)
-->
#### Contribution Guidelines. - [ ] Introduces a breaking change
<!--
- [ ] I have read Breaking changes are any fix or feature that breaks some previous functionality to Terra / is not backwards compatible.
the [`CONTRIBUTING.md`](https://github.com/PolyhedralDev/Terra/blob/master/CONTRIBUTING.md) Breaking changes do not include:
document in the root of the git repository. - changes that are backwards compatible and will work with *any* previously existing supported features.
- [ ] My code follows the code style for this - changes to code marked as in a pre-release
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. --> 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 #### Documentation
@@ -112,7 +84,21 @@
- [ ] I have added tests to cover my changes. - [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed. - [ ] All new and existing tests passed.
<!-- <!--
If it only introduces small changes, you don't need to add tests. Tests are typically not necessary for small changes.
But if you add big changes, you should probably at least write *some* testing, where applicable. 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.)
-->
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+1 -8
View File
@@ -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: To run Minecraft with Terra in the IDE (for testing) use the following tasks:
* Bukkit * Bukkit
* `installPaper` - Install a [Paper](https://github.com/PaperMC/Paper) test * `runServer` - Run the Paper test server with Terra installed.
server. (Only needs to be run once).
* `installPurpur` - Install a [Purpur](https://github.com/pl3xgaming/Purpur)
test server. (Only needs to be run once).
* `runPaper` - Run the Paper test server with Terra (`installPaper` must
have been run previously).
* `runPurpur` - Run the Purpur test server with Terra (`installPurpur` must
have been run previously).
* Fabric * Fabric
* `runClient` - Run a Minecraft Fabric client with Terra installed. * `runClient` - Run a Minecraft Fabric client with Terra installed.
* `runServer` - Run a Minecraft Fabric server with Terra installed. * `runServer` - Run a Minecraft Fabric server with Terra installed.
+12 -12
View File
@@ -1,38 +1,38 @@
preRelease(true) preRelease(true)
versionProjects(":common:api", version("6.3.1")) versionProjects(":common:api", version("6.4.1"))
versionProjects(":common:implementation", version("6.3.1")) versionProjects(":common:implementation", version("6.4.1"))
versionProjects(":platforms", version("6.3.1")) versionProjects(":platforms", version("6.4.1"))
allprojects { allprojects {
group = "com.dfsek.terra" group = "com.dfsek.terra"
configureCompilation() configureCompilation()
configureDependencies() configureDependencies()
configurePublishing() configurePublishing()
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
options.isFork = true options.isFork = true
options.isIncremental = true options.isIncremental = true
} }
tasks.withType<Test>().configureEach { tasks.withType<Test>().configureEach {
useJUnitPlatform() useJUnitPlatform()
maxHeapSize = "2G" maxHeapSize = "2G"
ignoreFailures = false ignoreFailures = false
failFast = true failFast = true
maxParallelForks = (Runtime.getRuntime().availableProcessors() - 1).takeIf { it > 0 } ?: 1 maxParallelForks = (Runtime.getRuntime().availableProcessors() - 1).takeIf { it > 0 } ?: 1
reports.html.required.set(false) reports.html.required.set(false)
reports.junitXml.required.set(false) reports.junitXml.required.set(false)
} }
tasks.withType<Copy>().configureEach { tasks.withType<Copy>().configureEach {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = DuplicatesStrategy.EXCLUDE
} }
tasks.withType<Jar>().configureEach { tasks.withType<Jar>().configureEach {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = DuplicatesStrategy.EXCLUDE
} }
@@ -45,11 +45,11 @@ afterEvaluate {
project(":platforms:bukkit:common").configureDistribution() project(":platforms:bukkit:common").configureDistribution()
forSubProjects(":common:addons") { forSubProjects(":common:addons") {
apply(plugin = "com.github.johnrengelman.shadow") apply(plugin = "com.github.johnrengelman.shadow")
tasks.named("build") { tasks.named("build") {
finalizedBy(tasks.named("shadowJar")) finalizedBy(tasks.named("shadowJar"))
} }
dependencies { dependencies {
"compileOnly"(project(":common:api")) "compileOnly"(project(":common:api"))
"testImplementation"(project(":common:api")) "testImplementation"(project(":common:api"))
+8 -16
View File
@@ -3,15 +3,6 @@ plugins {
kotlin("jvm") version embeddedKotlinVersion kotlin("jvm") version embeddedKotlinVersion
} }
buildscript {
configurations.all {
resolutionStrategy {
force("org.ow2.asm:asm:9.3") // TODO: remove when ShadowJar updates ASM version
force("org.ow2.asm:asm-commons:9.3")
}
}
}
repositories { repositories {
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
@@ -24,11 +15,12 @@ repositories {
} }
dependencies { dependencies {
implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:+") //TODO Allow pulling from Versions.kt
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.3.5") 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.3")
implementation("org.ow2.asm:asm-tree:9.3") implementation("org.ow2.asm", "asm", "9.5")
implementation("com.dfsek.tectonic:common:4.2.0") implementation("org.ow2.asm", "asm-tree", "9.5")
implementation("org.yaml:snakeyaml:1.27") implementation("com.dfsek.tectonic", "common", "4.2.0")
implementation("org.yaml", "snakeyaml", "2.2")
} }
+2 -2
View File
@@ -18,7 +18,7 @@ fun Project.addonDir(dir: File, task: Task) {
matchingAddons(dir) { matchingAddons(dir) {
it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon. it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon.
}.forEach { }.forEach {
println("Deleting old addon: " + it.absolutePath) logger.info("Deleting old addon: " + it.absolutePath)
it.delete() it.delete()
} }
forSubProjects(":common:addons") { forSubProjects(":common:addons") {
@@ -29,7 +29,7 @@ fun Project.addonDir(dir: File, task: Task) {
val base = "${jar.archiveBaseName.get()}-${version}" val base = "${jar.archiveBaseName.get()}-${version}"
println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base") logger.info("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base")
jar.archiveFile.orNull?.asFile?.copyTo(target) jar.archiveFile.orNull?.asFile?.copyTo(target)
} }
+4 -1
View File
@@ -48,6 +48,9 @@ fun Project.configureDependencies() {
maven("https://jitpack.io") { maven("https://jitpack.io") {
name = "JitPack" name = "JitPack"
} }
maven("https://nexuslite.gcnt.net/repos/other/") {
name = "GCNT"
}
} }
dependencies { dependencies {
@@ -58,4 +61,4 @@ fun Project.configureDependencies() {
compileOnly("com.google.guava:guava:30.0-jre") compileOnly("com.google.guava:guava:30.0-jre")
testImplementation("com.google.guava:guava:30.0-jre") testImplementation("com.google.guava:guava:30.0-jre")
} }
} }
+16 -13
View File
@@ -1,15 +1,12 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import io.papermc.paperweight.util.path
import java.io.File import java.io.File
import java.io.FileWriter import java.io.FileWriter
import java.net.URI
import java.net.URL import java.net.URL
import java.nio.file.FileSystems import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.plugins.BasePluginExtension import org.gradle.api.plugins.BasePluginExtension
import org.gradle.kotlin.dsl.TaskContainerScope
import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.extra
@@ -17,6 +14,10 @@ import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.named
import org.yaml.snakeyaml.DumperOptions import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml import org.yaml.snakeyaml.Yaml
import kotlin.io.path.copyTo
import kotlin.io.path.createDirectories
import kotlin.io.path.createFile
import kotlin.io.path.exists
fun Project.configureDistribution() { fun Project.configureDistribution() {
@@ -45,21 +46,22 @@ fun Project.configureDistribution() {
doLast { doLast {
// https://github.com/johnrengelman/shadow/issues/111 // https://github.com/johnrengelman/shadow/issues/111
val dest = URI.create("jar:" + tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().asFile.toURI()) val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().path
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs -> FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
forSubProjects(":common:addons") { forSubProjects(":common:addons") {
val jar = getJarTask() val jar = getJarTask()
println("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB") logger.info("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 boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else ""
val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}") val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}")
if (!Files.exists(addonPath)) { if (!addonPath.exists()) {
Files.createDirectories(addonPath.parent) addonPath.parent.createDirectories()
Files.createFile(addonPath) addonPath.createFile()
Files.copy(jar.archiveFile.get().asFile.toPath(), addonPath, StandardCopyOption.REPLACE_EXISTING) jar.archiveFile.get().asFile.toPath().copyTo(addonPath, overwrite = true)
} }
} }
@@ -89,7 +91,8 @@ fun Project.configureDistribution() {
val jar = getJarTask().archiveFileName.get() val jar = getJarTask().archiveFileName.get()
resources.computeIfAbsent( resources.computeIfAbsent(
if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "addons/bootstrap" if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "addons/bootstrap"
else "addons") { ArrayList() }.add(jar) else "addons"
) { ArrayList() }.add(jar)
} }
val options = DumperOptions() val options = DumperOptions()
@@ -110,7 +113,7 @@ fun Project.configureDistribution() {
FileWriter(manifest).use { FileWriter(manifest).use {
yaml.dump(resources, it) yaml.dump(resources, it)
} }
} }
} }
@@ -126,7 +129,7 @@ fun Project.configureDistribution() {
dependsOn(downloadDefaultPacks) dependsOn(downloadDefaultPacks)
configurations = listOf(project.configurations["shaded"]) configurations = listOf(project.configurations["shaded"])
archiveClassifier.set("shaded") archiveClassifier.set("shaded")
setVersion(project.version) version = project.version
relocate("org.apache.commons", "com.dfsek.terra.lib.commons") relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm") relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
relocate("com.dfsek.paralithic", "com.dfsek.terra.lib.paralithic") relocate("com.dfsek.paralithic", "com.dfsek.terra.lib.paralithic")
+2 -2
View File
@@ -42,10 +42,10 @@ fun preRelease(preRelease: Boolean) {
fun Project.versionProjects(project: String, version: String) { fun Project.versionProjects(project: String, version: String) {
forSubProjects(project) { forSubProjects(project) {
this.version = version this.version = version
println("Setting version of $path to $version") logger.info("Setting version of $path to $version")
} }
project(project).version = version project(project).version = version
println("Setting version of $project to $version") logger.info("Setting version of $project to $version")
} }
fun Project.version(version: String): String { fun Project.version(version: String): String {
+40 -37
View File
@@ -1,68 +1,71 @@
object Versions { object Versions {
object Libraries { object Libraries {
const val tectonic = "4.2.0" const val tectonic = "4.2.1"
const val paralithic = "0.7.0" const val paralithic = "0.7.1"
const val strata = "1.1.1" const val strata = "1.3.2"
const val cloud = "1.8.0" const val cloud = "1.8.4"
const val slf4j = "1.7.36" const val slf4j = "2.0.9"
const val log4j_slf4j_impl = "2.14.1" const val log4j_slf4j_impl = "2.20.0"
object Internal { object Internal {
const val apacheText = "1.9" const val shadow = "8.1.1"
const val jafama = "2.3.2" const val apacheText = "1.10.0"
const val apacheIO = "2.6" const val apacheIO = "2.14.0"
const val fastutil = "8.5.6" const val guava = "32.1.3-jre"
const val asm = "9.5"
const val snakeYml = "2.2"
} }
} }
object Fabric { object Fabric {
const val fabricLoader = "0.14.8" const val fabricAPI = "0.90.0+${Mod.minecraft}"
const val fabricAPI = "0.83.1+1.20.1"
}
object Quilt {
const val quiltLoader = "0.17.0"
const val fabricApi = "6.0.0-beta.3+0.76.0-1.19.4"
} }
//
// object Quilt {
// const val quiltLoader = "0.20.2"
// const val fabricApi = "7.3.1+0.89.3-1.20.1"
// }
object Mod { object Mod {
const val mixin = "0.11.2+mixin.0.8.5" const val mixin = "0.12.5+mixin.0.8.5"
const val minecraft = "1.20.1" const val minecraft = "1.20.2"
const val yarn = "$minecraft+build.2" const val yarn = "$minecraft+build.4"
const val fabricLoader = "0.14.21" const val fabricLoader = "0.14.23"
const val architecuryLoom = "0.12.0.290" const val architecuryLoom = "1.3.357"
const val architecturyPlugin = "3.4-SNAPSHOT" const val architecturyPlugin = "3.4.146"
const val loomQuiltflower = "1.7.1" const val loomVineflower = "1.11.0"
} }
object Forge { object Forge {
const val forge = "${Mod.minecraft}-47.0.3" const val forge = "${Mod.minecraft}-48.0.13"
const val burningwave = "12.53.0" const val burningwave = "12.63.0"
} }
object Bukkit { object Bukkit {
const val paper = "1.18.2-R0.1-SNAPSHOT" const val paper = "1.18.2-R0.1-SNAPSHOT"
const val paperLib = "1.0.5" const val paperLib = "1.0.5"
const val minecraft = "1.20.1" const val foliaLib = "0.2.5"
const val minecraft = "1.20.2"
const val reflectionRemapper = "0.1.0-SNAPSHOT" const val reflectionRemapper = "0.1.0-SNAPSHOT"
const val paperDevBundle = "1.20.1-R0.1-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 { object CLI {
const val nbt = "6.1" const val nbt = "6.1"
const val logback = "1.2.9" const val logback = "1.4.11"
const val commonsIO = "2.7"
const val guava = "31.0.1-jre"
} }
} }
@@ -82,7 +82,7 @@ abstract class GenerateDocsTask : DefaultTask() {
} }
template.add(keyName.toString(), description.toString().ifBlank { template.add(keyName.toString(), description.toString().ifBlank {
println("No description provided for field " + field.name + " in class " + name) logger.info("No description provided for field " + field.name + " in class " + name)
"*No description provided.*" "*No description provided.*"
}) })
} }
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -8,17 +8,17 @@ import com.dfsek.terra.api.addon.BaseAddon;
public class ApiAddon implements BaseAddon { public class ApiAddon implements BaseAddon {
private final Version version; private final Version version;
private final String id; private final String id;
public ApiAddon(Version version, String id) { public ApiAddon(Version version, String id) {
this.version = version; this.version = version;
this.id = id; this.id = id;
} }
@Override @Override
public Version getVersion() { public Version getVersion() {
return version; return version;
} }
@Override @Override
public String getID() { public String getID() {
return id; return id;
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -15,7 +15,7 @@ public class ApiAddonClassLoader extends URLClassLoader {
static { static {
ClassLoader.registerAsParallelCapable(); ClassLoader.registerAsParallelCapable();
} }
public ApiAddonClassLoader(URL[] urls, ClassLoader parent) { public ApiAddonClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent); super(urls, parent);
} }
@@ -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, * 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. * 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> { public class ApiAddonLoader implements BootstrapBaseAddon<BaseAddon> {
private static final Version VERSION = Versions.getVersion(1, 0, 0); private static final Version VERSION = Versions.getVersion(1, 0, 0);
@Override @Override
public Iterable<BaseAddon> loadAddons(Path addonsFolder, BootstrapAddonClassLoader parent) { public Iterable<BaseAddon> loadAddons(Path addonsFolder, BootstrapAddonClassLoader parent) {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override @Override
public String getID() { public String getID() {
return "API"; return "API";
} }
@Override @Override
public Version getVersion() { public Version getVersion() {
return VERSION; return VERSION;
@@ -9,11 +9,11 @@ class BaseBiomeColumn implements Column<Biome> {
private final Biome base; private final Biome base;
private final int min; private final int min;
private final int max; private final int max;
private final int x; private final int x;
private final int z; private final int z;
private final long seed; private final long seed;
protected BaseBiomeColumn(BiomeExtrusionProvider biomeProvider, Biome base, int min, int max, int x, int z, long seed) { protected BaseBiomeColumn(BiomeExtrusionProvider biomeProvider, Biome base, int min, int max, int x, int z, long seed) {
this.biomeProvider = biomeProvider; this.biomeProvider = biomeProvider;
this.base = base; this.base = base;
@@ -23,27 +23,27 @@ class BaseBiomeColumn implements Column<Biome> {
this.z = z; this.z = z;
this.seed = seed; this.seed = seed;
} }
@Override @Override
public int getMinY() { public int getMinY() {
return min; return min;
} }
@Override @Override
public int getMaxY() { public int getMaxY() {
return max; return max;
} }
@Override @Override
public int getX() { public int getX() {
return x; return x;
} }
@Override @Override
public int getZ() { public int getZ() {
return z; return z;
} }
@Override @Override
public Biome get(int y) { public Biome get(int y) {
return biomeProvider.extrude(base, x, y, z, seed); return biomeProvider.extrude(base, x, y, z, seed);
@@ -27,41 +27,41 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomeExtrusionAddon implements AddonInitializer { public class BiomeExtrusionAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<Extrusion>>> EXTRUSION_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<Extrusion>>> EXTRUSION_REGISTRY_KEY = new TypeKey<>() {
}; };
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
}; };
@Inject @Inject
private Platform platform; private Platform platform;
@Inject @Inject
private BaseAddon addon; private BaseAddon addon;
@Override @Override
public void initialize() { public void initialize() {
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry =
event.getPack() event.getPack()
.getOrCreateRegistry(PROVIDER_REGISTRY_KEY); .getOrCreateRegistry(PROVIDER_REGISTRY_KEY);
providerRegistry.register(addon.key("EXTRUSION"), BiomeExtrusionTemplate::new); providerRegistry.register(addon.key("EXTRUSION"), BiomeExtrusionTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Extrusion>>> extrusionRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<Extrusion>>> extrusionRegistry = event.getPack().getOrCreateRegistry(
EXTRUSION_REGISTRY_KEY); EXTRUSION_REGISTRY_KEY);
extrusionRegistry.register(addon.key("SET"), SetExtrusionTemplate::new); extrusionRegistry.register(addon.key("SET"), SetExtrusionTemplate::new);
extrusionRegistry.register(addon.key("REPLACE"), ReplaceExtrusionTemplate::new); extrusionRegistry.register(addon.key("REPLACE"), ReplaceExtrusionTemplate::new);
}) })
.failThrough(); .failThrough();
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPostLoadEvent.class) .register(addon, ConfigPackPostLoadEvent.class)
.then(event -> { .then(event -> {
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class); Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
event.getPack().applyLoader(ReplaceableBiome.class, new ReplaceableBiomeLoader(biomeRegistry)); event.getPack().applyLoader(ReplaceableBiome.class, new ReplaceableBiomeLoader(biomeRegistry));
}); });
} }
} }
@@ -16,7 +16,7 @@ public class BiomeExtrusionProvider implements BiomeProvider {
private final Set<Biome> biomes; private final Set<Biome> biomes;
private final List<Extrusion> extrusions; private final List<Extrusion> extrusions;
private final int resolution; private final int resolution;
public BiomeExtrusionProvider(BiomeProvider delegate, List<Extrusion> extrusions, int resolution) { public BiomeExtrusionProvider(BiomeProvider delegate, List<Extrusion> extrusions, int resolution) {
this.delegate = delegate; this.delegate = delegate;
this.biomes = delegate.stream().collect(Collectors.toSet()); this.biomes = delegate.stream().collect(Collectors.toSet());
@@ -24,43 +24,43 @@ public class BiomeExtrusionProvider implements BiomeProvider {
this.extrusions = extrusions; this.extrusions = extrusions;
this.resolution = resolution; this.resolution = resolution;
} }
@Override @Override
public Biome getBiome(int x, int y, int z, long seed) { public Biome getBiome(int x, int y, int z, long seed) {
Biome delegated = delegate.getBiome(x, y, z, seed); Biome delegated = delegate.getBiome(x, y, z, seed);
return extrude(delegated, x, y, z, seed); return extrude(delegated, x, y, z, seed);
} }
public Biome extrude(Biome original, int x, int y, int z, long seed) { public Biome extrude(Biome original, int x, int y, int z, long seed) {
for(Extrusion extrusion : extrusions) { for(Extrusion extrusion : extrusions) {
original = extrusion.extrude(original, x, y, z, seed); original = extrusion.extrude(original, x, y, z, seed);
} }
return original; return original;
} }
@Override @Override
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) { public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
return delegate.getBaseBiome(x, z, seed) return delegate.getBaseBiome(x, z, seed)
.map(base -> (Column<Biome>) new BaseBiomeColumn(this, base, min, max, 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)); .orElseGet(() -> BiomeProvider.super.getColumn(x, z, seed, min, max));
} }
@Override @Override
public Optional<Biome> getBaseBiome(int x, int z, long seed) { public Optional<Biome> getBaseBiome(int x, int z, long seed) {
return delegate.getBaseBiome(x, z, seed); return delegate.getBaseBiome(x, z, seed);
} }
@Override @Override
public Iterable<Biome> getBiomes() { public Iterable<Biome> getBiomes() {
return biomes; return biomes;
} }
@Override @Override
public int resolution() { public int resolution() {
return resolution; return resolution;
} }
public BiomeProvider getDelegate() { public BiomeProvider getDelegate() {
return delegate; return delegate;
} }
@@ -7,6 +7,6 @@ import com.dfsek.terra.api.world.biome.Biome;
public interface Extrusion { public interface Extrusion {
Biome extrude(Biome original, int x, int y, int z, long seed); Biome extrude(Biome original, int x, int y, int z, long seed);
Collection<Biome> getBiomes(); Collection<Biome> getBiomes();
} }
@@ -6,16 +6,16 @@ import com.dfsek.terra.api.world.biome.Biome;
final class PresentBiome implements ReplaceableBiome { final class PresentBiome implements ReplaceableBiome {
private final Biome biome; private final Biome biome;
PresentBiome(Biome biome) { PresentBiome(Biome biome) {
this.biome = biome; this.biome = biome;
} }
@Override @Override
public Biome get(Biome existing) { public Biome get(Biome existing) {
return biome; return biome;
} }
@Override @Override
public boolean isSelf() { public boolean isSelf() {
return false; return false;
@@ -13,19 +13,19 @@ public sealed interface ReplaceableBiome permits PresentBiome, SelfBiome {
static ReplaceableBiome of(Biome biome) { static ReplaceableBiome of(Biome biome) {
return new PresentBiome(biome); return new PresentBiome(biome);
} }
static ReplaceableBiome self() { static ReplaceableBiome self() {
return SelfBiome.INSTANCE; return SelfBiome.INSTANCE;
} }
Biome get(Biome existing); Biome get(Biome existing);
default Biome get() { default Biome get() {
if(isSelf()) { if(isSelf()) {
throw new IllegalStateException("Cannot get() self biome!"); throw new IllegalStateException("Cannot get() self biome!");
} }
return get(null); return get(null);
} }
boolean isSelf(); boolean isSelf();
} }
@@ -8,12 +8,12 @@ import com.dfsek.terra.api.world.biome.Biome;
final class SelfBiome implements ReplaceableBiome { final class SelfBiome implements ReplaceableBiome {
public static final SelfBiome INSTANCE = new SelfBiome(); public static final SelfBiome INSTANCE = new SelfBiome();
@Override @Override
public Biome get(Biome existing) { public Biome get(Biome existing) {
return Objects.requireNonNull(existing); return Objects.requireNonNull(existing);
} }
@Override @Override
public boolean isSelf() { public boolean isSelf() {
return true; return true;
@@ -15,14 +15,14 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomeExtrusionTemplate implements ObjectTemplate<BiomeProvider> { public class BiomeExtrusionTemplate implements ObjectTemplate<BiomeProvider> {
@Value("provider") @Value("provider")
private @Meta BiomeProvider provider; private @Meta BiomeProvider provider;
@Value("resolution") @Value("resolution")
@Default @Default
private @Meta int resolution = 4; private @Meta int resolution = 4;
@Value("extrusions") @Value("extrusions")
private @Meta List<@Meta Extrusion> extrusions; private @Meta List<@Meta Extrusion> extrusions;
@Override @Override
public BiomeProvider get() { public BiomeProvider get() {
return new BiomeExtrusionProvider(provider, extrusions, resolution); return new BiomeExtrusionProvider(provider, extrusions, resolution);
@@ -15,18 +15,18 @@ import com.dfsek.terra.api.world.biome.Biome;
public class ReplaceableBiomeLoader implements TypeLoader<ReplaceableBiome> { public class ReplaceableBiomeLoader implements TypeLoader<ReplaceableBiome> {
private final Registry<Biome> biomeRegistry; private final Registry<Biome> biomeRegistry;
public ReplaceableBiomeLoader(Registry<Biome> biomeRegistry) { public ReplaceableBiomeLoader(Registry<Biome> biomeRegistry) {
this.biomeRegistry = biomeRegistry; this.biomeRegistry = biomeRegistry;
} }
@Override @Override
public ReplaceableBiome load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) public ReplaceableBiome load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
throws LoadException { throws LoadException {
if(c.equals("SELF")) return ReplaceableBiome.self(); if(c.equals("SELF")) return ReplaceableBiome.self();
return biomeRegistry return biomeRegistry
.getByID((String) c) .getByID((String) c)
.map(ReplaceableBiome::of) .map(ReplaceableBiome::of)
.orElseThrow(() -> new LoadException("No such biome: " + c, depthTracker)); .orElseThrow(() -> new LoadException("No such biome: " + c, depthTracker));
} }
} }
@@ -12,10 +12,10 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class ReplaceExtrusionTemplate extends SamplerExtrusionTemplate { public class ReplaceExtrusionTemplate extends SamplerExtrusionTemplate {
@Value("to") @Value("to")
private @Meta ProbabilityCollection<@Meta ReplaceableBiome> biomes; private @Meta ProbabilityCollection<@Meta ReplaceableBiome> biomes;
@Value("from") @Value("from")
private @Meta String fromTag; private @Meta String fromTag;
@Override @Override
public Extrusion get() { public Extrusion get() {
return new ReplaceExtrusion(sampler, range, biomes, fromTag); return new ReplaceExtrusion(sampler, range, biomes, fromTag);
@@ -12,7 +12,7 @@ import com.dfsek.terra.api.util.Range;
public abstract class SamplerExtrusionTemplate implements ObjectTemplate<Extrusion> { public abstract class SamplerExtrusionTemplate implements ObjectTemplate<Extrusion> {
@Value("sampler") @Value("sampler")
protected @Meta NoiseSampler sampler; protected @Meta NoiseSampler sampler;
@Value("range") @Value("range")
protected @Meta Range range; protected @Meta Range range;
} }
@@ -12,7 +12,7 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class SetExtrusionTemplate extends SamplerExtrusionTemplate { public class SetExtrusionTemplate extends SamplerExtrusionTemplate {
@Value("to") @Value("to")
private @Meta ProbabilityCollection<@Meta ReplaceableBiome> biomes; private @Meta ProbabilityCollection<@Meta ReplaceableBiome> biomes;
@Override @Override
public Extrusion get() { public Extrusion get() {
return new SetExtrusion(sampler, range, biomes); return new SetExtrusion(sampler, range, biomes);
@@ -18,20 +18,20 @@ import com.dfsek.terra.api.world.biome.Biome;
*/ */
public class ReplaceExtrusion implements Extrusion { public class ReplaceExtrusion implements Extrusion {
private final NoiseSampler sampler; private final NoiseSampler sampler;
private final Range range; private final Range range;
private final ProbabilityCollection<ReplaceableBiome> biomes; private final ProbabilityCollection<ReplaceableBiome> biomes;
private final Predicate<Biome> hasTag; private final Predicate<Biome> hasTag;
public ReplaceExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) { public ReplaceExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) {
this.sampler = sampler; this.sampler = sampler;
this.range = range; this.range = range;
this.biomes = biomes; this.biomes = biomes;
this.hasTag = BiomeQueries.has(tag); this.hasTag = BiomeQueries.has(tag);
} }
@Override @Override
public Biome extrude(Biome original, int x, int y, int z, long seed) { public Biome extrude(Biome original, int x, int y, int z, long seed) {
if(hasTag.test(original)) { if(hasTag.test(original)) {
@@ -39,14 +39,14 @@ public class ReplaceExtrusion implements Extrusion {
} }
return original; return original;
} }
@Override @Override
public Collection<Biome> getBiomes() { public Collection<Biome> getBiomes() {
return biomes return biomes
.getContents() .getContents()
.stream() .stream()
.filter(Predicate.not(ReplaceableBiome::isSelf)) .filter(Predicate.not(ReplaceableBiome::isSelf))
.map(ReplaceableBiome::get) .map(ReplaceableBiome::get)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
} }
@@ -17,29 +17,29 @@ import com.dfsek.terra.api.world.biome.Biome;
*/ */
public class SetExtrusion implements Extrusion { public class SetExtrusion implements Extrusion {
private final NoiseSampler sampler; private final NoiseSampler sampler;
private final Range range; private final Range range;
private final ProbabilityCollection<ReplaceableBiome> biomes; private final ProbabilityCollection<ReplaceableBiome> biomes;
public SetExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes) { public SetExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes) {
this.sampler = sampler; this.sampler = sampler;
this.range = range; this.range = range;
this.biomes = biomes; this.biomes = biomes;
} }
@Override @Override
public Biome extrude(Biome original, int x, int y, int z, long seed) { 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); return range.ifInRange(y, () -> biomes.get(sampler, x, y, z, seed).get(original), original);
} }
@Override @Override
public Collection<Biome> getBiomes() { public Collection<Biome> getBiomes() {
return biomes return biomes
.getContents() .getContents()
.stream() .stream()
.filter(Predicate.not(ReplaceableBiome::isSelf)) .filter(Predicate.not(ReplaceableBiome::isSelf))
.map(ReplaceableBiome::get) .map(ReplaceableBiome::get)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
} }
@@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -1,12 +1,8 @@
version = version("1.0.0") version = version("1.0.1")
dependencies { dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader")) compileOnlyApi(project(":common:addons:manifest-addon-loader"))
compileOnlyApi(project(":common:addons:library-image")) compileOnlyApi(project(":common:addons:library-image"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.biome.image.lib.jafama") }
}
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -9,41 +9,41 @@ package com.dfsek.terra.addons.biome.image.v2;
import java.util.Optional; import java.util.Optional;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler; 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.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ImageBiomeProvider implements BiomeProvider { public class ImageBiomeProvider implements BiomeProvider {
private final int resolution; private final int resolution;
private final ColorConverter<Biome> colorConverter; private final ColorConverter<Biome> colorConverter;
private final ColorSampler colorSampler; private final ColorSampler colorSampler;
public ImageBiomeProvider(ColorConverter<Biome> colorConverter, ColorSampler colorSampler, int resolution) { public ImageBiomeProvider(ColorConverter<Biome> colorConverter, ColorSampler colorSampler, int resolution) {
this.resolution = resolution; this.resolution = resolution;
this.colorConverter = colorConverter; this.colorConverter = colorConverter;
this.colorSampler = colorSampler; this.colorSampler = colorSampler;
} }
@Override @Override
public Biome getBiome(int x, int y, int z, long seed) { public Biome getBiome(int x, int y, int z, long seed) {
return getBiome(x, z); return getBiome(x, z);
} }
public Biome getBiome(int x, int z) { public Biome getBiome(int x, int z) {
x /= resolution; x /= resolution;
z /= resolution; z /= resolution;
return colorConverter.apply(colorSampler.apply(x, z)); return colorConverter.apply(colorSampler.apply(x, z));
} }
@Override @Override
public Optional<Biome> getBaseBiome(int x, int z, long seed) { public Optional<Biome> getBaseBiome(int x, int z, long seed) {
return Optional.of(getBiome(x, z)); return Optional.of(getBiome(x, z));
} }
@Override @Override
public Iterable<Biome> getBiomes() { public Iterable<Biome> getBiomes() {
return colorConverter.getEntries(); return colorConverter.getEntries();
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -33,42 +33,46 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ImageBiomeProviderAddon implements AddonInitializer { public class ImageBiomeProviderAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() { 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<ColorConverter<Biome>>>> BIOME_COLOR_CONVERTER_REGISTRY_KEY = new TypeKey<>() {
}; };
public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<Biome>>>> BIOME_COLOR_MAPPING_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<Biome>>>> BIOME_COLOR_MAPPING_REGISTRY_KEY = new TypeKey<>() {
}; };
@Inject @Inject
private Platform platform; private Platform platform;
@Inject @Inject
private BaseAddon addon; private BaseAddon addon;
@Override @Override
public void initialize() { public void initialize() {
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
.priority(501) .priority(501)
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY); PROVIDER_REGISTRY_KEY);
providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new); providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry =
BIOME_COLOR_CONVERTER_REGISTRY_KEY); event.getPack().getOrCreateRegistry(
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new); BIOME_COLOR_CONVERTER_REGISTRY_KEY);
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new); 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( .then(event -> {
BIOME_COLOR_MAPPING_REGISTRY_KEY); CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry =
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"), () -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class), b -> b)); event.getPack().getOrCreateRegistry(
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new); BIOME_COLOR_MAPPING_REGISTRY_KEY);
}) biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"),
.failThrough(); () -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class),
b -> b));
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new);
})
.failThrough();
} }
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -13,26 +13,26 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.image.v2.ImageBiomeProvider; import com.dfsek.terra.addons.biome.image.v2.ImageBiomeProvider;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler; import com.dfsek.terra.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.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@SuppressWarnings("FieldMayBeFinal") @SuppressWarnings("FieldMayBeFinal")
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> { public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
@Value("resolution") @Value("resolution")
@Default @Default
@Description("Sets the resolution at which to sample the image.") @Description("Sets the resolution at which to sample the image.")
private int resolution = 1; private int resolution = 1;
@Value("color-sampler") @Value("color-sampler")
private ColorSampler colorSampler; private ColorSampler colorSampler;
@Value("color-conversion") @Value("color-conversion")
private ColorConverter<Biome> colorConverter; private ColorConverter<Biome> colorConverter;
@Override @Override
public BiomeProvider get() { public BiomeProvider get() {
return new ImageBiomeProvider(colorConverter, colorSampler, resolution); return new ImageBiomeProvider(colorConverter, colorSampler, resolution);
@@ -11,7 +11,7 @@ public class ClosestBiomeColorConverterTemplate extends ClosestColorConverterTem
@Value("match") @Value("match")
private ColorMapping<Biome> match; private ColorMapping<Biome> match;
@Override @Override
protected ColorMapping<Biome> getMapping() { protected ColorMapping<Biome> getMapping() {
return match; return match;
@@ -9,13 +9,13 @@ import com.dfsek.terra.api.world.biome.Biome;
public class ExactBiomeColorConverterTemplate extends ExactColorConverterTemplate<Biome> { public class ExactBiomeColorConverterTemplate extends ExactColorConverterTemplate<Biome> {
@Value("match") @Value("match")
private ColorMapping<Biome> match; private ColorMapping<Biome> match;
@Value("else") @Value("else")
private Biome fallback; private Biome fallback;
@Value("ignore-alpha") @Value("ignore-alpha")
@Default @Default
private boolean ignoreAlpha = true; private boolean ignoreAlpha = true;
@@ -29,7 +29,7 @@ public class ExactBiomeColorConverterTemplate extends ExactColorConverterTemplat
protected Biome getFallback() { protected Biome getFallback() {
return fallback; return fallback;
} }
@Override @Override
protected boolean ignoreAlpha() { protected boolean ignoreAlpha() {
return ignoreAlpha; return ignoreAlpha;
@@ -12,10 +12,10 @@ import com.dfsek.terra.api.world.biome.Biome;
public class DefinedBiomeColorMappingTemplate implements ObjectTemplate<ColorMapping<Biome>> { public class DefinedBiomeColorMappingTemplate implements ObjectTemplate<ColorMapping<Biome>> {
@Value("map") @Value("map")
Map<ColorString, Biome> map; Map<ColorString, Biome> map;
@Override @Override
public ColorMapping<Biome> get() { public ColorMapping<Biome> get() {
var map = MapUtil.mapKeys(this.map, ColorString::getColor); var map = MapUtil.mapKeys(this.map, ColorString::getColor);
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal 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 { dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader")) 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") }
}
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.biome.image; package com.dfsek.terra.addons.biome.image;
import net.jafama.FastMath;
import java.awt.Color; import java.awt.Color;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.HashMap; import java.util.HashMap;
@@ -25,62 +23,62 @@ public class ImageBiomeProvider implements BiomeProvider {
private final BufferedImage image; private final BufferedImage image;
private final int resolution; private final int resolution;
private final Align align; private final Align align;
public ImageBiomeProvider(Set<Biome> registry, BufferedImage image, int resolution, Align align) { public ImageBiomeProvider(Set<Biome> registry, BufferedImage image, int resolution, Align align) {
this.image = image; this.image = image;
this.resolution = resolution; this.resolution = resolution;
this.align = align; this.align = align;
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome)); registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
} }
private static int distance(Color a, Color b) { 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 @Override
public Biome getBiome(int x, int y, int z, long seed) { public Biome getBiome(int x, int y, int z, long seed) {
return getBiome(x, z); return getBiome(x, z);
} }
public Biome getBiome(int x, int z) { public Biome getBiome(int x, int z) {
x /= resolution; x /= resolution;
z /= resolution; z /= resolution;
Color color = align.getColor(image, x, z); Color color = align.getColor(image, x, z);
return colorBiomeMap.get(colorBiomeMap.keySet() return colorBiomeMap.get(colorBiomeMap.keySet()
.stream() .stream()
.reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new), .reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new),
(running, element) -> { (running, element) -> {
int d1 = distance(color, running); int d1 = distance(color, running);
int d2 = distance(color, element); int d2 = distance(color, element);
return d1 < d2 ? running : element; return d1 < d2 ? running : element;
})); }));
} }
@Override @Override
public Optional<Biome> getBaseBiome(int x, int z, long seed) { public Optional<Biome> getBaseBiome(int x, int z, long seed) {
return Optional.of(getBiome(x, z)); return Optional.of(getBiome(x, z));
} }
@Override @Override
public Iterable<Biome> getBiomes() { public Iterable<Biome> getBiomes() {
return colorBiomeMap.values(); return colorBiomeMap.values();
} }
public enum Align { public enum Align {
CENTER { CENTER {
@Override @Override
public Color getColor(BufferedImage image, int x, int z) { public Color getColor(BufferedImage image, int x, int z) {
return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()), return new Color(image.getRGB(Math.floorMod(x - image.getWidth() / 2, image.getWidth()),
FastMath.floorMod(z - image.getHeight() / 2, image.getHeight()))); Math.floorMod(z - image.getHeight() / 2, image.getHeight())));
} }
}, },
NONE { NONE {
@Override @Override
public Color getColor(BufferedImage image, int x, int z) { 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); public abstract Color getColor(BufferedImage image, int x, int z);
} }
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -26,30 +26,31 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ImageBiomeProviderAddon implements AddonInitializer { public class ImageBiomeProviderAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
}; };
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
@Inject @Inject
private Platform platform; private Platform platform;
@Inject @Inject
private BaseAddon addon; private BaseAddon addon;
@Override @Override
public void initialize() { public void initialize() {
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY); PROVIDER_REGISTRY_KEY);
providerRegistry.register(addon.key("IMAGE"), providerRegistry.register(addon.key("IMAGE"),
() -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class))); () -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
}) })
.failThrough(); .failThrough();
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."); 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.");
} }
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -33,11 +33,11 @@ public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
@Value("image.align") @Value("image.align")
@Description("Sets the alignment style to use for the image.") @Description("Sets the alignment style to use for the image.")
private ImageBiomeProvider.Align align; private ImageBiomeProvider.Align align;
public ImageProviderTemplate(Registry<Biome> set) { public ImageProviderTemplate(Registry<Biome> set) {
this.biomes = set; this.biomes = set;
} }
@Override @Override
public BiomeProvider get() { public BiomeProvider get() {
return new ImageBiomeProvider(new HashSet<>(biomes.entries()), image, resolution, align); return new ImageBiomeProvider(new HashSet<>(biomes.entries()), image, resolution, align);
@@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -6,7 +6,7 @@ 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 Version 2 is a re-implementation of the original addon with the primary goal of providing
consistent scaling for noise relative to the world consistent scaling for noise relative to the world
(See https://github.com/PolyhedralDev/Terra/issues/264 for more details), and has been (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. 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 This addon registers the `PIPELINE` biome provider type, and all associated
configurations. configurations.
@@ -1,12 +1,5 @@
version = version("1.0.0") version = version("1.0.1")
dependencies { dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader")) compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.biome.pipeline.lib.jafama")
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -11,6 +11,9 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.function.Supplier; 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.BiomePipelineTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.PipelineBiomeLoader; 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.source.SamplerSourceTemplate;
@@ -20,9 +23,6 @@ import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderStage
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceListStageTemplate; 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.ReplaceStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.SmoothStageTemplate; import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.SmoothStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon; import com.dfsek.terra.api.addon.BaseAddon;
@@ -38,52 +38,52 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineAddon implements AddonInitializer { public class BiomePipelineAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<Source>>> SOURCE_REGISTRY_KEY = new TypeKey<>() { 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<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
}; };
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() { public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
}; };
@Inject @Inject
private Platform platform; private Platform platform;
@Inject @Inject
private BaseAddon addon; private BaseAddon addon;
@Override @Override
public void initialize() { public void initialize() {
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY); PROVIDER_REGISTRY_KEY);
providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new); providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry(
SOURCE_REGISTRY_KEY); SOURCE_REGISTRY_KEY);
sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new); sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
STAGE_REGISTRY_KEY); STAGE_REGISTRY_KEY);
stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new); stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
stageRegistry.register(addon.key("SMOOTH"), SmoothStageTemplate::new); stageRegistry.register(addon.key("SMOOTH"), SmoothStageTemplate::new);
stageRegistry.register(addon.key("REPLACE"), ReplaceStageTemplate::new); stageRegistry.register(addon.key("REPLACE"), ReplaceStageTemplate::new);
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListStageTemplate::new); stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListStageTemplate::new);
stageRegistry.register(addon.key("BORDER"), BorderStageTemplate::new); stageRegistry.register(addon.key("BORDER"), BorderStageTemplate::new);
stageRegistry.register(addon.key("BORDER_LIST"), BorderListStageTemplate::new); stageRegistry.register(addon.key("BORDER_LIST"), BorderListStageTemplate::new);
}) })
.failThrough(); .failThrough();
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPostLoadEvent.class) .register(addon, ConfigPackPostLoadEvent.class)
.then(event -> { .then(event -> {
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class); Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
event.getPack().applyLoader(PipelineBiome.class, new PipelineBiomeLoader(biomeRegistry)); event.getPack().applyLoader(PipelineBiome.class, new PipelineBiomeLoader(biomeRegistry));
}); });
} }
} }
@@ -12,11 +12,11 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineColumn implements Column<Biome> { public class BiomePipelineColumn implements Column<Biome> {
private final int min; private final int min;
private final int max; private final int max;
private final int x; private final int x;
private final int z; private final int z;
private final Biome biome; private final Biome biome;
protected BiomePipelineColumn(BiomeProvider biomeProvider, int min, int max, int x, int z, long seed) { protected BiomePipelineColumn(BiomeProvider biomeProvider, int min, int max, int x, int z, long seed) {
this.min = min; this.min = min;
this.max = max; this.max = max;
@@ -24,44 +24,44 @@ public class BiomePipelineColumn implements Column<Biome> {
this.z = z; this.z = z;
this.biome = biomeProvider.getBiome(x, 0, z, seed); this.biome = biomeProvider.getBiome(x, 0, z, seed);
} }
@Override @Override
public int getMinY() { public int getMinY() {
return min; return min;
} }
@Override @Override
public int getMaxY() { public int getMaxY() {
return max; return max;
} }
@Override @Override
public int getX() { public int getX() {
return x; return x;
} }
@Override @Override
public int getZ() { public int getZ() {
return z; return z;
} }
@Override @Override
public Biome get(int y) { public Biome get(int y) {
return biome; return biome;
} }
@Override @Override
public void forRanges(int resolution, IntIntObjConsumer<Biome> consumer) { public void forRanges(int resolution, IntIntObjConsumer<Biome> consumer) {
consumer.accept(min, max, biome); consumer.accept(min, max, biome);
} }
@Override @Override
public void forEach(Consumer<Biome> consumer) { public void forEach(Consumer<Biome> consumer) {
for(int y = min; y < max; y++) { for(int y = min; y < max; y++) {
consumer.accept(biome); consumer.accept(biome);
} }
} }
@Override @Override
public void forEach(IntObjConsumer<Biome> consumer) { public void forEach(IntObjConsumer<Biome> consumer) {
for(int y = min; y < max; y++) { for(int y = min; y < max; y++) {
@@ -1,13 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.v2; package com.dfsek.terra.addons.biome.pipeline.v2;
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import net.jafama.FastMath;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
@@ -15,6 +9,11 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.StreamSupport; 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.noise.NoiseSampler;
import com.dfsek.terra.api.registry.key.StringIdentifiable; import com.dfsek.terra.api.registry.key.StringIdentifiable;
import com.dfsek.terra.api.util.Column; import com.dfsek.terra.api.util.Column;
@@ -23,23 +22,23 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class PipelineBiomeProvider implements BiomeProvider { public class PipelineBiomeProvider implements BiomeProvider {
private final LoadingCache<SeededVector, BiomeChunk> biomeChunkCache; private final LoadingCache<SeededVector, BiomeChunk> biomeChunkCache;
private final int chunkSize; private final int chunkSize;
private final int resolution; private final int resolution;
private final NoiseSampler mutator; private final NoiseSampler mutator;
private final double noiseAmp; private final double noiseAmp;
private final Set<Biome> biomes; private final Set<Biome> biomes;
public PipelineBiomeProvider(Pipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) { public PipelineBiomeProvider(Pipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
this.resolution = resolution; this.resolution = resolution;
this.mutator = mutator; this.mutator = mutator;
this.noiseAmp = noiseAmp; this.noiseAmp = noiseAmp;
this.chunkSize = pipeline.getChunkSize(); this.chunkSize = pipeline.getChunkSize();
this.biomeChunkCache = Caffeine.newBuilder() this.biomeChunkCache = Caffeine.newBuilder()
.maximumSize(64) .maximumSize(64)
.build(pipeline::generateChunk); .build(pipeline::generateChunk);
Set<PipelineBiome> biomeSet = new HashSet<>(); Set<PipelineBiome> biomeSet = new HashSet<>();
pipeline.getSource().getBiomes().forEach(biomeSet::add); pipeline.getSource().getBiomes().forEach(biomeSet::add);
Iterable<PipelineBiome> result = biomeSet; Iterable<PipelineBiome> result = biomeSet;
@@ -50,64 +49,65 @@ public class PipelineBiomeProvider implements BiomeProvider {
Iterable<PipelineBiome> finalResult = result; Iterable<PipelineBiome> finalResult = result;
result.forEach(pipelineBiome -> { result.forEach(pipelineBiome -> {
if(pipelineBiome.isPlaceholder()) { if(pipelineBiome.isPlaceholder()) {
StringBuilder biomeList = new StringBuilder("\n"); StringBuilder biomeList = new StringBuilder("\n");
StreamSupport.stream(finalResult.spliterator(), false) StreamSupport.stream(finalResult.spliterator(), false)
.sorted(Comparator.comparing(StringIdentifiable::getID)) .sorted(Comparator.comparing(StringIdentifiable::getID))
.forEach(delegate -> biomeList .forEach(delegate -> biomeList
.append(" - ") .append(" - ")
.append(delegate.getID()) .append(delegate.getID())
.append(':') .append(':')
.append(delegate.getClass().getCanonicalName()) .append(delegate.getClass().getCanonicalName())
.append('\n')); .append('\n'));
throw new IllegalArgumentException("Biome Pipeline leaks placeholder biome \"" + pipelineBiome.getID() + throw new IllegalArgumentException("Biome Pipeline leaks placeholder biome \"" + pipelineBiome.getID() +
"\". Ensure there is a stage to guarantee replacement of the placeholder biome. Biomes: " + "\". Ensure there is a stage to guarantee replacement of the placeholder biome. " +
"Biomes: " +
biomeList); biomeList);
} }
this.biomes.add(pipelineBiome.getBiome()); this.biomes.add(pipelineBiome.getBiome());
}); });
} }
@Override @Override
public Biome getBiome(int x, int y, int z, long seed) { public Biome getBiome(int x, int y, int z, long seed) {
return getBiome(x, z, seed); return getBiome(x, z, seed);
} }
public Biome getBiome(int x, int z, long seed) { public Biome getBiome(int x, int z, long seed) {
x += mutator.noise(seed + 1, x, z) * noiseAmp; x += mutator.noise(seed + 1, x, z) * noiseAmp;
z += mutator.noise(seed + 2, x, z) * noiseAmp; z += mutator.noise(seed + 2, x, z) * noiseAmp;
x /= resolution; x /= resolution;
z /= resolution; z /= resolution;
int chunkX = FastMath.floorDiv(x, chunkSize); int chunkX = Math.floorDiv(x, chunkSize);
int chunkZ = FastMath.floorDiv(z, chunkSize); int chunkZ = Math.floorDiv(z, chunkSize);
int chunkWorldX = chunkX * chunkSize; int chunkWorldX = chunkX * chunkSize;
int chunkWorldZ = chunkZ * chunkSize; int chunkWorldZ = chunkZ * chunkSize;
int xInChunk = x - chunkWorldX; int xInChunk = x - chunkWorldX;
int zInChunk = z - chunkWorldZ; int zInChunk = z - chunkWorldZ;
return biomeChunkCache.get(new SeededVector(seed, chunkWorldX, chunkWorldZ)).get(xInChunk, zInChunk).getBiome(); return biomeChunkCache.get(new SeededVector(seed, chunkWorldX, chunkWorldZ)).get(xInChunk, zInChunk).getBiome();
} }
@Override @Override
public Iterable<Biome> getBiomes() { public Iterable<Biome> getBiomes() {
return biomes; return biomes;
} }
@Override @Override
public Optional<Biome> getBaseBiome(int x, int z, long seed) { public Optional<Biome> getBaseBiome(int x, int z, long seed) {
return Optional.of(getBiome(x, z, seed)); return Optional.of(getBiome(x, z, seed));
} }
@Override @Override
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) { public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
return new BiomePipelineColumn(this, min, max, x, z, seed); return new BiomePipelineColumn(this, min, max, x, z, seed);
} }
@Override @Override
public int resolution() { public int resolution() {
return resolution; return resolution;
@@ -5,6 +5,6 @@ import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
public interface BiomeChunk { public interface BiomeChunk {
PipelineBiome get(int xInChunk, int zInChunk); PipelineBiome get(int xInChunk, int zInChunk);
} }
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api; package com.dfsek.terra.addons.biome.pipeline.v2.api;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
/** /**
@@ -9,14 +9,14 @@ import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
* filling in null biomes as a result of this resizing. * filling in null biomes as a result of this resizing.
*/ */
public interface Expander extends Stage { public interface Expander extends Stage {
PipelineBiome fillBiome(ViewPoint viewPoint); PipelineBiome fillBiome(ViewPoint viewPoint);
@Override @Override
default int maxRelativeReadDistance() { default int maxRelativeReadDistance() {
return 0; return 0;
} }
@Override @Override
default PipelineBiome apply(ViewPoint viewPoint) { default PipelineBiome apply(ViewPoint viewPoint) {
PipelineBiome currentBiome = viewPoint.getBiome(); PipelineBiome currentBiome = viewPoint.getBiome();
@@ -5,10 +5,10 @@ import java.util.List;
public interface Pipeline { public interface Pipeline {
BiomeChunk generateChunk(SeededVector worldCoordinates); BiomeChunk generateChunk(SeededVector worldCoordinates);
int getChunkSize(); int getChunkSize();
Source getSource(); Source getSource();
List<Stage> getStages(); List<Stage> getStages();
} }
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api; package com.dfsek.terra.addons.biome.pipeline.v2.api;
public record SeededVector(long seed, int x, int z) { public record SeededVector(long seed, int x, int z) {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(obj instanceof SeededVector that) { if(obj instanceof SeededVector that) {
@@ -9,7 +9,7 @@ public record SeededVector(long seed, int x, int z) {
} }
return false; return false;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int code = x; int code = x;
@@ -6,6 +6,6 @@ import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
public interface Source { public interface Source {
PipelineBiome get(long seed, int x, int z); PipelineBiome get(long seed, int x, int z);
Iterable<PipelineBiome> getBiomes(); Iterable<PipelineBiome> getBiomes();
} }
@@ -1,14 +1,14 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api; package com.dfsek.terra.addons.biome.pipeline.v2.api;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; 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 { public interface Stage {
PipelineBiome apply(ViewPoint viewPoint); PipelineBiome apply(ViewPoint viewPoint);
int maxRelativeReadDistance(); int maxRelativeReadDistance();
default Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) { default Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
return biomes; return biomes;
} }
@@ -7,32 +7,32 @@ import com.dfsek.terra.api.world.biome.Biome;
public final class DelegatedPipelineBiome implements PipelineBiome { public final class DelegatedPipelineBiome implements PipelineBiome {
private final Biome biome; private final Biome biome;
public DelegatedPipelineBiome(Biome biome) { public DelegatedPipelineBiome(Biome biome) {
this.biome = biome; this.biome = biome;
} }
@Override @Override
public Biome getBiome() { public Biome getBiome() {
return biome; return biome;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return biome.hashCode(); return biome.hashCode();
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof DelegatedPipelineBiome that)) return false; if(!(obj instanceof DelegatedPipelineBiome that)) return false;
return that.biome.equals(this.biome); return that.biome.equals(this.biome);
} }
@Override @Override
public Set<String> getTags() { public Set<String> getTags() {
return biome.getTags(); return biome.getTags();
} }
@Override @Override
public String getID() { public String getID() {
return biome.getID(); return biome.getID();
@@ -7,29 +7,29 @@ import com.dfsek.terra.api.world.biome.Biome;
public interface PipelineBiome extends StringIdentifiable { public interface PipelineBiome extends StringIdentifiable {
Biome getBiome();
static PipelineBiome placeholder(String id) { static PipelineBiome placeholder(String id) {
return new PlaceholderPipelineBiome(id); return new PlaceholderPipelineBiome(id);
} }
static PipelineBiome from(Biome biome) { static PipelineBiome from(Biome biome) {
return new DelegatedPipelineBiome(biome); return new DelegatedPipelineBiome(biome);
} }
static PipelineBiome self() { static PipelineBiome self() {
return SelfPipelineBiome.INSTANCE; return SelfPipelineBiome.INSTANCE;
} }
Biome getBiome();
Set<String> getTags(); Set<String> getTags();
default boolean isPlaceholder() { default boolean isPlaceholder() {
return false; return false;
} }
default boolean isSelf() { default boolean isSelf() {
return false; return false;
} }
} }
@@ -9,43 +9,43 @@ import com.dfsek.terra.api.world.biome.Biome;
final class PlaceholderPipelineBiome implements PipelineBiome { final class PlaceholderPipelineBiome implements PipelineBiome {
private final Set<String> tags; private final Set<String> tags;
private final String id; private final String id;
public PlaceholderPipelineBiome(String id) { public PlaceholderPipelineBiome(String id) {
this.id = id; this.id = id;
tags = new HashSet<>(); tags = new HashSet<>();
tags.add(id); tags.add(id);
tags.add("ALL"); tags.add("ALL");
} }
@Override @Override
public Biome getBiome() { public Biome getBiome() {
throw new UnsupportedOperationException("Cannot get raw biome from placeholder pipeline biome"); throw new UnsupportedOperationException("Cannot get raw biome from placeholder pipeline biome");
} }
@Override @Override
public Set<String> getTags() { public Set<String> getTags() {
return tags; return tags;
} }
@Override @Override
public String getID() { public String getID() {
return id; return id;
} }
@Override @Override
public boolean isPlaceholder() { public boolean isPlaceholder() {
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return id.hashCode(); return id.hashCode();
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof PlaceholderPipelineBiome that)) return false; if(!(obj instanceof PlaceholderPipelineBiome that)) return false;
return this.id.equals(that.id); return this.id.equals(that.id);
} }
} }
@@ -8,31 +8,31 @@ import com.dfsek.terra.api.world.biome.Biome;
final class SelfPipelineBiome implements PipelineBiome { final class SelfPipelineBiome implements PipelineBiome {
public static final SelfPipelineBiome INSTANCE = new SelfPipelineBiome(); public static final SelfPipelineBiome INSTANCE = new SelfPipelineBiome();
private SelfPipelineBiome() { private SelfPipelineBiome() {
} }
@Override @Override
public Biome getBiome() { public Biome getBiome() {
throw new UnsupportedOperationException("Cannot get biome from self delegate"); throw new UnsupportedOperationException("Cannot get biome from self delegate");
} }
@Override @Override
public boolean isSelf() { public boolean isSelf() {
return true; return true;
} }
@Override @Override
public boolean isPlaceholder() { public boolean isPlaceholder() {
return true; return true;
} }
@Override @Override
public Set<String> getTags() { public Set<String> getTags() {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override @Override
public String getID() { public String getID() {
return "SELF"; return "SELF";
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -15,9 +15,9 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.List; import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.v2.PipelineBiomeProvider; import com.dfsek.terra.addons.biome.pipeline.v2.PipelineBiomeProvider;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.PipelineImpl;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source; import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; 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.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -29,29 +29,25 @@ public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
@Default @Default
@Description(""" @Description("""
The resolution at which to sample biomes. The resolution at which to sample biomes.
Larger values are quadratically faster, but produce lower quality results. Larger values are quadratically faster, but produce lower quality results.
For example, a value of 3 would sample every 3 blocks.""") For example, a value of 3 would sample every 3 blocks.""")
protected @Meta int resolution = 1; protected @Meta int resolution = 1;
@Value("pipeline.source")
@Description("The Biome Source to use for initial population of biomes.")
private @Meta Source source;
@Value("pipeline.stages")
@Description("A list of pipeline stages to apply to the result of #source")
private @Meta List<@Meta Stage> stages;
@Value("blend.sampler") @Value("blend.sampler")
@Default @Default
@Description("A sampler to use for blending the edges of biomes via domain warping.") @Description("A sampler to use for blending the edges of biomes via domain warping.")
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero(); protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
@Value("blend.amplitude") @Value("blend.amplitude")
@Default @Default
@Description("The amplitude at which to perform blending.") @Description("The amplitude at which to perform blending.")
protected @Meta double blendAmplitude = 0d; 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 @Override
public BiomeProvider get() { public BiomeProvider get() {
return new PipelineBiomeProvider(new PipelineImpl(source, stages, resolution, 128), resolution, blendSampler, blendAmplitude); return new PipelineBiomeProvider(new PipelineImpl(source, stages, resolution, 128), resolution, blendSampler, blendAmplitude);
@@ -15,18 +15,18 @@ import com.dfsek.terra.api.world.biome.Biome;
public class PipelineBiomeLoader implements TypeLoader<PipelineBiome> { public class PipelineBiomeLoader implements TypeLoader<PipelineBiome> {
private final Registry<Biome> biomeRegistry; private final Registry<Biome> biomeRegistry;
public PipelineBiomeLoader(Registry<Biome> biomeRegistry) { public PipelineBiomeLoader(Registry<Biome> biomeRegistry) {
this.biomeRegistry = biomeRegistry; this.biomeRegistry = biomeRegistry;
} }
@Override @Override
public PipelineBiome load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) public PipelineBiome load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
throws LoadException { throws LoadException {
if(c.equals("SELF")) return PipelineBiome.self(); if(c.equals("SELF")) return PipelineBiome.self();
return biomeRegistry return biomeRegistry
.getByID((String) c) .getByID((String) c)
.map(PipelineBiome::from) .map(PipelineBiome::from)
.orElseGet(() -> PipelineBiome.placeholder((String) c)); .orElseGet(() -> PipelineBiome.placeholder((String) c));
} }
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -22,11 +22,11 @@ public class SamplerSourceTemplate extends SourceTemplate {
@Value("sampler") @Value("sampler")
@Description("The sampler used to distribute biomes.") @Description("The sampler used to distribute biomes.")
private @Meta NoiseSampler noise; private @Meta NoiseSampler noise;
@Value("biomes") @Value("biomes")
@Description("The biomes to be distributed.") @Description("The biomes to be distributed.")
private @Meta ProbabilityCollection<@Meta PipelineBiome> biomes; private @Meta ProbabilityCollection<@Meta PipelineBiome> biomes;
@Override @Override
public Source get() { public Source get() {
return new SamplerSource(biomes, noise); return new SamplerSource(biomes, noise);
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -7,8 +7,8 @@
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander; package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander; import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.expander.FractalExpander; import com.dfsek.terra.addons.biome.pipeline.v2.stage.expander.FractalExpander;
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -11,9 +11,9 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.Map; import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; 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.addons.biome.pipeline.v2.stage.mutators.BorderListStage;
import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -23,17 +23,17 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class BorderListStageTemplate extends StageTemplate { public class BorderListStageTemplate extends StageTemplate {
@Value("from") @Value("from")
private @Meta String from; private @Meta String from;
@Value("default-replace") @Value("default-replace")
private @Meta String defaultReplace; private @Meta String defaultReplace;
@Value("default-to") @Value("default-to")
private @Meta ProbabilityCollection<@Meta PipelineBiome> defaultTo; private @Meta ProbabilityCollection<@Meta PipelineBiome> defaultTo;
@Value("replace") @Value("replace")
private @Meta Map<@Meta PipelineBiome, @Meta ProbabilityCollection<@Meta PipelineBiome>> replace; private @Meta Map<@Meta PipelineBiome, @Meta ProbabilityCollection<@Meta PipelineBiome>> replace;
@Override @Override
public Stage get() { public Stage get() {
return new BorderListStage(replace, from, defaultReplace, noise, defaultTo); return new BorderListStage(replace, from, defaultReplace, noise, defaultTo);
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -9,9 +9,9 @@ package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
import com.dfsek.tectonic.api.config.template.annotations.Value; import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; 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.addons.biome.pipeline.v2.stage.mutators.BorderStage;
import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -21,13 +21,13 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class BorderStageTemplate extends StageTemplate { public class BorderStageTemplate extends StageTemplate {
@Value("from") @Value("from")
private @Meta String from; private @Meta String from;
@Value("replace") @Value("replace")
private @Meta String replace; private @Meta String replace;
@Value("to") @Value("to")
private @Meta ProbabilityCollection<@Meta PipelineBiome> to; private @Meta ProbabilityCollection<@Meta PipelineBiome> to;
@Override @Override
public Stage get() { public Stage get() {
return new BorderStage(from, replace, noise, to); return new BorderStage(from, replace, noise, to);
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -11,9 +11,9 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.Map; import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; 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.addons.biome.pipeline.v2.stage.mutators.ReplaceListStage;
import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -23,13 +23,13 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class ReplaceListStageTemplate extends StageTemplate { public class ReplaceListStageTemplate extends StageTemplate {
@Value("default-from") @Value("default-from")
private @Meta String defaultFrom; private @Meta String defaultFrom;
@Value("default-to") @Value("default-to")
private @Meta ProbabilityCollection<@Meta PipelineBiome> defaultTo; private @Meta ProbabilityCollection<@Meta PipelineBiome> defaultTo;
@Value("to") @Value("to")
private @Meta Map<@Meta PipelineBiome, @Meta ProbabilityCollection<@Meta PipelineBiome>> replace; private @Meta Map<@Meta PipelineBiome, @Meta ProbabilityCollection<@Meta PipelineBiome>> replace;
@Override @Override
public Stage get() { public Stage get() {
return new ReplaceListStage(replace, defaultFrom, defaultTo, noise); return new ReplaceListStage(replace, defaultFrom, defaultTo, noise);
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -9,9 +9,9 @@ package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
import com.dfsek.tectonic.api.config.template.annotations.Value; import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; 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.addons.biome.pipeline.v2.stage.mutators.ReplaceStage;
import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -21,10 +21,10 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class ReplaceStageTemplate extends StageTemplate { public class ReplaceStageTemplate extends StageTemplate {
@Value("from") @Value("from")
private @Meta String from; private @Meta String from;
@Value("to") @Value("to")
private @Meta ProbabilityCollection<@Meta PipelineBiome> to; private @Meta ProbabilityCollection<@Meta PipelineBiome> to;
@Override @Override
public Stage get() { public Stage get() {
return new ReplaceStage(from, to, noise); return new ReplaceStage(from, to, noise);
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -7,8 +7,8 @@
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator; package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.SmoothStage; import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.SmoothStage;
@@ -1,53 +1,54 @@
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline; 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.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander; 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.SeededVector;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; 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.api.biome.PipelineBiome;
import net.jafama.FastMath;
import java.util.List;
public class BiomeChunkImpl implements BiomeChunk { public class BiomeChunkImpl implements BiomeChunk {
private PipelineBiome[][] biomes;
private final SeededVector worldOrigin; private final SeededVector worldOrigin;
private final int chunkOriginArrayIndex; private final int chunkOriginArrayIndex;
private final int worldCoordinateScale; private final int worldCoordinateScale;
private final int size;
private PipelineBiome[] biomes;
public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) { public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) {
this.worldOrigin = worldOrigin; this.worldOrigin = worldOrigin;
this.chunkOriginArrayIndex = pipeline.getChunkOriginArrayIndex(); this.chunkOriginArrayIndex = pipeline.getChunkOriginArrayIndex();
this.worldCoordinateScale = pipeline.getResolution(); this.worldCoordinateScale = pipeline.getResolution();
int size = pipeline.getArraySize(); this.size = pipeline.getArraySize();
int expanderCount = pipeline.getExpanderCount(); int expanderCount = pipeline.getExpanderCount();
int expansionsApplied = 0; int expansionsApplied = 0;
// Allocate working arrays // Allocate working arrays
this.biomes = new PipelineBiome[size][size]; this.biomes = new PipelineBiome[size * size];
PipelineBiome[][] lookupArray = 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 // A second lookup array is required such that stage application doesn't affect lookups, otherwise application may cascade
// Construct working grid // Construct working grid
int gridOrigin = 0; int gridOrigin = 0;
int gridInterval = calculateGridInterval(expanderCount, expansionsApplied); int gridInterval = calculateGridInterval(expanderCount, expansionsApplied);
int gridSize = (size / gridInterval); int gridSize = (size / gridInterval);
gridSize += expanderCount > 0 ? 1 : 0; // Add an extra border if expansion occurs gridSize += expanderCount > 0 ? 1 : 0; // Add an extra border if expansion occurs
// Fill working grid with initial cells // Fill working grid with initial cells
for(int gridX = 0; gridX < gridSize; gridX++) { for(int gridX = 0; gridX < gridSize; gridX++) {
for(int gridZ = 0; gridZ < gridSize; gridZ++) { for(int gridZ = 0; gridZ < gridSize; gridZ++) {
int xIndex = gridOrigin + gridX * gridInterval; int xIndex = gridOrigin + gridX * gridInterval;
int zIndex = gridOrigin + gridZ * gridInterval; int zIndex = gridOrigin + gridZ * gridInterval;
biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex), zIndexToWorldCoordinate(zIndex)); biomes[(xIndex * size) + zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex),
zIndexToWorldCoordinate(zIndex));
} }
} }
for(Stage stage : pipeline.getStages()) { for(Stage stage : pipeline.getStages()) {
if(stage instanceof Expander) { if(stage instanceof Expander) {
// Shrink working grid size, the expander will fill in null cells (as a result of shrinking the grid) during mutation // Shrink working grid size, the expander will fill in null cells (as a result of shrinking the grid) during mutation
@@ -55,46 +56,32 @@ public class BiomeChunkImpl implements BiomeChunk {
gridInterval = calculateGridInterval(expanderCount, expansionsApplied); gridInterval = calculateGridInterval(expanderCount, expansionsApplied);
gridSize = expandSize(gridSize); gridSize = expandSize(gridSize);
} }
int stageReadDistance = stage.maxRelativeReadDistance(); int stageReadDistance = stage.maxRelativeReadDistance();
if(stageReadDistance > 0) { if(stageReadDistance > 0) {
// Discard edges such that adjacent lookups are only ran on valid cells // Discard edges such that adjacent lookups are only ran on valid cells
gridSize = contractBordersFromSize(gridSize, stageReadDistance); gridSize = contractBordersFromSize(gridSize, stageReadDistance);
gridOrigin += stageReadDistance * gridInterval; gridOrigin += stageReadDistance * gridInterval;
} }
// Cycle arrays, the previously populated array is swapped to be used for lookups, and the result of the stage application // 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 // overwrites the previous lookup array. This saves having to allocate a new array copy each time
PipelineBiome[][] tempArray = biomes; PipelineBiome[] tempArray = biomes;
biomes = lookupArray; biomes = lookupArray;
lookupArray = tempArray; lookupArray = tempArray;
// Apply stage to working grid // Apply stage to working grid
for(int gridZ = 0; gridZ < gridSize; gridZ = gridZ + 1) { for(int gridZ = 0; gridZ < gridSize; gridZ = gridZ + 1) {
for(int gridX = 0; gridX < gridSize; gridX = gridX + 1) { for(int gridX = 0; gridX < gridSize; gridX = gridX + 1) {
int xIndex = gridOrigin + gridX * gridInterval; int xIndex = gridOrigin + gridX * gridInterval;
int zIndex = gridOrigin + gridZ * gridInterval; int zIndex = gridOrigin + gridZ * gridInterval;
biomes[xIndex][zIndex] = stage.apply(new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray)); biomes[(xIndex * size) + zIndex] = stage.apply(
new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray, size));
} }
} }
} }
} }
@Override
public PipelineBiome get(int xInChunk, int zInChunk) {
int xIndex = xInChunk + chunkOriginArrayIndex;
int zIndex = zInChunk + chunkOriginArrayIndex;
return biomes[xIndex][zIndex];
}
private int xIndexToWorldCoordinate(int xIndex) {
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
private int zIndexToWorldCoordinate(int zIndex) {
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
protected static int initialSizeToArraySize(int expanderCount, int initialSize) { protected static int initialSizeToArraySize(int expanderCount, int initialSize) {
int size = initialSize; int size = initialSize;
for(int i = 0; i < expanderCount; i++) { for(int i = 0; i < expanderCount; i++) {
@@ -102,24 +89,24 @@ public class BiomeChunkImpl implements BiomeChunk {
} }
return size; return size;
} }
protected static int calculateChunkOriginArrayIndex(int totalExpanderCount, List<Stage> stages) { protected static int calculateChunkOriginArrayIndex(int totalExpanderCount, List<Stage> stages) {
int finalGridOrigin = calculateFinalGridOrigin(totalExpanderCount, stages); int finalGridOrigin = calculateFinalGridOrigin(totalExpanderCount, stages);
int initialGridInterval = calculateGridInterval(totalExpanderCount, 0); int initialGridInterval = calculateGridInterval(totalExpanderCount, 0);
// Round the final grid origin up to the nearest multiple of initialGridInterval, such that each // Round the final grid origin up to the nearest multiple of initialGridInterval, such that each
// chunk samples points on the same overall grid. // chunk samples points on the same overall grid.
// Without this, shared chunk borders (required because of adjacent cell reads) will not be identical // 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. // because points would be sampled on grids at different offsets, resulting in artifacts at borders.
return FastMath.ceilToInt((double) finalGridOrigin / initialGridInterval) * initialGridInterval; return (int) Math.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
} }
private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) { private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) {
int gridOrigin = 0; int gridOrigin = 0;
int expansionsApplied = 0; int expansionsApplied = 0;
int gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied); int gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
for (Stage stage : stages) { for(Stage stage : stages) {
if (stage instanceof Expander) { if(stage instanceof Expander) {
expansionsApplied++; expansionsApplied++;
gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied); gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
} }
@@ -127,27 +114,42 @@ public class BiomeChunkImpl implements BiomeChunk {
} }
return gridOrigin; return gridOrigin;
} }
protected static int calculateChunkSize(int arraySize, int chunkOriginArrayIndex, int totalExpanderCount) { protected static int calculateChunkSize(int arraySize, int chunkOriginArrayIndex, int totalExpanderCount) {
return contractBordersFromSize(arraySize, chunkOriginArrayIndex) - (totalExpanderCount > 0 ? 1 : 0); return contractBordersFromSize(arraySize, chunkOriginArrayIndex) - (totalExpanderCount > 0 ? 1 : 0);
} }
private static int expandSize(int size) { private static int expandSize(int size) {
return size * 2 - 1; return size * 2 - 1;
} }
private static int contractBordersFromSize(int size, int border) { private static int contractBordersFromSize(int size, int border) {
return size - border * 2; return size - border * 2;
} }
private static int calculateGridInterval(int totalExpansions, int expansionsApplied) { private static int calculateGridInterval(int totalExpansions, int expansionsApplied) {
return 1 << (totalExpansions - expansionsApplied); return 1 << (totalExpansions - expansionsApplied);
} }
@Override
public PipelineBiome get(int xInChunk, int zInChunk) {
int xIndex = xInChunk + chunkOriginArrayIndex;
int zIndex = zInChunk + chunkOriginArrayIndex;
return biomes[(xIndex * size) + 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() { private SeededVector getOrigin() {
return worldOrigin; return worldOrigin;
} }
/** /**
* Represents a point on the operating grid within the biomes array * Represents a point on the operating grid within the biomes array
*/ */
@@ -159,9 +161,11 @@ public class BiomeChunkImpl implements BiomeChunk {
private final int gridZ; private final int gridZ;
private final int xIndex; private final int xIndex;
private final int zIndex; private final int zIndex;
private final PipelineBiome[][] lookupArray; private final PipelineBiome[] lookupArray;
private final int size;
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex, PipelineBiome[][] lookupArray) {
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex,
PipelineBiome[] lookupArray, int size) {
this.chunk = chunk; this.chunk = chunk;
this.gridInterval = gridInterval; this.gridInterval = gridInterval;
this.gridX = gridX; this.gridX = gridX;
@@ -169,47 +173,48 @@ public class BiomeChunkImpl implements BiomeChunk {
this.xIndex = xIndex; this.xIndex = xIndex;
this.zIndex = zIndex; this.zIndex = zIndex;
this.lookupArray = lookupArray; this.lookupArray = lookupArray;
this.biome = lookupArray[xIndex][zIndex]; this.size = size;
this.biome = lookupArray[(this.xIndex * this.size) + this.zIndex];
} }
public PipelineBiome getRelativeBiome(int x, int z) { public PipelineBiome getRelativeBiome(int x, int z) {
int lookupXIndex = this.xIndex + x * gridInterval; int lookupXIndex = this.xIndex + x * gridInterval;
int lookupZIndex = this.zIndex + z * gridInterval; int lookupZIndex = this.zIndex + z * gridInterval;
return lookupArray[lookupXIndex][lookupZIndex]; return lookupArray[(lookupXIndex * this.size) + lookupZIndex];
} }
public PipelineBiome getBiome() { public PipelineBiome getBiome() {
return biome; return biome;
} }
/** /**
* @return X position of the point relative to the operating grid * @return X position of the point relative to the operating grid
*/ */
public int gridX() { public int gridX() {
return gridX; return gridX;
} }
/** /**
* @return Z position of the point relative to the operating grid * @return Z position of the point relative to the operating grid
*/ */
public int gridZ() { public int gridZ() {
return gridZ; return gridZ;
} }
/** /**
* @return X position of the point in the world * @return X position of the point in the world
*/ */
public int worldX() { public int worldX() {
return chunk.xIndexToWorldCoordinate(xIndex); return chunk.xIndexToWorldCoordinate(xIndex);
} }
/** /**
* @return Z position of the point in the world * @return Z position of the point in the world
*/ */
public int worldZ() { public int worldZ() {
return chunk.zIndexToWorldCoordinate(zIndex); return chunk.zIndexToWorldCoordinate(zIndex);
} }
public long worldSeed() { public long worldSeed() {
return chunk.getOrigin().seed(); return chunk.getOrigin().seed();
} }
@@ -14,9 +14,9 @@ import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
public class PipelineImpl implements Pipeline { public class PipelineImpl implements Pipeline {
private static final Logger logger = LoggerFactory.getLogger(PipelineImpl.class); private static final Logger logger = LoggerFactory.getLogger(PipelineImpl.class);
private final Source source; private final Source source;
private final List<Stage> stages; private final List<Stage> stages;
private final int chunkSize; private final int chunkSize;
@@ -24,68 +24,68 @@ public class PipelineImpl implements Pipeline {
private final int arraySize; private final int arraySize;
private final int chunkOriginArrayIndex; private final int chunkOriginArrayIndex;
private final int resolution; private final int resolution;
public PipelineImpl(Source source, List<Stage> stages, int resolution, int idealChunkArraySize) { public PipelineImpl(Source source, List<Stage> stages, int resolution, int idealChunkArraySize) {
this.source = source; this.source = source;
this.stages = stages; this.stages = stages;
this.resolution = resolution; this.resolution = resolution;
this.expanderCount = (int) stages.stream().filter(s -> s instanceof Expander).count(); this.expanderCount = (int) stages.stream().filter(s -> s instanceof Expander).count();
// Optimize for the ideal array size // Optimize for the ideal array size
int arraySize; int arraySize;
int chunkOriginArrayIndex; int chunkOriginArrayIndex;
int chunkSize; int chunkSize;
int initialSize = 1; int initialSize = 1;
while (true) { while(true) {
arraySize = BiomeChunkImpl.initialSizeToArraySize(expanderCount, initialSize); arraySize = BiomeChunkImpl.initialSizeToArraySize(expanderCount, initialSize);
chunkOriginArrayIndex = BiomeChunkImpl.calculateChunkOriginArrayIndex(expanderCount, stages); chunkOriginArrayIndex = BiomeChunkImpl.calculateChunkOriginArrayIndex(expanderCount, stages);
chunkSize = BiomeChunkImpl.calculateChunkSize(arraySize, chunkOriginArrayIndex, expanderCount); chunkSize = BiomeChunkImpl.calculateChunkSize(arraySize, chunkOriginArrayIndex, expanderCount);
if (chunkSize > 1 && arraySize >= idealChunkArraySize) break; if(chunkSize > 1 && arraySize >= idealChunkArraySize) break;
initialSize++; initialSize++;
} }
this.arraySize = arraySize; this.arraySize = arraySize;
this.chunkOriginArrayIndex = chunkOriginArrayIndex; this.chunkOriginArrayIndex = chunkOriginArrayIndex;
this.chunkSize = chunkSize; this.chunkSize = chunkSize;
logger.debug("Initialized a new biome pipeline:"); logger.debug("Initialized a new biome pipeline:");
logger.debug("Array size: {} (Target: {})", arraySize, idealChunkArraySize); logger.debug("Array size: {} (Target: {})", arraySize, idealChunkArraySize);
logger.debug("Internal array origin: {}", chunkOriginArrayIndex); logger.debug("Internal array origin: {}", chunkOriginArrayIndex);
logger.debug("Chunk size: {}", chunkSize); logger.debug("Chunk size: {}", chunkSize);
} }
@Override @Override
public BiomeChunk generateChunk(SeededVector worldCoordinates) { public BiomeChunk generateChunk(SeededVector worldCoordinates) {
return new BiomeChunkImpl(worldCoordinates, this); return new BiomeChunkImpl(worldCoordinates, this);
} }
@Override @Override
public int getChunkSize() { public int getChunkSize() {
return chunkSize; return chunkSize;
} }
@Override @Override
public Source getSource() { public Source getSource() {
return source; return source;
} }
@Override @Override
public List<Stage> getStages() { public List<Stage> getStages() {
return stages; return stages;
} }
protected int getExpanderCount() { protected int getExpanderCount() {
return expanderCount; return expanderCount;
} }
protected int getArraySize() { protected int getArraySize() {
return arraySize; return arraySize;
} }
protected int getChunkOriginArrayIndex() { protected int getChunkOriginArrayIndex() {
return chunkOriginArrayIndex; return chunkOriginArrayIndex;
} }
protected int getResolution() { protected int getResolution() {
return resolution; return resolution;
} }
@@ -9,17 +9,17 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class SamplerSource implements Source { public class SamplerSource implements Source {
private final ProbabilityCollection<PipelineBiome> biomes; private final ProbabilityCollection<PipelineBiome> biomes;
private final NoiseSampler sampler; private final NoiseSampler sampler;
public SamplerSource(ProbabilityCollection<PipelineBiome> biomes, NoiseSampler sampler) { public SamplerSource(ProbabilityCollection<PipelineBiome> biomes, NoiseSampler sampler) {
this.biomes = biomes; this.biomes = biomes;
this.sampler = sampler; this.sampler = sampler;
} }
@Override @Override
public PipelineBiome get(long seed, int x, int z) { public PipelineBiome get(long seed, int x, int z) {
return biomes.get(sampler, x, z, seed); return biomes.get(sampler, x, z, seed);
} }
@Override @Override
public Iterable<PipelineBiome> getBiomes() { public Iterable<PipelineBiome> getBiomes() {
return biomes.getContents(); return biomes.getContents();
@@ -3,23 +3,23 @@ package com.dfsek.terra.addons.biome.pipeline.v2.source;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source; 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 { public class SingleSource implements Source {
private final PipelineBiome biome; private final PipelineBiome biome;
public SingleSource(PipelineBiome biome) { public SingleSource(PipelineBiome biome) {
this.biome = biome; this.biome = biome;
} }
@Override @Override
public PipelineBiome get(long seed, int x, int z) { public PipelineBiome get(long seed, int x, int z) {
return biome; return biome;
} }
@Override @Override
public Set<PipelineBiome> getBiomes() { public Set<PipelineBiome> getBiomes() {
return Collections.singleton(biome); return Collections.singleton(biome);
@@ -7,30 +7,30 @@ import com.dfsek.terra.api.noise.NoiseSampler;
public class FractalExpander implements Expander { public class FractalExpander implements Expander {
private final NoiseSampler sampler; private final NoiseSampler sampler;
public FractalExpander(NoiseSampler sampler) { public FractalExpander(NoiseSampler sampler) {
this.sampler = sampler; this.sampler = sampler;
} }
@Override @Override
public PipelineBiome fillBiome(BiomeChunkImpl.ViewPoint viewPoint) { public PipelineBiome fillBiome(BiomeChunkImpl.ViewPoint viewPoint) {
int xMod2 = viewPoint.gridX() % 2; int xMod2 = viewPoint.gridX() % 2;
int zMod2 = viewPoint.gridZ() % 2; int zMod2 = viewPoint.gridZ() % 2;
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ()); double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
if (xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly 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); 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 } 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); return roll > 0 ? viewPoint.getRelativeBiome(0, -1) : viewPoint.getRelativeBiome(0, 1);
} else { // Pick one of 4 corners randomly } else { // Pick one of 4 corners randomly
return roll > 0 ? 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) :
roll > -0.25 ? viewPoint.getRelativeBiome(-1, -1) : viewPoint.getRelativeBiome(1, -1); roll > -0.25 ? viewPoint.getRelativeBiome(-1, -1) : viewPoint.getRelativeBiome(1, -1);
} }
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -28,9 +28,9 @@ public class BorderListStage implements Stage {
private final ProbabilityCollection<PipelineBiome> replaceDefault; private final ProbabilityCollection<PipelineBiome> replaceDefault;
private final String defaultReplace; private final String defaultReplace;
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace; private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
private final Vector2Int[] borderPoints; private final Vector2Int[] borderPoints;
public BorderListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String border, String defaultReplace, public BorderListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String border, String defaultReplace,
NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replaceDefault) { NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replaceDefault) {
this.border = border; this.border = border;
@@ -38,7 +38,7 @@ public class BorderListStage implements Stage {
this.replaceDefault = replaceDefault; this.replaceDefault = replaceDefault;
this.defaultReplace = defaultReplace; this.defaultReplace = defaultReplace;
this.replace = replace; this.replace = replace;
List<Vector2Int> points = new ArrayList<>(); List<Vector2Int> points = new ArrayList<>();
for(int x = -1; x <= 1; x++) { for(int x = -1; x <= 1; x++) {
for(int z = -1; z <= 1; z++) { for(int z = -1; z <= 1; z++) {
@@ -47,9 +47,9 @@ public class BorderListStage implements Stage {
} }
} }
this.borderPoints = points.toArray(new Vector2Int[0]); this.borderPoints = points.toArray(new Vector2Int[0]);
} }
@Override @Override
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) { public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
Set<PipelineBiome> biomeSet = new HashSet<>(); Set<PipelineBiome> biomeSet = new HashSet<>();
@@ -58,7 +58,7 @@ public class BorderListStage implements Stage {
replace.forEach((biome, collection) -> biomeSet.addAll(collection.getContents())); replace.forEach((biome, collection) -> biomeSet.addAll(collection.getContents()));
return biomeSet; return biomeSet;
} }
@Override @Override
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) { public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
PipelineBiome center = viewPoint.getBiome(); PipelineBiome center = viewPoint.getBiome();
@@ -68,17 +68,18 @@ public class BorderListStage implements Stage {
if(current != null && current.getTags().contains(border)) { if(current != null && current.getTags().contains(border)) {
if(replace.containsKey(center)) { if(replace.containsKey(center)) {
PipelineBiome replacement = replace.get(center).get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), PipelineBiome replacement = replace.get(center).get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
viewPoint.worldSeed()); viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement; return replacement.isSelf() ? center : replacement;
} }
PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed()); PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement; return replacement.isSelf() ? center : replacement;
} }
} }
} }
return center; return center;
} }
@Override @Override
public int maxRelativeReadDistance() { public int maxRelativeReadDistance() {
return 1; return 1;
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -27,7 +27,7 @@ public class BorderStage implements Stage {
private final ProbabilityCollection<PipelineBiome> replace; private final ProbabilityCollection<PipelineBiome> replace;
private final String replaceTag; private final String replaceTag;
private final Vector2Int[] borderPoints; private final Vector2Int[] borderPoints;
public BorderStage(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replace) { public BorderStage(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replace) {
this.border = border; this.border = border;
this.noiseSampler = noiseSampler; this.noiseSampler = noiseSampler;
@@ -42,7 +42,7 @@ public class BorderStage implements Stage {
} }
this.borderPoints = points.toArray(new Vector2Int[0]); this.borderPoints = points.toArray(new Vector2Int[0]);
} }
@Override @Override
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) { public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
PipelineBiome center = viewPoint.getBiome(); PipelineBiome center = viewPoint.getBiome();
@@ -57,23 +57,23 @@ public class BorderStage implements Stage {
} }
return center; return center;
} }
@Override @Override
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) { public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
Set<PipelineBiome> biomeSet = new HashSet<>(); Set<PipelineBiome> biomeSet = new HashSet<>();
biomes.forEach(biomeSet::add); biomes.forEach(biomeSet::add);
biomeSet.addAll( biomeSet.addAll(
replace replace
.getContents() .getContents()
.stream() .stream()
.filter( .filter(
Predicate.not(PipelineBiome::isSelf) Predicate.not(PipelineBiome::isSelf)
) )
.toList() .toList()
); );
return biomeSet; return biomeSet;
} }
@Override @Override
public int maxRelativeReadDistance() { public int maxRelativeReadDistance() {
return 1; return 1;
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -24,7 +24,7 @@ public class ReplaceListStage implements Stage {
private final NoiseSampler sampler; private final NoiseSampler sampler;
private final ProbabilityCollection<PipelineBiome> replaceDefault; private final ProbabilityCollection<PipelineBiome> replaceDefault;
private final String defaultTag; private final String defaultTag;
public ReplaceListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String defaultTag, public ReplaceListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String defaultTag,
ProbabilityCollection<PipelineBiome> replaceDefault, NoiseSampler sampler) { ProbabilityCollection<PipelineBiome> replaceDefault, NoiseSampler sampler) {
this.replace = replace; this.replace = replace;
@@ -32,7 +32,7 @@ public class ReplaceListStage implements Stage {
this.defaultTag = defaultTag; this.defaultTag = defaultTag;
this.replaceDefault = replaceDefault; this.replaceDefault = replaceDefault;
} }
@Override @Override
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) { public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
PipelineBiome center = viewPoint.getBiome(); PipelineBiome center = viewPoint.getBiome();
@@ -46,18 +46,18 @@ public class ReplaceListStage implements Stage {
} }
return center; return center;
} }
@Override @Override
public int maxRelativeReadDistance() { public int maxRelativeReadDistance() {
return 0; return 0;
} }
@Override @Override
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) { public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
Set<PipelineBiome> biomeSet = new HashSet<>(); Set<PipelineBiome> biomeSet = new HashSet<>();
Set<PipelineBiome> reject = new HashSet<>(); Set<PipelineBiome> reject = new HashSet<>();
biomes.forEach(biome -> { biomes.forEach(biome -> {
if(!biome.getTags().contains(defaultTag) && !replace.containsKey(biome)) { if(!biome.getTags().contains(defaultTag) && !replace.containsKey(biome)) {
biomeSet.add(biome); biomeSet.add(biome);
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -22,13 +22,13 @@ public class ReplaceStage implements Stage {
private final String replaceableTag; private final String replaceableTag;
private final ProbabilityCollection<PipelineBiome> replace; private final ProbabilityCollection<PipelineBiome> replace;
private final NoiseSampler sampler; private final NoiseSampler sampler;
public ReplaceStage(String replaceable, ProbabilityCollection<PipelineBiome> replace, NoiseSampler sampler) { public ReplaceStage(String replaceable, ProbabilityCollection<PipelineBiome> replace, NoiseSampler sampler) {
this.replaceableTag = replaceable; this.replaceableTag = replaceable;
this.replace = replace; this.replace = replace;
this.sampler = sampler; this.sampler = sampler;
} }
@Override @Override
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) { public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
if(viewPoint.getBiome().getTags().contains(replaceableTag)) { if(viewPoint.getBiome().getTags().contains(replaceableTag)) {
@@ -37,12 +37,12 @@ public class ReplaceStage implements Stage {
} }
return viewPoint.getBiome(); return viewPoint.getBiome();
} }
@Override @Override
public int maxRelativeReadDistance() { public int maxRelativeReadDistance() {
return 0; return 0;
} }
@Override @Override
public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) { public Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
Set<PipelineBiome> biomeSet = new HashSet<>(); Set<PipelineBiome> biomeSet = new HashSet<>();
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -16,25 +16,25 @@ import com.dfsek.terra.api.noise.NoiseSampler;
public class SmoothStage implements Stage { public class SmoothStage implements Stage {
private final NoiseSampler sampler; private final NoiseSampler sampler;
public SmoothStage(NoiseSampler sampler) { public SmoothStage(NoiseSampler sampler) {
this.sampler = sampler; this.sampler = sampler;
} }
@Override @Override
public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) { public PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
PipelineBiome top = viewPoint.getRelativeBiome(1, 0); PipelineBiome top = viewPoint.getRelativeBiome(1, 0);
PipelineBiome bottom = viewPoint.getRelativeBiome(-1, 0); PipelineBiome bottom = viewPoint.getRelativeBiome(-1, 0);
PipelineBiome left = viewPoint.getRelativeBiome(0, 1); PipelineBiome left = viewPoint.getRelativeBiome(0, 1);
PipelineBiome right = viewPoint.getRelativeBiome(0, -1); PipelineBiome right = viewPoint.getRelativeBiome(0, -1);
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ()); double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
boolean vert = Objects.equals(top, bottom); boolean vert = Objects.equals(top, bottom);
boolean horiz = Objects.equals(left, right); boolean horiz = Objects.equals(left, right);
if(vert && horiz) { if(vert && horiz) {
return roll > 0 ? return roll > 0 ?
roll > 0.25 ? left : right : roll > 0.25 ? left : right :
@@ -48,7 +48,7 @@ public class SmoothStage implements Stage {
} }
return viewPoint.getBiome(); return viewPoint.getBiome();
} }
@Override @Override
public int maxRelativeReadDistance() { public int maxRelativeReadDistance() {
return 1; return 1;
@@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -1,12 +1,5 @@
version = version("1.0.1") version = version("1.0.2")
dependencies { dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader")) compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
} }
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.biome.pipeline.lib.jafama")
}
@@ -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, * 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. * 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 width;
private final int offset; private final int offset;
private BiomeDelegate[][] biomes; private BiomeDelegate[][] biomes;
public BiomeHolderImpl(int width, Vector2.Mutable origin) { public BiomeHolderImpl(int width, Vector2.Mutable origin) {
width += 4; width += 4;
this.width = width; this.width = width;
@@ -28,38 +28,38 @@ public class BiomeHolderImpl implements BiomeHolder {
this.origin = origin; this.origin = origin;
this.offset = 2; this.offset = 2;
} }
private BiomeHolderImpl(BiomeDelegate[][] biomes, Vector2.Mutable origin, int width, int offset) { private BiomeHolderImpl(BiomeDelegate[][] biomes, Vector2.Mutable origin, int width, int offset) {
this.biomes = biomes; this.biomes = biomes;
this.origin = origin; this.origin = origin;
this.width = width; this.width = width;
this.offset = 2 * offset; this.offset = 2 * offset;
} }
@Override @Override
public BiomeHolder expand(BiomeExpander expander, long seed) { public BiomeHolder expand(BiomeExpander expander, long seed) {
BiomeDelegate[][] old = biomes; BiomeDelegate[][] old = biomes;
int newWidth = width * 2 - 1; int newWidth = width * 2 - 1;
biomes = new BiomeDelegate[newWidth][newWidth]; biomes = new BiomeDelegate[newWidth][newWidth];
for(int x = 0; x < width; x++) { for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) { for(int z = 0; z < width; z++) {
biomes[x * 2][z * 2] = old[x][z]; biomes[x * 2][z * 2] = old[x][z];
if(z != width - 1) if(z != width - 1)
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z], 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) if(x != width - 1)
biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), seed, old[x][z], 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) 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], 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); return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset);
} }
@Override @Override
public void mutate(BiomeMutator mutator, long seed) { public void mutate(BiomeMutator mutator, long seed) {
for(int x = 0; x < width; x++) { for(int x = 0; x < width; x++) {
@@ -69,7 +69,7 @@ public class BiomeHolderImpl implements BiomeHolder {
} }
} }
} }
@Override @Override
public void fill(BiomeSource source, long seed) { public void fill(BiomeSource source, long seed) {
for(int x = 0; x < width; x++) { for(int x = 0; x < width; x++) {
@@ -78,14 +78,14 @@ public class BiomeHolderImpl implements BiomeHolder {
} }
} }
} }
@Override @Override
public BiomeDelegate getBiome(int x, int z) { public BiomeDelegate getBiome(int x, int z) {
x += offset; x += offset;
z += offset; z += offset;
return getBiomeRaw(x, z); return getBiomeRaw(x, z);
} }
@Override @Override
public BiomeDelegate getBiomeRaw(int x, int z) { public BiomeDelegate getBiomeRaw(int x, int z) {
if(x >= width || z >= width || x < 0 || z < 0) return null; if(x >= width || z >= width || x < 0 || z < 0) return null;
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -22,14 +22,14 @@ public class BiomePipeline {
private final List<Stage> stages; private final List<Stage> stages;
private final int size; private final int size;
private final int init; private final int init;
private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) { private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) {
this.source = source; this.source = source;
this.stages = stages; this.stages = stages;
this.size = size; this.size = size;
this.init = init; this.init = init;
} }
/** /**
* Get biomes in a chunk * Get biomes in a chunk
* *
@@ -44,37 +44,37 @@ public class BiomePipeline {
for(Stage stage : stages) holder = stage.apply(holder, seed); for(Stage stage : stages) holder = stage.apply(holder, seed);
return holder; return holder;
} }
public BiomeSource getSource() { public BiomeSource getSource() {
return source; return source;
} }
public List<Stage> getStages() { public List<Stage> getStages() {
return Collections.unmodifiableList(stages); return Collections.unmodifiableList(stages);
} }
public int getSize() { public int getSize() {
return size; return size;
} }
public static final class BiomePipelineBuilder { public static final class BiomePipelineBuilder {
private final int init; private final int init;
private final List<Stage> stages = new ArrayList<>(); private final List<Stage> stages = new ArrayList<>();
private int expand; private int expand;
public BiomePipelineBuilder(int init) { public BiomePipelineBuilder(int init) {
this.init = init; this.init = init;
expand = init; expand = init;
} }
public BiomePipeline build(BiomeSource source) { public BiomePipeline build(BiomeSource source) {
for(Stage stage : stages) { for(Stage stage : stages) {
if(stage.isExpansion()) expand = expand * 2 - 1; if(stage.isExpansion()) expand = expand * 2 - 1;
} }
return new BiomePipeline(source, stages, expand, init); return new BiomePipeline(source, stages, expand, init);
} }
public BiomePipelineBuilder addStage(Stage stage) { public BiomePipelineBuilder addStage(Stage stage) {
stages.add(stage); stages.add(stage);
return this; return this;
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -40,56 +40,57 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineAddon implements AddonInitializer { public class BiomePipelineAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() { 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<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
}; };
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_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 @Inject
private Platform platform; private Platform platform;
@Inject @Inject
private BaseAddon addon; private BaseAddon addon;
@Override @Override
public void initialize() { public void initialize() {
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY); PROVIDER_REGISTRY_KEY);
providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new); providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry(
SOURCE_REGISTRY_KEY); SOURCE_REGISTRY_KEY);
sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new); sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new);
}) })
.then(event -> { .then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry( CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
STAGE_REGISTRY_KEY); STAGE_REGISTRY_KEY);
stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new); stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
stageRegistry.register(addon.key("SMOOTH"), SmoothMutatorTemplate::new); stageRegistry.register(addon.key("SMOOTH"), SmoothMutatorTemplate::new);
stageRegistry.register(addon.key("REPLACE"), ReplaceMutatorTemplate::new); stageRegistry.register(addon.key("REPLACE"), ReplaceMutatorTemplate::new);
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListMutatorTemplate::new); stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListMutatorTemplate::new);
stageRegistry.register(addon.key("BORDER"), BorderMutatorTemplate::new); stageRegistry.register(addon.key("BORDER"), BorderMutatorTemplate::new);
stageRegistry.register(addon.key("BORDER_LIST"), BorderListMutatorTemplate::new); stageRegistry.register(addon.key("BORDER_LIST"), BorderListMutatorTemplate::new);
}) })
.failThrough(); .failThrough();
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPostLoadEvent.class) .register(addon, ConfigPackPostLoadEvent.class)
.then(event -> { .then(event -> {
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class); Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
event.getPack().applyLoader(BiomeDelegate.class, new BiomeDelegateLoader(biomeRegistry)); event.getPack().applyLoader(BiomeDelegate.class, new BiomeDelegateLoader(biomeRegistry));
}); });
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."); 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.");
} }
} }
@@ -12,11 +12,11 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
class BiomePipelineColumn implements Column<Biome> { class BiomePipelineColumn implements Column<Biome> {
private final int min; private final int min;
private final int max; private final int max;
private final int x; private final int x;
private final int z; private final int z;
private final Biome biome; private final Biome biome;
protected BiomePipelineColumn(BiomeProvider biomeProvider, int min, int max, int x, int z, long seed) { protected BiomePipelineColumn(BiomeProvider biomeProvider, int min, int max, int x, int z, long seed) {
this.min = min; this.min = min;
this.max = max; this.max = max;
@@ -24,44 +24,44 @@ class BiomePipelineColumn implements Column<Biome> {
this.z = z; this.z = z;
this.biome = biomeProvider.getBiome(x, 0, z, seed); this.biome = biomeProvider.getBiome(x, 0, z, seed);
} }
@Override @Override
public int getMinY() { public int getMinY() {
return min; return min;
} }
@Override @Override
public int getMaxY() { public int getMaxY() {
return max; return max;
} }
@Override @Override
public int getX() { public int getX() {
return x; return x;
} }
@Override @Override
public int getZ() { public int getZ() {
return z; return z;
} }
@Override @Override
public Biome get(int y) { public Biome get(int y) {
return biome; return biome;
} }
@Override @Override
public void forRanges(int resolution, IntIntObjConsumer<Biome> consumer) { public void forRanges(int resolution, IntIntObjConsumer<Biome> consumer) {
consumer.accept(min, max, biome); consumer.accept(min, max, biome);
} }
@Override @Override
public void forEach(Consumer<Biome> consumer) { public void forEach(Consumer<Biome> consumer) {
for(int y = min; y < max; y++) { for(int y = min; y < max; y++) {
consumer.accept(biome); consumer.accept(biome);
} }
} }
@Override @Override
public void forEach(IntObjConsumer<Biome> consumer) { public void forEach(IntObjConsumer<Biome> consumer) {
for(int y = min; y < max; y++) { for(int y = min; y < max; y++) {
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -9,7 +9,6 @@ package com.dfsek.terra.addons.biome.pipeline;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import net.jafama.FastMath;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
@@ -33,18 +32,18 @@ public class BiomePipelineProvider implements BiomeProvider {
private final int resolution; private final int resolution;
private final NoiseSampler mutator; private final NoiseSampler mutator;
private final double noiseAmp; private final double noiseAmp;
private final Set<Biome> biomes; private final Set<Biome> biomes;
public BiomePipelineProvider(BiomePipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) { public BiomePipelineProvider(BiomePipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
this.resolution = resolution; this.resolution = resolution;
this.mutator = mutator; this.mutator = mutator;
this.noiseAmp = noiseAmp; this.noiseAmp = noiseAmp;
holderCache = Caffeine.newBuilder() holderCache = Caffeine.newBuilder()
.maximumSize(1024) .maximumSize(1024)
.build(key -> pipeline.getBiomes(key.x, key.z, key.seed)); .build(key -> pipeline.getBiomes(key.x, key.z, key.seed));
this.pipeline = pipeline; this.pipeline = pipeline;
Set<BiomeDelegate> biomeSet = new HashSet<>(); Set<BiomeDelegate> biomeSet = new HashSet<>();
pipeline.getSource().getBiomes().forEach(biomeSet::add); pipeline.getSource().getBiomes().forEach(biomeSet::add);
Iterable<BiomeDelegate> result = biomeSet; Iterable<BiomeDelegate> result = biomeSet;
@@ -55,16 +54,16 @@ public class BiomePipelineProvider implements BiomeProvider {
Iterable<BiomeDelegate> finalResult = result; Iterable<BiomeDelegate> finalResult = result;
result.forEach(biomeDelegate -> { result.forEach(biomeDelegate -> {
if(biomeDelegate.isEphemeral()) { if(biomeDelegate.isEphemeral()) {
StringBuilder biomeList = new StringBuilder("\n"); StringBuilder biomeList = new StringBuilder("\n");
StreamSupport.stream(finalResult.spliterator(), false) StreamSupport.stream(finalResult.spliterator(), false)
.sorted(Comparator.comparing(StringIdentifiable::getID)) .sorted(Comparator.comparing(StringIdentifiable::getID))
.forEach(delegate -> biomeList .forEach(delegate -> biomeList
.append(" - ") .append(" - ")
.append(delegate.getID()) .append(delegate.getID())
.append(':') .append(':')
.append(delegate.getClass().getCanonicalName()) .append(delegate.getClass().getCanonicalName())
.append('\n')); .append('\n'));
throw new IllegalArgumentException("Biome Pipeline leaks ephemeral biome \"" + biomeDelegate.getID() + throw new IllegalArgumentException("Biome Pipeline leaks ephemeral biome \"" + biomeDelegate.getID() +
"\". Ensure there is a stage to guarantee replacement of the ephemeral biome. Biomes: " + "\". Ensure there is a stage to guarantee replacement of the ephemeral biome. Biomes: " +
biomeList); biomeList);
@@ -72,12 +71,12 @@ public class BiomePipelineProvider implements BiomeProvider {
this.biomes.add(biomeDelegate.getBiome()); this.biomes.add(biomeDelegate.getBiome());
}); });
} }
@Override @Override
public Biome getBiome(int x, int y, int z, long seed) { public Biome getBiome(int x, int y, int z, long seed) {
return getBiome(x, z, seed); return getBiome(x, z, seed);
} }
public Biome getBiome(int x, int z, long seed) { public Biome getBiome(int x, int z, long seed) {
x += mutator.noise(seed + 1, x, z) * noiseAmp; x += mutator.noise(seed + 1, x, z) * noiseAmp;
z += mutator.noise(seed + 2, x, z) * noiseAmp; z += mutator.noise(seed + 2, x, z) * noiseAmp;
@@ -86,32 +85,32 @@ public class BiomePipelineProvider implements BiomeProvider {
x /= resolution; x /= resolution;
z /= resolution; z /= resolution;
int fdX = FastMath.floorDiv(x, pipeline.getSize()); int fdX = Math.floorDiv(x, pipeline.getSize());
int fdZ = FastMath.floorDiv(z, pipeline.getSize()); int fdZ = Math.floorDiv(z, pipeline.getSize());
return holderCache.get(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * 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 @Override
public Optional<Biome> getBaseBiome(int x, int z, long seed) { public Optional<Biome> getBaseBiome(int x, int z, long seed) {
return Optional.of(getBiome(x, z, seed)); return Optional.of(getBiome(x, z, seed));
} }
@Override @Override
public Iterable<Biome> getBiomes() { public Iterable<Biome> getBiomes() {
return biomes; return biomes;
} }
@Override @Override
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) { public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
return new BiomePipelineColumn(this, min, max, x, z, seed); return new BiomePipelineColumn(this, min, max, x, z, seed);
} }
@Override @Override
public int resolution() { public int resolution() {
return resolution; return resolution;
} }
private record SeededVector(int x, int z, long seed) { private record SeededVector(int x, int z, long seed) {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
@@ -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, * 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. * 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 { public interface BiomeHolder {
BiomeHolder expand(BiomeExpander expander, long seed); BiomeHolder expand(BiomeExpander expander, long seed);
void mutate(BiomeMutator mutator, long seed); void mutate(BiomeMutator mutator, long seed);
void fill(BiomeSource source, long seed); void fill(BiomeSource source, long seed);
BiomeDelegate getBiome(int x, int z); BiomeDelegate getBiome(int x, int z);
BiomeDelegate getBiomeRaw(int x, int z); BiomeDelegate getBiomeRaw(int x, int z);
} }
@@ -10,26 +10,26 @@ public interface BiomeDelegate extends StringIdentifiable {
static BiomeDelegate ephemeral(String id) { static BiomeDelegate ephemeral(String id) {
return new EphemeralBiomeDelegate(id); return new EphemeralBiomeDelegate(id);
} }
static BiomeDelegate from(Biome biome) { static BiomeDelegate from(Biome biome) {
return new DelegatedBiome(biome); return new DelegatedBiome(biome);
} }
static BiomeDelegate self() { static BiomeDelegate self() {
return SelfDelegate.INSTANCE; return SelfDelegate.INSTANCE;
} }
Biome getBiome(); Biome getBiome();
Set<String> getTags(); Set<String> getTags();
default boolean isEphemeral() { default boolean isEphemeral() {
return false; return false;
} }
default boolean isSelf() { default boolean isSelf() {
return false; return false;
} }
} }
@@ -7,32 +7,32 @@ import com.dfsek.terra.api.world.biome.Biome;
final class DelegatedBiome implements BiomeDelegate { final class DelegatedBiome implements BiomeDelegate {
private final Biome biome; private final Biome biome;
public DelegatedBiome(Biome biome) { public DelegatedBiome(Biome biome) {
this.biome = biome; this.biome = biome;
} }
@Override @Override
public Biome getBiome() { public Biome getBiome() {
return biome; return biome;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return biome.hashCode(); return biome.hashCode();
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof DelegatedBiome that)) return false; if(!(obj instanceof DelegatedBiome that)) return false;
return that.biome.equals(this.biome); return that.biome.equals(this.biome);
} }
@Override @Override
public Set<String> getTags() { public Set<String> getTags() {
return biome.getTags(); return biome.getTags();
} }
@Override @Override
public String getID() { public String getID() {
return biome.getID(); return biome.getID();
@@ -9,43 +9,43 @@ import com.dfsek.terra.api.world.biome.Biome;
final class EphemeralBiomeDelegate implements BiomeDelegate { final class EphemeralBiomeDelegate implements BiomeDelegate {
private final Set<String> tags; private final Set<String> tags;
private final String id; private final String id;
public EphemeralBiomeDelegate(String id) { public EphemeralBiomeDelegate(String id) {
this.id = id; this.id = id;
tags = new HashSet<>(); tags = new HashSet<>();
tags.add(id); tags.add(id);
tags.add("ALL"); tags.add("ALL");
} }
@Override @Override
public Biome getBiome() { public Biome getBiome() {
throw new UnsupportedOperationException("Cannot get biome from ephemeral delegate"); throw new UnsupportedOperationException("Cannot get biome from ephemeral delegate");
} }
@Override @Override
public Set<String> getTags() { public Set<String> getTags() {
return tags; return tags;
} }
@Override @Override
public String getID() { public String getID() {
return id; return id;
} }
@Override @Override
public boolean isEphemeral() { public boolean isEphemeral() {
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return id.hashCode(); return id.hashCode();
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(!(obj instanceof EphemeralBiomeDelegate that)) return false; if(!(obj instanceof EphemeralBiomeDelegate that)) return false;
return this.id.equals(that.id); return this.id.equals(that.id);
} }
} }
@@ -8,31 +8,31 @@ import com.dfsek.terra.api.world.biome.Biome;
final class SelfDelegate implements BiomeDelegate { final class SelfDelegate implements BiomeDelegate {
public static final SelfDelegate INSTANCE = new SelfDelegate(); public static final SelfDelegate INSTANCE = new SelfDelegate();
private SelfDelegate() { private SelfDelegate() {
} }
@Override @Override
public Biome getBiome() { public Biome getBiome() {
throw new UnsupportedOperationException("Cannot get biome from self delegate"); throw new UnsupportedOperationException("Cannot get biome from self delegate");
} }
@Override @Override
public boolean isSelf() { public boolean isSelf() {
return true; return true;
} }
@Override @Override
public boolean isEphemeral() { public boolean isEphemeral() {
return true; return true;
} }
@Override @Override
public Set<String> getTags() { public Set<String> getTags() {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override @Override
public String getID() { public String getID() {
return "SELF"; return "SELF";
@@ -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, * 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. * 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 { public interface Stage {
BiomeHolder apply(BiomeHolder in, long seed); BiomeHolder apply(BiomeHolder in, long seed);
boolean isExpansion(); boolean isExpansion();
Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes); Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes);
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -13,23 +13,23 @@ import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
public interface BiomeMutator { public interface BiomeMutator {
BiomeDelegate mutate(ViewPoint viewPoint, double x, double z, long seed); BiomeDelegate mutate(ViewPoint viewPoint, double x, double z, long seed);
default Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes) { default Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes) {
return biomes; return biomes;
} }
class ViewPoint { class ViewPoint {
private final BiomeHolder biomes; private final BiomeHolder biomes;
private final int offX; private final int offX;
private final int offZ; private final int offZ;
public ViewPoint(BiomeHolder biomes, int offX, int offZ) { public ViewPoint(BiomeHolder biomes, int offX, int offZ) {
this.biomes = biomes; this.biomes = biomes;
this.offX = offX; this.offX = offX;
this.offZ = offZ; this.offZ = offZ;
} }
public BiomeDelegate getBiome(int x, int z) { public BiomeDelegate getBiome(int x, int z) {
return biomes.getBiomeRaw(x + offX, z + offZ); return biomes.getBiomeRaw(x + offX, z + offZ);
} }
@@ -15,18 +15,18 @@ import com.dfsek.terra.api.world.biome.Biome;
public class BiomeDelegateLoader implements TypeLoader<BiomeDelegate> { public class BiomeDelegateLoader implements TypeLoader<BiomeDelegate> {
private final Registry<Biome> biomeRegistry; private final Registry<Biome> biomeRegistry;
public BiomeDelegateLoader(Registry<Biome> biomeRegistry) { public BiomeDelegateLoader(Registry<Biome> biomeRegistry) {
this.biomeRegistry = biomeRegistry; this.biomeRegistry = biomeRegistry;
} }
@Override @Override
public BiomeDelegate load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker) public BiomeDelegate load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
throws LoadException { throws LoadException {
if(c.equals("SELF")) return BiomeDelegate.self(); if(c.equals("SELF")) return BiomeDelegate.self();
return biomeRegistry return biomeRegistry
.getByID((String) c) .getByID((String) c)
.map(BiomeDelegate::from) .map(BiomeDelegate::from)
.orElseGet(() -> BiomeDelegate.ephemeral((String) c)); .orElseGet(() -> BiomeDelegate.ephemeral((String) c));
} }
} }
@@ -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, * 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. * reference the LICENSE file in this module's root directory.
@@ -35,15 +35,15 @@ public class BiomePipelineTemplate extends BiomeProviderTemplate {
and subtract 1. (The size is also printed to the server console if you and subtract 1. (The size is also printed to the server console if you
have debug mode enabled)""") have debug mode enabled)""")
private @Meta int initialSize = 2; private @Meta int initialSize = 2;
@Value("pipeline.source") @Value("pipeline.source")
@Description("The Biome Source to use for initial population of biomes.") @Description("The Biome Source to use for initial population of biomes.")
private @Meta BiomeSource source; private @Meta BiomeSource source;
@Value("pipeline.stages") @Value("pipeline.stages")
@Description("A list of pipeline stages to apply to the result of #source") @Description("A list of pipeline stages to apply to the result of #source")
private @Meta List<@Meta Stage> stages; private @Meta List<@Meta Stage> stages;
@Override @Override
public BiomeProvider get() { public BiomeProvider get() {
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize); BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize);
@@ -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, * 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. * reference the LICENSE file in this module's root directory.

Some files were not shown because too many files have changed in this diff Show More