Compare commits

..

74 Commits

Author SHA1 Message Date
dfsek e887a9f1a1 remove additional events, make Event extend Monad 2022-09-02 22:51:57 -07:00
dfsek 3077178cd2 Merge remote-tracking branch 'origin/ver/7.0.0' into dev/pure 2022-08-28 21:39:36 -07:00
dfsek a0738a3b32 Merge pull request #365 from Astrashh/dev/linear-map
Linear map normalizer
2022-08-24 11:55:08 -07:00
Zoë ee3be35359 Merge pull request #368 from duplexsystem/ver/7.0.0
git is being bad so I'm just pring
2022-08-23 12:58:36 -05:00
Zoë cb6dbe3ec9 fix format 2022-08-23 12:55:18 -05:00
Zoë c40fc4b844 Merge pull request #367 from duplexsystem/ver/7.0.0
fixes
2022-08-22 23:18:32 -05:00
Zoë 2e8bc8d561 sub structures use pos as origin 2022-08-22 22:55:28 -05:00
Zoë 08df8b1652 some fixes 2022-08-22 22:41:26 -05:00
Astrash 3dcfeb987f Add meta annotations 2022-08-23 11:06:32 +10:00
Astrash f0efb4c931 Add default 'from' values for linear map template 2022-08-23 11:02:17 +10:00
Astrash 82596a8ffd Implement linear map normalizer 2022-08-23 11:02:17 +10:00
dfsek 9aa124605c Merge pull request #364 from duplexsystem/ver/7.0.0
oop 2
2022-08-22 17:28:13 -07:00
Zoë ec7f0dacfa oop 2 2022-08-21 21:07:16 -05:00
dfsek 507895636e Merge pull request #363 from duplexsystem/ver/7.0.0
oops
2022-08-21 19:06:42 -07:00
Zoë 32ddc287f7 oops 2022-08-21 20:48:21 -05:00
dfsek 91766599c6 Merge remote-tracking branch 'origin/ver/7.0.0' into dev/pure
# Conflicts:
#	common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/BiomePipelineAddon.java
#	common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/DistributorAddon.java
#	common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/LocatorAddon.java
2022-08-21 13:40:57 -07:00
dfsek 710c00b0d8 annotate initialize method @NotNull 2022-08-21 13:40:19 -07:00
dfsek b6320c95ea Merge pull request #362 from duplexsystem/dev/enviroment
Dev/enviroment
2022-08-21 13:35:02 -07:00
Zoë 0b8524b08d remove comment 2022-08-21 14:33:57 -05:00
Zoë b5d081fde4 remove more random 2022-08-21 14:29:57 -05:00
Zoë b044b2c48e Merge remote-tracking branch 'origin/ver/7.0.0' into dev/enviroment 2022-08-21 12:30:15 -05:00
Zoë b627ce6e58 Update libs and use libs.versions.toml for dep management 2022-08-21 12:21:12 -05:00
dfsek fcffefe91d clean up PluginConfig 2022-08-21 01:06:24 -07:00
dfsek ec8564df2f remove most references to ConfigPack from API 2022-08-21 01:02:10 -07:00
dfsek 997d2204c7 create config-pack addon project 2022-08-21 00:55:03 -07:00
dfsek 4f687f7587 remove ConfigPack and related interfaces 2022-08-21 00:53:03 -07:00
dfsek 620ae7d1ff make Registry immutable, remove other registry implementations 2022-08-21 00:51:26 -07:00
dfsek 6a53a0c56b Merge pull request #355 from Astrashh/dev/pipeline-reimplementation
Biome pipeline reimplementation
2022-08-20 12:34:48 -07:00
Zoë 5d5408e142 terraScript random is no more 2022-08-19 23:18:42 -05:00
Astrash 2025fe6e90 Merge branch 'ver/7.0.0' into dev/pipeline-reimplementation 2022-08-20 13:05:12 +10:00
Zoë e658a5d917 fix enum to uppcases 2022-08-19 20:36:57 -05:00
Zoë 8c16225ed1 Update ModPlatform.java 2022-08-19 20:36:51 -05:00
Zoë 2d97c776fc Dim opts 2022-08-19 20:36:41 -05:00
Zoë 6cd91bcc1d Random Changes 2022-08-19 20:36:32 -05:00
Zoë 5f5c4f85c7 Fixes 2022-08-19 20:35:01 -05:00
Zoë 1702a46fda Merge remote-tracking branch 'origin/fix/scale-pipeline-264' into ver/7.0.0 2022-08-19 20:34:39 -05:00
Astrash 97b74508f8 Merge branch 'ver/7.0.0' into dev/pipeline-reimplementation 2022-08-19 11:37:55 +10:00
dfsek b04a4850da deprecare getByID 2022-08-18 16:54:16 -07:00
dfsek c8beb0f965 clean up unneeded injects 2022-08-18 16:52:46 -07:00
dfsek 74f9c4f9b1 convert all addons to use monad initialiser 2022-08-16 14:36:03 -07:00
dfsek 45c3729392 update OreAddon to use do notation 2022-08-15 11:12:10 -07:00
dfsek 8538ee6804 add simple do notation for monadic binding 2022-08-15 10:33:25 -07:00
dfsek ee64039f5f add vavr dependency 2022-08-15 10:11:38 -07:00
dfsek 0609a7cf6b implement MonadAddonInitializer 2022-08-15 10:06:29 -07:00
dfsek 97854e3037 create monad and functor interfaces 2022-08-14 19:14:47 -07:00
dfsek a6b193503d Merge pull request #358 from Astrashh/dev/dot-product-slant
Calculate noise3d generator slant with dot product
2022-08-14 19:03:45 -07:00
Astrash 7e6b4a0b74 Calculate slant with approx dot product rather than derivative 2022-08-15 10:34:29 +10:00
Astrash af4465196c Replace sout with logger debug calls 2022-08-07 14:53:13 +10:00
Astrash 68058e7dc6 Remove test class from source 2022-08-07 12:30:22 +10:00
Astrash e30ce62d86 Ephemeral -> Placeholder 2022-08-07 12:23:51 +10:00
Astrash 227a2362af Move reimplementation classes into main package 2022-08-07 12:15:50 +10:00
Astrash eb0c40aafd Handle resolution and biome blending 2022-08-07 11:46:55 +10:00
Astrash 3835533cc9 Working state for pipeline implementation 2022-08-06 22:15:15 +10:00
dfsek b83d4c21e0 factor in resolution 2022-07-16 04:22:29 -07:00
dfsek 145eed893a fix #264 with artifacting 2022-07-16 04:22:28 -07:00
dfsek 3dd3c047b4 Merge pull request #341 from duplexsystem/dev/enviroment
Remove vanilla key, Comminfy Some code, Minor Biome Enviroment Tweaks, Port all Enviroment Settings to Bukkit, and Implment Fertilization
2022-07-14 19:51:16 -07:00
Zoë 1003304fde Reformat 2022-07-14 19:50:25 -07:00
Zoë 04c6363469 Merge remote-tracking branch 'origin/dev/enviroment' into dev/enviroment 2022-07-14 19:43:56 -07:00
Zoë 4b518c28a0 Requested changes 2022-07-14 19:43:50 -07:00
Zoë 199360b981 Update LifecycleEntryPoint.java 2022-07-14 00:45:52 -07:00
Zoë f75880acac Bukkit update 2022-07-14 00:38:54 -07:00
Zoë dd9f421972 Growing 2022-07-12 18:46:32 -07:00
Zoë 5c2998c91c remove more 2022-07-12 13:39:52 -07:00
Zoë 09c0f0acc9 Remove unused config keys 2022-07-12 13:37:28 -07:00
Zoë 970a5c60d9 clean 2022-07-12 13:09:58 -07:00
Zoë d8285bc9a7 make bukkit growing better 2022-07-12 13:04:07 -07:00
Zoë 75b545b0be Bukkit Growing 2022-07-12 01:04:55 -07:00
Zoë 50377a1b89 Fabric/Quilt fertilization support 2022-07-11 21:49:16 -07:00
Zoë ba6d4649c6 remove bukkit 1.18 2022-07-11 15:16:54 -07:00
Zoë a286e26656 Bukkit 2022-07-11 14:57:43 -07:00
Zoë 526e655a8f remove unused key 2022-07-11 13:53:38 -07:00
Zoë f26cedd613 Remove Vanilla Key 2022-07-11 13:49:55 -07:00
Zoë b1b91726ef UX tweaks to biome config 2022-07-10 20:18:49 -07:00
Zoë 796f66e708 We do a little commonifying 2022-07-10 19:38:35 -07:00
1078 changed files with 11537 additions and 26282 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 = 4 ij_continuation_indent_size = 8
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 = false ij_java_align_multiline_chained_methods = true
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 = false ij_java_align_multiline_method_parentheses = true
ij_java_align_multiline_parameters = true ij_java_align_multiline_parameters = true
ij_java_align_multiline_parameters_in_calls = false ij_java_align_multiline_parameters_in_calls = true
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 = false ij_java_keep_indents_on_empty_lines = true
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
[{*.yml, *.yaml}] [{*.yaml, *.yml}]
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 = false ij_yaml_keep_indents_on_empty_lines = true
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
+12 -7
View File
@@ -1,14 +1,19 @@
# Global owners, automatically request review when pull request is submitted # Global owners, automatically request review when pull request is submitted
* @dfsek @solonovamax @duplexsystem @astrsh @justaureus * @dfsek @solonovamax
# Platforms # Platforms
/platforms/ @dfsek @solonovamax @duplexsystem @justaureus ## dfsek wrote the majority of the platform impls
/platforms/bukkit @dfsek @solonovamax @duplexsystem @justaureus @OakLoaf /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 @duplexsystem @astrsh /common/ @dfsek @solonovamax
# Gradle Stuff # Gradle Stuff
/buildSrc/ @dfsek @solonovamax @duplexsystem ## Most gradle stuff was written by solonovamax
*.gradle.kts @dfsek @solonovamax @duplexsystem /buildSrc/ @solonovamax
/gradle/ @dfsek @solonovamax @duplexsystem *.gradle.kts @solonovamax
+8 -8
View File
@@ -43,7 +43,7 @@ assignees: ""
is Terra that is causing the issue. is Terra that is causing the issue.
- [ ] I have checked that this is an issue with Terra and not an issue with the - [ ] I have checked that this is an issue with Terra and not an issue with the
pack I am using. pack I am using.
<!-- If this is an issue with the default Terra pack, please open an issue on the pack repo: https://github.com/PolyhedralDev/TerraOverworldConfig/issues/new --> <!-- If this is an issue with the default Terra pack, please open an issue on the pack repo: https://github.com/PolyhedralDev/TerraDefaultConfig/issues/new -->
- [ ] I have attached a copy of the `latest.log` file - [ ] I have attached a copy of the `latest.log` file
- [ ] I have filled out and provided all the appropriate information. - [ ] I have filled out and provided all the appropriate information.
@@ -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
+83 -69
View File
@@ -1,19 +1,58 @@
# Pull Request # Pull Request
## Description ## Brief description.
<!-- Include a description of the PR here --> <!-- Please provide a brief description of the goals of your PR -->
<!-- <!--
If applicable, include 'Fixes #XXXX' or 'Closes #XXXX' for any related open issues. ###########################################################################
This helps us relate, track, and close the relevant issues. ## WARNING! ##
## IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN YOUR PR BEING CLOSED ##
###########################################################################
-->
<!--
Please go through this checklist item by item and make sure you have successfully completed each of these steps.
- Your pull request MUST be either on the latest version of Terra, or on a branch for a future release.
- Make sure that there are no already existing PRs that fix this. If so, it will be closed as a duplicate.
- Make sure that this change is actually within the scope of Terra and is something a terrain generator should be doing.
- Make sure that this is not an issue with a specific Terra *pack*, and instead applies to all of Terra.
- Make sure that you have filled out all the required information and given descriptions of everything.
-->
<!-- You can erase any parts of this template not applicable to your Pull Request. -->
### What Issues Does This Fix?
<!--
Put Fix #XXXX or Closes #XXXX here if there are any open issues that this PR fixes.
This is to automatically close the relevant issues.
You may remove this if there is no issue for this PR.
But unless this is a very small change, you should make an issue for it.
--> -->
### Changelog ## Licensing
<!-- In order to be accepted, your changes must be under the GPLv3 license. Please check one of the following: -->
- [ ] I am the original author of this code, and I am willing to release it
under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html).
- [ ] I am not the original author of this code, but it is in public domain or
released under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) or a
compatible license.
<!--
Please provide reliable evidence of this.
NOTE: for compatible licenses, you must make sure to add the included license somewhere in the program, if so required.
(And even if it's not required, it's still nice to do it. Also add attribution somewhere.)
-->
## Goal of the PR
<!-- <!--
Fill out a changelog below of what has been done, and what might be planned to be done. What is the goal of the PR?
You may delete this if your PR is not adding new features, only fixing bugs or adding translations. Put a checklist here of what has been done
(and what *hasn't*, but you plan to do),
so we can easily know what was changed.
Note: this is only required for PRs that add new features.
If your PR is not adding new features, only fixing bugs or adding translations, then you may delete this section.
--> -->
- [ ] <!-- First thing --> - [ ] <!-- First thing -->
@@ -22,58 +61,47 @@ You may delete this if your PR is not adding new features, only fixing bugs or a
- [ ] <!-- Second thing --> - [ ] <!-- Second thing -->
- [ ] <!-- etc. --> - [ ] <!-- etc. -->
## Checklist ## Affects of the PR
<!-- <!---
Select the options below that apply. What types of changes does your code introduce? (Select any that apply. You may select multiple.)
You must put an x in all the boxes that it applies to. (Like this: [x]) 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 <!-- Changes include bug fixes. --> - [ ] Bug Fix <!-- Anything which fixes an issue in Terra. -->
- [ ] Build system <!-- Changes the build system. --> - [ ] Build system <!-- Anything which pretain to the build system. -->
- [ ] Documentation <!-- Changes add to or improve documentation. --> - [ ] Documentation <!-- Anything which adds or improves documentation for existing features. -->
- [ ] New Feature <!-- Changes add new functionality to Terra. --> - [ ] New Feature <!-- Anything which adds new functionality to Terra. -->
- [ ] Performance <!-- Changes improve the performance of Terra. --> - [ ] Performance <!-- Anything which is imrpoves the performance of Terra. -->
- [ ] Refactoring <!-- Changes do not add any new code, only moves code around. --> - [ ] Refactoring <!-- Anything which does not add any new code, only moves code around. -->
- [ ] Repository <!-- Changes affect the repository. E.g. changes to the `README.md` file. --> - [ ] Repository <!-- Anything which affects the repository. Eg. changes to the `README.md` file. -->
- [ ] Revert <!-- Changes revert previous commits. --> - [ ] Revert <!-- Anything which reverts previous commits. -->
- [ ] Style <!-- Changes update style, namely the .editorconfig file. --> - [ ] Style <!-- Anything which updates style. -->
- [ ] Tests <!-- Changes add or update tests. --> - [ ] Tests <!-- Anything which adds or updates tests. -->
- [ ] Translation <!-- Changes include translations to other languages for Terra. --> - [ ] Translation <!-- Anything which is internationalizing the Terra program to other languages. -->
#### Compatibility #### Compatiblity
<!-- The following options determine if the PR pertains to a major, minor, or patch version bump --> - [ ] Breaking
change <!-- A fix, or a feature, that breaks some previous functionality to Terra. -->
- [ ] Non-Breaking change.
<!--
A change which does not break *any* previous functionality of Terra.
(ie. is backwards compatible and will work with *any* previously existing supported features.
Note: if a feature is annotated with @Incubating, @Preview, @Experimental,
or is in a package called something similar to the previous annotations,
then you may push breaking changes to only THOSE parts of Terra.)
-->
- [ ] Introduces a breaking change #### Contribution Guidelines.
<!--
Breaking changes are any fix or feature that breaks some previous functionality to Terra / is not backwards compatible. - [ ] I have read
Breaking changes do not include: the [`CONTRIBUTING.md`](https://github.com/PolyhedralDev/Terra/blob/master/CONTRIBUTING.md)
- changes that are backwards compatible and will work with *any* previously existing supported features. document in the root of the git repository.
- changes to code marked as in a pre-release - [ ] My code follows the code style for this
state (annotated with @Incubating, @Preview, @Experimental 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. -->
or in a package called something similar to the previous annotations)
-->
- [ ] Introduces new functionality in a backwards compatible way.
- [ ] Introduces bug fixes
#### Documentation #### Documentation
@@ -84,21 +112,7 @@ You must put an x in all the boxes that it applies to. (Like this: [x])
- [ ] 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.
<!-- <!--
Tests are typically not necessary for small changes. If it only introduces small changes, you don't need to add tests.
Including *some* testing is recommended for large changes where applicable. But if you add big changes, you should probably at least write *some* testing, 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.)
-->
-47
View File
@@ -1,47 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
name: Gradle Build
on: [ pull_request ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Set up JDK 21
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
with:
java-version: '21'
distribution: 'temurin'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- uses: burrunan/gradle-cache-action@03c71a8ba93d670980695505f48f49daf43704a6
name: Build Terra
with:
# Specifies arguments for Gradle execution
# If arguments is missing or empty, then Gradle is not executed
arguments: build
# arguments can be multi-line for better readability
# arguments: |
# --no-paralell
# build
# -x test
# Gradle version to use for execution:
# wrapper (default), current, rc, nightly, release-nightly, or
# versions like 6.6 (see https://services.gradle.org/versions/all)
gradle-version: wrapper
# Properties are passed as -Pname=value
properties: |
kotlin.js.compiler=ir
kotlin.parallel.tasks.in.project=true
-2
View File
@@ -249,5 +249,3 @@ nbdist/
platforms/**/run/** platforms/**/run/**
#Vale Config File
**/.vale.ini
-6
View File
@@ -1,6 +0,0 @@
[submodule "platforms/allay/src/main/resources/mappings"]
path = platforms/allay/src/main/resources/mappings
url = https://github.com/GeyserMC/mappings
[submodule "platforms/allay/src/main/resources/mappings-generator"]
path = platforms/allay/src/main/resources/mappings-generator
url = https://github.com/GeyserMC/mappings-generator
+34 -14
View File
@@ -315,15 +315,19 @@ Terra has a global moderation team which is currently comprised of the following
members: members:
- solonovamax - solonovamax
- discord: [@solonovamax#6983](https://discord.com/channels/@me/566146322273402881)* -
discord: [@solonovamax#6983](https://discord.com/channels/@me/566146322273402881)*
- github: [@solonovamax](https://github.com/solonovamax) - github: [@solonovamax](https://github.com/solonovamax)
- email: [solonovamax@12oclockpoint.com](mailto:solonovamax@12oclockpoint.com) -
email: [solonovamax@12oclockpoint.com](mailto:solonovamax@12oclockpoint.com)
- dfsek - dfsek
- discord: [@dfsek#4208](https://discord.com/channels/@me/378350362236682240)* -
discord: [@dfsek#4208](https://discord.com/channels/@me/378350362236682240)*
- github: [@dfsek](https://github.com/dfsek) - github: [@dfsek](https://github.com/dfsek)
- email: [dfsek@protonmail.com](mailto:dfsek@protonmail.com) - email: [dfsek@protonmail.com](mailto:dfsek@protonmail.com)
- duplex (duplexsystem) - duplex (duplexsystem)
- discord: [@Duplex#0797](https://discord.com/channels/@me/356822848641171456)* -
discord: [@Duplex#0797](https://discord.com/channels/@me/356822848641171456)*
- github: [@duplexsystem](https://github.com/duplexsystem) - github: [@duplexsystem](https://github.com/duplexsystem)
- email: [duplexsys@protonmail.com](mailto:duplexsys@protonmail.com) - email: [duplexsys@protonmail.com](mailto:duplexsys@protonmail.com)
@@ -397,17 +401,32 @@ issue on this github repo, or contact a member of the global moderation team.
## License and Attribution ## License and Attribution
This set of guidelines is distributed under a This set of guidelines is distributed under a
[Creative Commons Attribution-ShareAlike license](https://creativecommons.org/licenses/by-sa/3.0/). [Creative Commons Attribution-ShareAlike license](https://creativecommons.org/licenses/by-sa/3.0/)
.
These guidelines have been adapted with modifications from the following sources: These guidelines have been adapted from
[Mozilla's Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/)
, which were adapted from:
- [Mozilla's Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/) - Mozilla's original Community Participation Guidelines
- The [Ubuntu Code of Conduct](https://ubuntu.com/community/code-of-conduct) - The [Ubuntu Code of Conduct](https://ubuntu.com/community/code-of-conduct)
- Mozilla's [View Source Conference Code of Conduct](https://viewsourceconf.org/berlin-2016/code-of-conduct/) -
- The [Rust Language Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct)
- The [Stumptown Syndicate's Citizen Code of Conduct](http://citizencodeofconduct.org/) Mozilla's [View Source Conference Code of Conduct](https://viewsourceconf.org/berlin-2016/code-of-conduct/)
- The [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html)
- The [WisCon code of conduct](http://wiscon.net/policies/anti-harassment/code-of-conduct/) - And
the [Rust Language Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct)
which in turn were based
on [Stumptown Syndicate's Citizen Code of Conduct](http://citizencodeofconduct.org/)
, along with some adapted text from
the [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html) and
the [WisCon code of conduct](http://wiscon.net/policies/anti-harassment/code-of-conduct/)
.
It was then modified by solonovamax with various inclusions from
the [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html) and
a few other sources.
## Notes ## Notes
@@ -424,6 +443,7 @@ people are not comfortable
using [neopronouns](https://www.mypronouns.org/neopronouns). But if someone using [neopronouns](https://www.mypronouns.org/neopronouns). But if someone
refuses to use your more common pronouns, you should report them to us. refuses to use your more common pronouns, you should report them to us.
Additionally, you may not ask people to use unreasonable pronouns, such as ' Additionally, you may not ask people to use unreasonable pronouns, such as '
acab/acabself', 'that/bitch', 'ur/mom', or anything else that may be considered acab/acabself', 'that/bitch', 'ur/mom', or
disrectful. Doing so will be considered mockery of individuals who use 'dream/dreamself' (pronouns related to real people, eg. the minecraft youtuber '
dreamwastaken'). Doing so will be considered mockery of individuals who use
non-standard pronouns and is very disrespectful. non-standard pronouns and is very disrespectful.
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020-2025 Polyhedral Development Copyright (c) 2020-2021 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 -1
View File
@@ -47,7 +47,14 @@ 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
* `runServer` - Run the Paper test server with Terra installed. * `installPaper` - Install a [Paper](https://github.com/PaperMC/Paper) test
server. (Only needs to be run once).
* `installPurpur` - Install a [Purpur](https://github.com/pl3xgaming/Purpur)
test server. (Only needs to be run once).
* `runPaper` - Run the Paper test server with Terra (`installPaper` must
have been run previously).
* `runPurpur` - Run the Purpur test server with Terra (`installPurpur` must
have been run previously).
* 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.
+13 -16
View File
@@ -1,39 +1,38 @@
preRelease(true) preRelease(true)
versionProjects(":common:api", version("6.6.1")) versionProjects(":common:api", version("6.2.0"))
versionProjects(":common:implementation", version("6.6.1")) versionProjects(":common:implementation", version("6.2.0"))
versionProjects(":platforms", version("6.6.1")) versionProjects(":platforms", version("6.2.0"))
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
options.release.set(21)
} }
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
} }
@@ -43,15 +42,13 @@ afterEvaluate {
forImmediateSubProjects(":platforms") { forImmediateSubProjects(":platforms") {
configureDistribution() configureDistribution()
} }
project(":platforms:bukkit:common").configureDistribution()
project(":platforms:minestom:example").configureDistribution()
forSubProjects(":common:addons") { forSubProjects(":common:addons") {
apply(plugin = "com.gradleup.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"))
+6 -10
View File
@@ -9,18 +9,14 @@ repositories {
maven("https://repo.codemc.org/repository/maven-public") { maven("https://repo.codemc.org/repository/maven-public") {
name = "CodeMC" name = "CodeMC"
} }
maven("https://repo.papermc.io/repository/maven-public/") {
name = "PaperMC"
}
} }
dependencies { dependencies {
//TODO Allow pulling from Versions.kt implementation(libs.libraries.internal.shadow)
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1")
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.7.2")
implementation("org.ow2.asm", "asm", "9.7")
implementation("org.ow2.asm", "asm-tree", "9.7") implementation(libs.libraries.internal.asm)
implementation("com.dfsek.tectonic", "common", "4.2.1") implementation(libs.libraries.internal.asm.tree)
implementation("org.yaml", "snakeyaml", "2.3") implementation(libs.libraries.tectonic)
implementation(libs.libraries.snakeyaml)
} }
+7
View File
@@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
+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 {
logger.info("Deleting old addon: " + it.absolutePath) println("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}"
logger.info("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base") println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base")
jar.archiveFile.orNull?.asFile?.copyTo(target) jar.archiveFile.orNull?.asFile?.copyTo(target)
} }
@@ -22,8 +22,8 @@ fun Project.configureCompilation() {
apply<TectonicDocPlugin>() apply<TectonicDocPlugin>()
configure<JavaPluginExtension> { configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_21 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_17
} }
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
+14 -19
View File
@@ -5,6 +5,8 @@ import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.getting import org.gradle.kotlin.dsl.getting
import org.gradle.kotlin.dsl.maven import org.gradle.kotlin.dsl.maven
import org.gradle.kotlin.dsl.repositories import org.gradle.kotlin.dsl.repositories
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.kotlin.dsl.apply
fun Project.configureDependencies() { fun Project.configureDependencies() {
val testImplementation by configurations.getting val testImplementation by configurations.getting
@@ -15,6 +17,8 @@ fun Project.configureDependencies() {
val shaded by configurations.creating val shaded by configurations.creating
val libs = rootProject.project.versionCatalogs.libs
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
val shadedApi by configurations.creating { val shadedApi by configurations.creating {
shaded.extendsFrom(this) shaded.extendsFrom(this)
@@ -36,7 +40,7 @@ fun Project.configureDependencies() {
maven("https://repo.codemc.org/repository/maven-public") { maven("https://repo.codemc.org/repository/maven-public") {
name = "CodeMC" name = "CodeMC"
} }
maven("https://repo.papermc.io/repository/maven-public/") { maven("https://papermc.io/repo/repository/maven-public/") {
name = "PaperMC" name = "PaperMC"
} }
maven("https://files.minecraftforge.net/maven/") { maven("https://files.minecraftforge.net/maven/") {
@@ -48,26 +52,17 @@ fun Project.configureDependencies() {
maven("https://jitpack.io") { maven("https://jitpack.io") {
name = "JitPack" name = "JitPack"
} }
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { maven("https://api.modrinth.com/maven") {
name = "Sonatype Snapshots" name = "Modrinth"
}
maven("https://repo.opencollab.dev/maven-releases/") {
name = "OpenCollab Releases"
}
maven("https://repo.opencollab.dev/maven-snapshots/") {
name = "OpenCollab Snapshots"
}
maven("https://storehouse.okaeri.eu/repository/maven-public/") {
name = "Okaeri"
} }
} }
dependencies { dependencies {
testImplementation("org.junit.jupiter", "junit-jupiter-api", Versions.Libraries.Internal.junit) testImplementation(libs.findLibrary("libraries.internal.junit.jupiter.api").get())
testImplementation("org.junit.jupiter", "junit-jupiter-engine", Versions.Libraries.Internal.junit) testImplementation(libs.findLibrary("libraries.internal.junit.jupiter.engine").get())
compileOnly("org.jetbrains", "annotations", Versions.Libraries.Internal.jetBrainsAnnotations) compileOnly(libs.findLibrary("libraries.internal.jetbrains.annotations").get())
compileOnly("com.google.guava", "guava", Versions.Libraries.Internal.guava) compileOnly(libs.findLibrary("libraries.guava").get())
testImplementation("com.google.guava", "guava", Versions.Libraries.Internal.guava) testImplementation(libs.findLibrary("libraries.guava").get())
} }
} }
+27 -46
View File
@@ -1,14 +1,13 @@
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.URL import java.net.URL
import java.nio.file.FileSystems import java.nio.file.FileSystems
import java.nio.file.Path import java.nio.file.Files
import java.nio.file.StandardCopyOption
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.plugins.BasePluginExtension import org.gradle.api.plugins.BasePluginExtension
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.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
@@ -16,43 +15,17 @@ 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
private fun Project.installAddonsInto(dest: Path) {
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
forSubProjects(":common:addons") {
val jar = getJarTask()
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 addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}")
if (!addonPath.exists()) {
addonPath.parent.createDirectories()
addonPath.createFile()
jar.archiveFile.get().asFile.toPath().copyTo(addonPath, overwrite = true)
}
}
}
}
fun Project.configureDistribution() { fun Project.configureDistribution() {
apply(plugin = "com.gradleup.shadow") apply(plugin = "com.github.johnrengelman.shadow")
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") { val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
group = "terra" group = "terra"
doFirst { doFirst {
try { file("${buildDir}/resources/main/packs/").deleteRecursively()
file("${buildDir}/resources/main/packs/").deleteRecursively() val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/latest/default.zip")
val defaultPackUrl = downloadPack(defaultPackUrl, project)
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/default.zip")
downloadPack(defaultPackUrl, project)
} catch (_:Exception) {}
} }
} }
@@ -70,18 +43,25 @@ fun Project.configureDistribution() {
doLast { doLast {
// https://github.com/johnrengelman/shadow/issues/111 // https://github.com/johnrengelman/shadow/issues/111
val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().path val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().asFile.toPath()
installAddonsInto(dest)
} FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
} forSubProjects(":common:addons") {
val jar = getJarTask()
tasks.create("installAddonsIntoDefaultJar") {
group = "terra" println("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB")
dependsOn(compileAddons)
val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else ""
doLast { val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}")
val dest = tasks.named<Jar>("jar").get().archiveFile.get().path
installAddonsInto(dest) if (!Files.exists(addonPath)) {
Files.createDirectories(addonPath.parent)
Files.createFile(addonPath)
Files.copy(jar.archiveFile.get().asFile.toPath(), addonPath, StandardCopyOption.REPLACE_EXISTING)
}
}
}
} }
} }
@@ -145,9 +125,10 @@ fun Project.configureDistribution() {
dependsOn(downloadDefaultPacks) dependsOn(downloadDefaultPacks)
configurations = listOf(project.configurations["shaded"]) configurations = listOf(project.configurations["shaded"])
archiveClassifier.set("shaded") archiveClassifier.set("shaded")
version = project.version setVersion(project.version)
relocate("org.apache.commons", "com.dfsek.terra.lib.commons") relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm") relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
relocate("com.dfsek.paralithic", "com.dfsek.terra.lib.paralithic")
relocate("org.json", "com.dfsek.terra.lib.json") relocate("org.json", "com.dfsek.terra.lib.json")
relocate("org.yaml", "com.dfsek.terra.lib.yaml") relocate("org.yaml", "com.dfsek.terra.lib.yaml")
+12
View File
@@ -0,0 +1,12 @@
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.Project
import org.gradle.kotlin.dsl.*
internal
val Project.versionCatalogs: VersionCatalogsExtension
get() = the<VersionCatalogsExtension>()
internal
val VersionCatalogsExtension.libs: VersionCatalog
get() = named("libs")
+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
logger.info("Setting version of $path to $version") println("Setting version of $path to $version")
} }
project(project).version = version project(project).version = version
logger.info("Setting version of $project to $version") println("Setting version of $project to $version")
} }
fun Project.version(version: String): String { fun Project.version(version: String): String {
-89
View File
@@ -1,89 +0,0 @@
object Versions {
object Terra {
const val overworldConfig = "v1.3.4"
}
object Libraries {
const val tectonic = "4.2.1"
const val paralithic = "0.8.1"
const val strata = "1.3.2"
const val cloud = "2.0.0"
const val caffeine = "3.1.8"
const val slf4j = "2.0.16"
object Internal {
const val shadow = "8.3.3"
const val apacheText = "1.12.0"
const val apacheIO = "2.17.0"
const val guava = "33.3.1-jre"
const val asm = "9.7.1"
const val snakeYml = "2.3"
const val jetBrainsAnnotations = "26.0.1"
const val junit = "5.11.3"
const val nbt = "6.1"
}
}
object Fabric {
const val fabricAPI = "0.118.0+${Mod.minecraft}"
const val cloud = "2.0.0-beta.9"
}
//
// object Quilt {
// const val quiltLoader = "0.20.2"
// const val fabricApi = "7.3.1+0.89.3-1.20.1"
// }
object Mod {
const val mixin = "0.15.3+mixin.0.8.7"
const val minecraft = "1.21.4"
const val yarn = "$minecraft+build.8"
const val fabricLoader = "0.16.10"
const val architecuryLoom = "1.7.413"
const val architecturyPlugin = "3.4.159"
}
//
// object Forge {
// const val forge = "${Mod.minecraft}-48.0.13"
// const val burningwave = "12.63.0"
// }
object Bukkit {
const val minecraft = "1.21.4"
const val paperBuild = "$minecraft-R0.1-20241211.212446-17"
const val paper = paperBuild
const val paperLib = "1.0.8"
const val reflectionRemapper = "0.1.1"
const val paperDevBundle = paperBuild
const val runPaper = "2.3.1"
const val paperWeight = "1.7.2"
const val cloud = "2.0.0-beta.10"
}
//
// object Sponge {
// const val sponge = "9.0.0-SNAPSHOT"
// const val mixin = "0.8.2"
// const val minecraft = "1.17.1"
// }
//
object CLI {
const val logback = "1.5.8"
const val picocli = "4.7.6"
}
object Allay {
const val api = "0.2.0"
const val gson = "2.12.1"
}
object Minestom {
const val minestom = "187931e50b"
}
}
@@ -82,7 +82,7 @@ abstract class GenerateDocsTask : DefaultTask() {
} }
template.add(keyName.toString(), description.toString().ifBlank { template.add(keyName.toString(), description.toString().ifBlank {
logger.info("No description provided for field " + field.name + " in class " + name) println("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-2025 Polyhedral Development Copyright (c) 2020-2021 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-2025 Polyhedral Development * Copyright (c) 2020-2021 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-2025 Polyhedral Development * Copyright (c) 2020-2021 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);
@@ -10,58 +10,60 @@ import com.dfsek.terra.addons.biome.extrusion.config.BiomeExtrusionTemplate;
import com.dfsek.terra.addons.biome.extrusion.config.ReplaceableBiomeLoader; import com.dfsek.terra.addons.biome.extrusion.config.ReplaceableBiomeLoader;
import com.dfsek.terra.addons.biome.extrusion.config.extrusions.ReplaceExtrusionTemplate; import com.dfsek.terra.addons.biome.extrusion.config.extrusions.ReplaceExtrusionTemplate;
import com.dfsek.terra.addons.biome.extrusion.config.extrusions.SetExtrusionTemplate; import com.dfsek.terra.addons.biome.extrusion.config.extrusions.SetExtrusionTemplate;
import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer;
import com.dfsek.terra.api.Platform; import com.dfsek.terra.addons.manifest.api.monad.Do;
import com.dfsek.terra.api.addon.BaseAddon; import com.dfsek.terra.addons.manifest.api.monad.Get;
import com.dfsek.terra.addons.manifest.api.monad.Init;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler; import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.util.function.monad.Monad;
import com.dfsek.terra.api.util.generic.Construct;
import com.dfsek.terra.api.util.reflection.TypeKey; import com.dfsek.terra.api.util.reflection.TypeKey;
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;
import org.jetbrains.annotations.NotNull;
public class BiomeExtrusionAddon implements AddonInitializer {
public class BiomeExtrusionAddon implements MonadAddonInitializer {
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
private Platform platform;
@Inject
private BaseAddon addon;
@Override @Override
public void initialize() { public @NotNull Monad<?, Init<?>> initialize() {
platform.getEventManager() return Do.with(
.getHandler(FunctionalEventHandler.class) Get.eventManager().map(eventManager -> eventManager.getHandler(FunctionalEventHandler.class)),
.register(addon, ConfigPackPreLoadEvent.class) Get.addon(),
.then(event -> { Get.platform(),
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = ((functionalEventHandler, base, platform) -> Init.ofPure(Construct.construct(() -> {
event.getPack() functionalEventHandler.register(base, ConfigPackPostLoadEvent.class)
.getOrCreateRegistry(PROVIDER_REGISTRY_KEY); .then(event -> {
providerRegistry.register(addon.key("EXTRUSION"), BiomeExtrusionTemplate::new); Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
}) event.getPack().applyLoader(ReplaceableBiome.class,
.then(event -> { new ReplaceableBiomeLoader(biomeRegistry));
CheckedRegistry<Supplier<ObjectTemplate<Extrusion>>> extrusionRegistry = event.getPack().getOrCreateRegistry( });
EXTRUSION_REGISTRY_KEY); return functionalEventHandler.register(base, ConfigPackPreLoadEvent.class)
extrusionRegistry.register(addon.key("SET"), SetExtrusionTemplate::new); .then(event -> {
extrusionRegistry.register(addon.key("REPLACE"), ReplaceExtrusionTemplate::new); Registry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry =
}) event.getPack()
.failThrough(); .createRegistry(PROVIDER_REGISTRY_KEY);
providerRegistry.register(base.key("EXTRUSION"), BiomeExtrusionTemplate::new);
platform.getEventManager() })
.getHandler(FunctionalEventHandler.class) .then(event -> {
.register(addon, ConfigPackPostLoadEvent.class) Registry<Supplier<ObjectTemplate<Extrusion>>> extrusionRegistry =
.then(event -> { event.getPack().createRegistry(
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class); EXTRUSION_REGISTRY_KEY);
event.getPack().applyLoader(ReplaceableBiome.class, new ReplaceableBiomeLoader(biomeRegistry)); extrusionRegistry.register(base.key("SET"), SetExtrusionTemplate::new);
}); extrusionRegistry.register(base.key("REPLACE"), ReplaceExtrusionTemplate::new);
})
.failThrough();
}))
));
} }
} }
@@ -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;
} }
@@ -1,12 +1,12 @@
package com.dfsek.terra.addons.biome.extrusion.api; package com.dfsek.terra.addons.biome.extrusion.api;
import com.dfsek.terra.api.world.biome.Biome;
import java.util.Collection; import java.util.Collection;
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,21 +0,0 @@
MIT License
Copyright (c) 2020-2025 Polyhedral Development
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1,5 +0,0 @@
# biome-provider-image-v2
Implements and registers the `IMAGE` biome provider, which
utilizes various config types provided by the `library-image` addon to
distribute biomes based on images.
@@ -1,8 +0,0 @@
version = version("1.0.1")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
compileOnlyApi(project(":common:addons:library-image"))
}
@@ -1,51 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.image.v2;
import java.util.Optional;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ImageBiomeProvider implements BiomeProvider {
private final int resolution;
private final ColorConverter<Biome> colorConverter;
private final ColorSampler colorSampler;
public ImageBiomeProvider(ColorConverter<Biome> colorConverter, ColorSampler colorSampler, int resolution) {
this.resolution = resolution;
this.colorConverter = colorConverter;
this.colorSampler = colorSampler;
}
@Override
public Biome getBiome(int x, int y, int z, long seed) {
return getBiome(x, z);
}
public Biome getBiome(int x, int z) {
x /= resolution;
z /= resolution;
return colorConverter.apply(colorSampler.apply(x, z));
}
@Override
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
return Optional.of(getBiome(x, z));
}
@Override
public Iterable<Biome> getBiomes() {
return colorConverter.getEntries();
}
}
@@ -1,78 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.image.v2;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.function.Supplier;
import com.dfsek.terra.addons.biome.image.v2.config.ImageProviderTemplate;
import com.dfsek.terra.addons.biome.image.v2.config.converter.ClosestBiomeColorConverterTemplate;
import com.dfsek.terra.addons.biome.image.v2.config.converter.ExactBiomeColorConverterTemplate;
import com.dfsek.terra.addons.biome.image.v2.config.converter.mapping.DefinedBiomeColorMappingTemplate;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.addons.image.converter.mapping.BiomeDefinedColorMapping;
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ImageBiomeProviderAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<ColorConverter<Biome>>>> BIOME_COLOR_CONVERTER_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<Biome>>>> BIOME_COLOR_MAPPING_REGISTRY_KEY = new TypeKey<>() {
};
@Inject
private Platform platform;
@Inject
private BaseAddon addon;
@Override
public void initialize() {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.priority(501)
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY);
providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry =
event.getPack().getOrCreateRegistry(
BIOME_COLOR_CONVERTER_REGISTRY_KEY);
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new);
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry =
event.getPack().getOrCreateRegistry(
BIOME_COLOR_MAPPING_REGISTRY_KEY);
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"),
() -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class),
b -> b));
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new);
})
.failThrough();
}
}
@@ -1,40 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.image.v2.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.image.v2.ImageBiomeProvider;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@SuppressWarnings("FieldMayBeFinal")
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
@Value("resolution")
@Default
@Description("Sets the resolution at which to sample the image.")
private int resolution = 1;
@Value("color-sampler")
private ColorSampler colorSampler;
@Value("color-conversion")
private ColorConverter<Biome> colorConverter;
@Override
public BiomeProvider get() {
return new ImageBiomeProvider(colorConverter, colorSampler, resolution);
}
}
@@ -1,19 +0,0 @@
package com.dfsek.terra.addons.biome.image.v2.config.converter;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.image.config.converter.ClosestColorConverterTemplate;
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
import com.dfsek.terra.api.world.biome.Biome;
public class ClosestBiomeColorConverterTemplate extends ClosestColorConverterTemplate<Biome> {
@Value("match")
private ColorMapping<Biome> match;
@Override
protected ColorMapping<Biome> getMapping() {
return match;
}
}
@@ -1,37 +0,0 @@
package com.dfsek.terra.addons.biome.image.v2.config.converter;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.image.config.converter.ExactColorConverterTemplate;
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
import com.dfsek.terra.api.world.biome.Biome;
public class ExactBiomeColorConverterTemplate extends ExactColorConverterTemplate<Biome> {
@Value("match")
private ColorMapping<Biome> match;
@Value("else")
private Biome fallback;
@Value("ignore-alpha")
@Default
private boolean ignoreAlpha = true;
@Override
protected ColorMapping<Biome> getMapping() {
return match;
}
@Override
protected Biome getFallback() {
return fallback;
}
@Override
protected boolean ignoreAlpha() {
return ignoreAlpha;
}
}
@@ -1,24 +0,0 @@
package com.dfsek.terra.addons.biome.image.v2.config.converter.mapping;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.Map;
import com.dfsek.terra.addons.image.config.ColorLoader.ColorString;
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
import com.dfsek.terra.addons.image.util.MapUtil;
import com.dfsek.terra.api.world.biome.Biome;
public class DefinedBiomeColorMappingTemplate implements ObjectTemplate<ColorMapping<Biome>> {
@Value("map")
Map<ColorString, Biome> map;
@Override
public ColorMapping<Biome> get() {
var map = MapUtil.mapKeys(this.map, ColorString::getColor);
return () -> map;
}
}
@@ -1,14 +0,0 @@
schema-version: 1
contributors:
- Terra contributors
id: biome-provider-image-v2
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.image.v2.ImageBiomeProviderAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
depends:
library-image: "1.+"
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020-2025 Polyhedral Development Copyright (c) 2020-2021 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,7 +1,5 @@
version = version("1.0.1") version = version("1.0.0")
dependencies { dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader")) compileOnlyApi(project(":common:addons:manifest-addon-loader"))
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2025 Polyhedral Development * Copyright (c) 2020-2021 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,6 +7,8 @@
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;
@@ -23,62 +25,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 Math.abs(a.getRed() - b.getRed()) + Math.abs(a.getGreen() - b.getGreen()) + Math.abs(a.getBlue() - b.getBlue()); return FastMath.abs(a.getRed() - b.getRed()) + FastMath.abs(a.getGreen() - b.getGreen()) + FastMath.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(Math.floorMod(x - image.getWidth() / 2, image.getWidth()), return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()),
Math.floorMod(z - image.getHeight() / 2, image.getHeight()))); FastMath.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(Math.floorMod(x, image.getWidth()), Math.floorMod(z, image.getHeight()))); return new Color(image.getRGB(FastMath.floorMod(x, image.getWidth()), FastMath.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-2025 Polyhedral Development * Copyright (c) 2020-2021 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.
@@ -8,49 +8,44 @@
package com.dfsek.terra.addons.biome.image; package com.dfsek.terra.addons.biome.image;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer;
import com.dfsek.terra.api.Platform; import com.dfsek.terra.addons.manifest.api.monad.Do;
import com.dfsek.terra.api.addon.BaseAddon; import com.dfsek.terra.addons.manifest.api.monad.Get;
import com.dfsek.terra.addons.manifest.api.monad.Init;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler; import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.util.function.monad.Monad;
import com.dfsek.terra.api.util.reflection.TypeKey; import com.dfsek.terra.api.util.reflection.TypeKey;
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;
import org.jetbrains.annotations.NotNull;
public class ImageBiomeProviderAddon implements AddonInitializer {
public class ImageBiomeProviderAddon implements MonadAddonInitializer {
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
private Platform platform;
@Inject
private BaseAddon addon;
@Override @Override
public void initialize() { public @NotNull Monad<?, Init<?>> initialize() {
platform.getEventManager() return Do.with(
.getHandler(FunctionalEventHandler.class) Get.eventManager().map(eventManager -> eventManager.getHandler(FunctionalEventHandler.class)),
.register(addon, ConfigPackPreLoadEvent.class) Get.addon(),
.then(event -> { Get.platform(),
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry( ((functionalEventHandler, base, platform) -> Init.ofPure(
PROVIDER_REGISTRY_KEY); functionalEventHandler.register(base, ConfigPackPreLoadEvent.class)
providerRegistry.register(addon.key("IMAGE"), .then(event -> {
() -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class))); Registry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().createRegistry(
}) PROVIDER_REGISTRY_KEY);
.failThrough(); providerRegistry.register(base.key("IMAGE"),
if(platform.getTerraConfig().isDebugLog()) () -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
logger.warn( })
"The biome-provider-image addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the " + .failThrough()))
"biome-provider-image-v2 addon for future pack development instead."); );
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2025 Polyhedral Development * Copyright (c) 2020-2021 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,21 +0,0 @@
MIT License
Copyright (c) 2020-2025 Polyhedral Development
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1,12 +0,0 @@
# biome-provider-pipeline-2
The second version of the Biome Pipeline, a procedural biome provider that uses a series
of "stages" to apply "mutations" to a 2D grid of biomes.
Version 2 is a re-implementation of the original addon with the primary goal of providing
consistent scaling for noise relative to the world
(See https://github.com/PolyhedralDev/Terra/issues/264 for more details), and has been
included as a separate addon to maintain parity with packs utilizing the first version.
This addon registers the `PIPELINE` biome provider type, and all associated
configurations.
@@ -1,5 +0,0 @@
version = version("1.0.1")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
}
@@ -1,89 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.v2;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.function.Supplier;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.config.BiomePipelineTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.PipelineBiomeLoader;
import com.dfsek.terra.addons.biome.pipeline.v2.config.source.SamplerSourceTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander.ExpanderStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderListStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceListStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.SmoothStageTemplate;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<Source>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
};
@Inject
private Platform platform;
@Inject
private BaseAddon addon;
@Override
public void initialize() {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
PROVIDER_REGISTRY_KEY);
providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry(
SOURCE_REGISTRY_KEY);
sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
STAGE_REGISTRY_KEY);
stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
stageRegistry.register(addon.key("SMOOTH"), SmoothStageTemplate::new);
stageRegistry.register(addon.key("REPLACE"), ReplaceStageTemplate::new);
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListStageTemplate::new);
stageRegistry.register(addon.key("BORDER"), BorderStageTemplate::new);
stageRegistry.register(addon.key("BORDER_LIST"), BorderListStageTemplate::new);
})
.failThrough();
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPostLoadEvent.class)
.then(event -> {
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
event.getPack().applyLoader(PipelineBiome.class, new PipelineBiomeLoader(biomeRegistry));
});
}
}
@@ -1,71 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.v2;
import java.util.function.Consumer;
import com.dfsek.terra.api.util.Column;
import com.dfsek.terra.api.util.function.IntIntObjConsumer;
import com.dfsek.terra.api.util.function.IntObjConsumer;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineColumn implements Column<Biome> {
private final int min;
private final int max;
private final int x;
private final int z;
private final Biome biome;
protected BiomePipelineColumn(BiomeProvider biomeProvider, int min, int max, int x, int z, long seed) {
this.min = min;
this.max = max;
this.x = x;
this.z = z;
this.biome = biomeProvider.getBiome(x, 0, z, seed);
}
@Override
public int getMinY() {
return min;
}
@Override
public int getMaxY() {
return max;
}
@Override
public int getX() {
return x;
}
@Override
public int getZ() {
return z;
}
@Override
public Biome get(int y) {
return biome;
}
@Override
public void forRanges(int resolution, IntIntObjConsumer<Biome> consumer) {
consumer.accept(min, max, biome);
}
@Override
public void forEach(Consumer<Biome> consumer) {
for(int y = min; y < max; y++) {
consumer.accept(biome);
}
}
@Override
public void forEach(IntObjConsumer<Biome> consumer) {
for(int y = min; y < max; y++) {
consumer.accept(y, biome);
}
}
}
@@ -1,10 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
public interface BiomeChunk {
PipelineBiome get(int xInChunk, int zInChunk);
}
@@ -1,16 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api;
import com.dfsek.terra.api.util.cache.SeededVector2Key;
import java.util.List;
public interface Pipeline {
BiomeChunk generateChunk(SeededVector2Key worldCoordinates);
int getChunkSize();
Source getSource();
List<Stage> getStages();
}
@@ -1,11 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
public interface Source {
PipelineBiome get(long seed, int x, int z);
Iterable<PipelineBiome> getBiomes();
}
@@ -1,55 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.v2.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.v2.PipelineBiomeProvider;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.PipelineImpl;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
@Value("resolution")
@Default
@Description("""
The resolution at which to sample biomes.
Larger values are quadratically faster, but produce lower quality results.
For example, a value of 3 would sample every 3 blocks.""")
protected @Meta int resolution = 1;
@Value("blend.sampler")
@Default
@Description("A sampler to use for blending the edges of biomes via domain warping.")
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
@Value("blend.amplitude")
@Default
@Description("The amplitude at which to perform blending.")
protected @Meta double blendAmplitude = 0d;
@Value("pipeline.source")
@Description("The Biome Source to use for initial population of biomes.")
private @Meta Source source;
@Value("pipeline.stages")
@Description("A list of pipeline stages to apply to the result of #source")
private @Meta List<@Meta Stage> stages;
@Override
public BiomeProvider get() {
return new PipelineBiomeProvider(new PipelineImpl(source, stages, resolution, 128), resolution, blendSampler, blendAmplitude);
}
}
@@ -1,23 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class StageTemplate implements ObjectTemplate<Stage> {
@Value("sampler")
@Description("Sampler to use for stage distribution.")
protected @Meta NoiseSampler noise;
}
@@ -1,20 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.expander.FractalExpander;
public class ExpanderStageTemplate extends StageTemplate {
@Override
public Expander get() {
return new FractalExpander(noise);
}
}
@@ -1,20 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.SmoothStage;
public class SmoothStageTemplate extends StageTemplate {
@Override
public Stage get() {
return new SmoothStage(noise);
}
}
@@ -1,27 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.v2.source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class SamplerSource implements Source {
private final ProbabilityCollection<PipelineBiome> biomes;
private final NoiseSampler sampler;
public SamplerSource(ProbabilityCollection<PipelineBiome> biomes, NoiseSampler sampler) {
this.biomes = biomes;
this.sampler = sampler;
}
@Override
public PipelineBiome get(long seed, int x, int z) {
return biomes.get(sampler, x, z, seed);
}
@Override
public Iterable<PipelineBiome> getBiomes() {
return biomes.getContents();
}
}
@@ -1,12 +0,0 @@
schema-version: 1
contributors:
- Terra contributors
id: biome-provider-pipeline-v2
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.pipeline.v2.BiomePipelineAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020-2025 Polyhedral Development Copyright (c) 2020-2021 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,5 +1,5 @@
version = version("1.0.2") version = version("1.0.1")
dependencies { dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader")) compileOnlyApi(project(":common:addons:manifest-addon-loader"))
} }
@@ -1,94 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeExpander;
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeMutator;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.api.util.vector.Vector2;
public class BiomeHolderImpl implements BiomeHolder {
private final Vector2.Mutable origin;
private final int width;
private final int offset;
private BiomeDelegate[][] biomes;
public BiomeHolderImpl(int width, Vector2.Mutable origin) {
width += 4;
this.width = width;
biomes = new BiomeDelegate[width][width];
this.origin = origin;
this.offset = 2;
}
private BiomeHolderImpl(BiomeDelegate[][] biomes, Vector2.Mutable origin, int width, int offset) {
this.biomes = biomes;
this.origin = origin;
this.width = width;
this.offset = 2 * offset;
}
@Override
public BiomeHolder expand(BiomeExpander expander, long seed) {
BiomeDelegate[][] old = biomes;
int newWidth = width * 2 - 1;
biomes = new BiomeDelegate[newWidth][newWidth];
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
biomes[x * 2][z * 2] = old[x][z];
if(z != width - 1)
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
old[x][z + 1]);
if(x != width - 1)
biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), seed, old[x][z],
old[x + 1][z]);
if(x != width - 1 && z != width - 1)
biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(x + 1 + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
}
}
return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset);
}
@Override
public void mutate(BiomeMutator mutator, long seed) {
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
BiomeMutator.ViewPoint viewPoint = new BiomeMutator.ViewPoint(this, x, z);
biomes[x][z] = mutator.mutate(viewPoint, x + origin.getX(), z + origin.getZ(), seed);
}
}
}
@Override
public void fill(BiomeSource source, long seed) {
for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) {
biomes[x][z] = source.getBiome(origin.getX() + x, origin.getZ() + z, seed);
}
}
}
@Override
public BiomeDelegate getBiome(int x, int z) {
x += offset;
z += offset;
return getBiomeRaw(x, z);
}
@Override
public BiomeDelegate getBiomeRaw(int x, int z) {
if(x >= width || z >= width || x < 0 || z < 0) return null;
return biomes[x][z];
}
}
@@ -1,83 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.api.util.vector.Vector2;
public class BiomePipeline {
private final BiomeSource source;
private final List<Stage> stages;
private final int size;
private final int init;
private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) {
this.source = source;
this.stages = stages;
this.size = size;
this.init = init;
}
/**
* Get biomes in a chunk
*
* @param x Chunk X coord
* @param z Chunk Z coord
*
* @return BiomeHolder containing biomes.
*/
public BiomeHolder getBiomes(int x, int z, long seed) {
BiomeHolder holder = new BiomeHolderImpl(init, Vector2.of(x * (init - 1), z * (init - 1)).mutable());
holder.fill(source, seed);
for(Stage stage : stages) holder = stage.apply(holder, seed);
return holder;
}
public BiomeSource getSource() {
return source;
}
public List<Stage> getStages() {
return Collections.unmodifiableList(stages);
}
public int getSize() {
return size;
}
public static final class BiomePipelineBuilder {
private final int init;
private final List<Stage> stages = new ArrayList<>();
private int expand;
public BiomePipelineBuilder(int init) {
this.init = init;
expand = init;
}
public BiomePipeline build(BiomeSource source) {
for(Stage stage : stages) {
if(stage.isExpansion()) expand = expand * 2 - 1;
}
return new BiomePipeline(source, stages, expand, init);
}
public BiomePipelineBuilder addStage(Stage stage) {
stages.add(stage);
return this;
}
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2025 Polyhedral Development * Copyright (c) 2020-2021 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.
@@ -8,89 +8,87 @@
package com.dfsek.terra.addons.biome.pipeline; package com.dfsek.terra.addons.biome.pipeline;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
import com.dfsek.terra.addons.biome.pipeline.config.BiomeDelegateLoader;
import com.dfsek.terra.addons.biome.pipeline.config.BiomePipelineTemplate; import com.dfsek.terra.addons.biome.pipeline.config.BiomePipelineTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.SamplerSourceTemplate; import com.dfsek.terra.addons.biome.pipeline.config.PipelineBiomeLoader;
import com.dfsek.terra.addons.biome.pipeline.config.source.SamplerSourceTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.expander.ExpanderStageTemplate; import com.dfsek.terra.addons.biome.pipeline.config.stage.expander.ExpanderStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderListMutatorTemplate; import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderListStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderMutatorTemplate; import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListMutatorTemplate; import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceMutatorTemplate; import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothMutatorTemplate; import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.api.Source;
import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.api.Platform; import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer;
import com.dfsek.terra.addons.manifest.api.monad.Do;
import com.dfsek.terra.addons.manifest.api.monad.Get;
import com.dfsek.terra.addons.manifest.api.monad.Init;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler; import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.util.function.monad.Monad;
import com.dfsek.terra.api.util.generic.Construct;
import com.dfsek.terra.api.util.reflection.TypeKey; import com.dfsek.terra.api.util.reflection.TypeKey;
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 BiomePipelineAddon implements AddonInitializer { public class BiomePipelineAddon implements MonadAddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> 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<>() {
}; };
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
@Inject
private Platform platform;
@Inject
private BaseAddon addon;
@Override @Override
public void initialize() { public Monad<?, Init<?>> initialize() {
platform.getEventManager() return Do.with(
.getHandler(FunctionalEventHandler.class) Get.eventManager().map(eventManager -> eventManager.getHandler(FunctionalEventHandler.class)),
.register(addon, ConfigPackPreLoadEvent.class) Get.addon(),
.then(event -> { ((functionalEventHandler, base) -> Init.ofPure(Construct.construct(() -> {
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry( functionalEventHandler.register(base, ConfigPackPreLoadEvent.class)
PROVIDER_REGISTRY_KEY); .then(event -> {
providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new); CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry =
}) event.getPack().getOrCreateRegistry(
.then(event -> { PROVIDER_REGISTRY_KEY);
CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry( providerRegistry.register(base.key("PIPELINE"), BiomePipelineTemplate::new);
SOURCE_REGISTRY_KEY); })
sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new); .then(event -> {
}) CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry =
.then(event -> { event.getPack().getOrCreateRegistry(
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry( SOURCE_REGISTRY_KEY);
STAGE_REGISTRY_KEY); sourceRegistry.register(base.key("SAMPLER"), SamplerSourceTemplate::new);
stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new); })
stageRegistry.register(addon.key("SMOOTH"), SmoothMutatorTemplate::new); .then(event -> {
stageRegistry.register(addon.key("REPLACE"), ReplaceMutatorTemplate::new); CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry =
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListMutatorTemplate::new); event.getPack().getOrCreateRegistry(
stageRegistry.register(addon.key("BORDER"), BorderMutatorTemplate::new); STAGE_REGISTRY_KEY);
stageRegistry.register(addon.key("BORDER_LIST"), BorderListMutatorTemplate::new); stageRegistry.register(base.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
}) stageRegistry.register(base.key("SMOOTH"), SmoothStageTemplate::new);
.failThrough(); stageRegistry.register(base.key("REPLACE"), ReplaceStageTemplate::new);
platform.getEventManager() stageRegistry.register(base.key("REPLACE_LIST"), ReplaceListStageTemplate::new);
.getHandler(FunctionalEventHandler.class) stageRegistry.register(base.key("BORDER"), BorderStageTemplate::new);
.register(addon, ConfigPackPostLoadEvent.class) stageRegistry.register(base.key("BORDER_LIST"), BorderListStageTemplate::new);
.then(event -> { })
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class); .failThrough();
event.getPack().applyLoader(BiomeDelegate.class, new BiomeDelegateLoader(biomeRegistry)); return functionalEventHandler.register(base, ConfigPackPostLoadEvent.class)
}); .then(event -> {
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
if(platform.getTerraConfig().isDebugLog()) event.getPack().applyLoader(PipelineBiome.class,
logger.warn( new PipelineBiomeLoader(biomeRegistry));
"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.");
})))
);
} }
} }
@@ -9,14 +9,14 @@ 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;
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 @@ 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,130 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.StreamSupport;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.registry.key.StringIdentifiable;
import com.dfsek.terra.api.util.Column;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineProvider implements BiomeProvider {
private final LoadingCache<SeededVector, BiomeHolder> holderCache;
private final BiomePipeline pipeline;
private final int resolution;
private final NoiseSampler mutator;
private final double noiseAmp;
private final Set<Biome> biomes;
public BiomePipelineProvider(BiomePipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
this.resolution = resolution;
this.mutator = mutator;
this.noiseAmp = noiseAmp;
holderCache = Caffeine.newBuilder()
.maximumSize(1024)
.build(key -> pipeline.getBiomes(key.x, key.z, key.seed));
this.pipeline = pipeline;
Set<BiomeDelegate> biomeSet = new HashSet<>();
pipeline.getSource().getBiomes().forEach(biomeSet::add);
Iterable<BiomeDelegate> result = biomeSet;
for(Stage stage : pipeline.getStages()) {
result = stage.getBiomes(result); // pass through all stages
}
this.biomes = new HashSet<>();
Iterable<BiomeDelegate> finalResult = result;
result.forEach(biomeDelegate -> {
if(biomeDelegate.isEphemeral()) {
StringBuilder biomeList = new StringBuilder("\n");
StreamSupport.stream(finalResult.spliterator(), false)
.sorted(Comparator.comparing(StringIdentifiable::getID))
.forEach(delegate -> biomeList
.append(" - ")
.append(delegate.getID())
.append(':')
.append(delegate.getClass().getCanonicalName())
.append('\n'));
throw new IllegalArgumentException("Biome Pipeline leaks ephemeral biome \"" + biomeDelegate.getID() +
"\". Ensure there is a stage to guarantee replacement of the ephemeral biome. Biomes: " +
biomeList);
}
this.biomes.add(biomeDelegate.getBiome());
});
}
@Override
public Biome getBiome(int x, int y, int z, long seed) {
return getBiome(x, z, seed);
}
public Biome getBiome(int x, int z, long seed) {
x += mutator.noise(seed + 1, x, z) * noiseAmp;
z += mutator.noise(seed + 2, x, z) * noiseAmp;
x /= resolution;
z /= resolution;
int fdX = Math.floorDiv(x, pipeline.getSize());
int fdZ = Math.floorDiv(z, pipeline.getSize());
return holderCache.get(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(),
z - fdZ * pipeline.getSize()).getBiome();
}
@Override
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
return Optional.of(getBiome(x, z, seed));
}
@Override
public Iterable<Biome> getBiomes() {
return biomes;
}
@Override
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
return new BiomePipelineColumn(this, min, max, x, z, seed);
}
@Override
public int resolution() {
return resolution;
}
private record SeededVector(int x, int z, long seed) {
@Override
public boolean equals(Object obj) {
if(obj instanceof SeededVector that) {
return this.z == that.z && this.x == that.x && this.seed == that.seed;
}
return false;
}
@Override
public int hashCode() {
int code = x;
code = 31 * code + z;
return 31 * code + ((int) (seed ^ (seed >>> 32)));
}
}
}
@@ -1,20 +1,19 @@
package com.dfsek.terra.addons.biome.pipeline.v2; package com.dfsek.terra.addons.biome.pipeline;
import com.dfsek.terra.api.util.cache.SeededVector2Key;
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;
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.api.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline; import com.dfsek.terra.addons.biome.pipeline.api.Pipeline;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage; import com.dfsek.terra.addons.biome.pipeline.api.SeededVector;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.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<SeededVector2Key, 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(1024)
.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,65 +49,59 @@ 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. " + "\". Ensure there is a stage to guarantee replacement of the placeholder biome. Biomes: " +
"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 = Math.floorDiv(x, chunkSize); int chunkX = FastMath.floorDiv(x, chunkSize);
int chunkZ = Math.floorDiv(z, chunkSize); int chunkZ = FastMath.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 SeededVector2Key(chunkWorldX, chunkWorldZ, seed)).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
public Optional<Biome> getBaseBiome(int x, int z, long 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;
@@ -0,0 +1,10 @@
package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
public interface BiomeChunk {
PipelineBiome get(int xInChunk, int zInChunk);
}
@@ -1,26 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeExpander;
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeMutator;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
public interface BiomeHolder {
BiomeHolder expand(BiomeExpander expander, long seed);
void mutate(BiomeMutator mutator, long seed);
void fill(BiomeSource source, long seed);
BiomeDelegate getBiome(int x, int z);
BiomeDelegate getBiomeRaw(int x, int z);
}
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api; package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl.ViewPoint;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint; import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
/** /**
@@ -9,14 +9,14 @@ import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoin
* 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();
@@ -0,0 +1,14 @@
package com.dfsek.terra.addons.biome.pipeline.api;
import java.util.List;
public interface Pipeline {
BiomeChunk generateChunk(SeededVector worldCoordinates);
int getChunkSize();
Source getSource();
List<Stage> getStages();
}
@@ -0,0 +1,19 @@
package com.dfsek.terra.addons.biome.pipeline.api;
public record SeededVector(long seed, int x, int z) {
@Override
public boolean equals(Object obj) {
if(obj instanceof SeededVector that) {
return this.z == that.z && this.x == that.x && this.seed == that.seed;
}
return false;
}
@Override
public int hashCode() {
int code = x;
code = 31 * code + z;
return 31 * code + ((int) (seed ^ (seed >>> 32)));
}
}
@@ -0,0 +1,11 @@
package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
public interface Source {
PipelineBiome get(long seed, int x, int z);
Iterable<PipelineBiome> getBiomes();
}
@@ -1,14 +1,14 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api; package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl.ViewPoint;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint; import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
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;
} }
@@ -1,4 +1,4 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome; package com.dfsek.terra.addons.biome.pipeline.api.biome;
import java.util.Set; import java.util.Set;
@@ -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();
@@ -1,4 +1,4 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome; package com.dfsek.terra.addons.biome.pipeline.api.biome;
import java.util.Set; import java.util.Set;
@@ -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;
} }
} }
@@ -1,4 +1,4 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome; package com.dfsek.terra.addons.biome.pipeline.api.biome;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -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);
} }
} }
@@ -1,4 +1,4 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome; package com.dfsek.terra.addons.biome.pipeline.api.biome;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@@ -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,35 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
import java.util.Set;
import com.dfsek.terra.api.registry.key.StringIdentifiable;
import com.dfsek.terra.api.world.biome.Biome;
public interface BiomeDelegate extends StringIdentifiable {
static BiomeDelegate ephemeral(String id) {
return new EphemeralBiomeDelegate(id);
}
static BiomeDelegate from(Biome biome) {
return new DelegatedBiome(biome);
}
static BiomeDelegate self() {
return SelfDelegate.INSTANCE;
}
Biome getBiome();
Set<String> getTags();
default boolean isEphemeral() {
return false;
}
default boolean isSelf() {
return false;
}
}
@@ -1,40 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
import java.util.Set;
import com.dfsek.terra.api.world.biome.Biome;
final class DelegatedBiome implements BiomeDelegate {
private final Biome biome;
public DelegatedBiome(Biome biome) {
this.biome = biome;
}
@Override
public Biome getBiome() {
return biome;
}
@Override
public int hashCode() {
return biome.hashCode();
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof DelegatedBiome that)) return false;
return that.biome.equals(this.biome);
}
@Override
public Set<String> getTags() {
return biome.getTags();
}
@Override
public String getID() {
return biome.getID();
}
}
@@ -1,51 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
import java.util.HashSet;
import java.util.Set;
import com.dfsek.terra.api.world.biome.Biome;
final class EphemeralBiomeDelegate implements BiomeDelegate {
private final Set<String> tags;
private final String id;
public EphemeralBiomeDelegate(String id) {
this.id = id;
tags = new HashSet<>();
tags.add(id);
tags.add("ALL");
}
@Override
public Biome getBiome() {
throw new UnsupportedOperationException("Cannot get biome from ephemeral delegate");
}
@Override
public Set<String> getTags() {
return tags;
}
@Override
public String getID() {
return id;
}
@Override
public boolean isEphemeral() {
return true;
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof EphemeralBiomeDelegate that)) return false;
return this.id.equals(that.id);
}
}
@@ -1,40 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
import java.util.Collections;
import java.util.Set;
import com.dfsek.terra.api.world.biome.Biome;
final class SelfDelegate implements BiomeDelegate {
public static final SelfDelegate INSTANCE = new SelfDelegate();
private SelfDelegate() {
}
@Override
public Biome getBiome() {
throw new UnsupportedOperationException("Cannot get biome from self delegate");
}
@Override
public boolean isSelf() {
return true;
}
@Override
public boolean isEphemeral() {
return true;
}
@Override
public Set<String> getTags() {
return Collections.emptySet();
}
@Override
public String getID() {
return "SELF";
}
}
@@ -1,20 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api.stage;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
public interface Stage {
BiomeHolder apply(BiomeHolder in, long seed);
boolean isExpansion();
Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes);
}
@@ -1,15 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api.stage.type;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
public interface BiomeExpander {
BiomeDelegate getBetween(double x, double z, long seed, BiomeDelegate... others);
}
@@ -1,37 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.api.stage.type;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
public interface BiomeMutator {
BiomeDelegate mutate(ViewPoint viewPoint, double x, double z, long seed);
default Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes) {
return biomes;
}
class ViewPoint {
private final BiomeHolder biomes;
private final int offX;
private final int offZ;
public ViewPoint(BiomeHolder biomes, int offX, int offZ) {
this.biomes = biomes;
this.offX = offX;
this.offZ = offZ;
}
public BiomeDelegate getBiome(int x, int z) {
return biomes.getBiomeRaw(x + offX, z + offZ);
}
}
}
@@ -1,32 +0,0 @@
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.world.biome.Biome;
public class BiomeDelegateLoader implements TypeLoader<BiomeDelegate> {
private final Registry<Biome> biomeRegistry;
public BiomeDelegateLoader(Registry<Biome> biomeRegistry) {
this.biomeRegistry = biomeRegistry;
}
@Override
public BiomeDelegate load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
throws LoadException {
if(c.equals("SELF")) return BiomeDelegate.self();
return biomeRegistry
.getByID((String) c)
.map(BiomeDelegate::from)
.orElseGet(() -> BiomeDelegate.ephemeral((String) c));
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2025 Polyhedral Development * Copyright (c) 2020-2021 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.
@@ -10,45 +10,50 @@ package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.config.template.annotations.Default; import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Description; import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value; import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.List; import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.BiomePipeline; import com.dfsek.terra.addons.biome.pipeline.PipelineBiomeProvider;
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider; import com.dfsek.terra.addons.biome.pipeline.pipeline.PipelineImpl;
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage; import com.dfsek.terra.addons.biome.pipeline.api.Source;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.api.Stage;
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.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@SuppressWarnings({ "FieldMayBeFinal", "unused" }) @SuppressWarnings({ "FieldMayBeFinal", "unused" })
public class BiomePipelineTemplate extends BiomeProviderTemplate { public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
@Value("pipeline.initial-size") @Value("resolution")
@Default @Default
@Description(""" @Description("""
The initial size of biome chunks. This value must be at least 2. The resolution at which to sample biomes.
<b>This is not the final size of biome chunks. Final chunks will be much larger</b>.
It is recommended to keep biome chunks' final size in the range of [50, 300] Larger values are quadratically faster, but produce lower quality results.
to prevent performance issues. To calculate the size of biome chunks, simply For example, a value of 3 would sample every 3 blocks.""")
take initial-size and for each expand stage, multiply the running value by 2 protected @Meta int resolution = 1;
and subtract 1. (The size is also printed to the server console if you
have debug mode enabled)""")
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 Source 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;
@Value("blend.sampler")
@Default
@Description("A sampler to use for blending the edges of biomes via domain warping.")
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
@Value("blend.amplitude")
@Default
@Description("The amplitude at which to perform blending.")
protected @Meta double blendAmplitude = 0d;
@Override @Override
public BiomeProvider get() { public BiomeProvider get() {
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize); return new PipelineBiomeProvider(new PipelineImpl(source, stages, resolution, 500), resolution, blendSampler, blendAmplitude);
stages.forEach(biomePipelineBuilder::addStage);
BiomePipeline pipeline = biomePipelineBuilder.build(source);
return new BiomePipelineProvider(pipeline, resolution, blend, blendAmp);
} }
} }
@@ -1,37 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
@Value("resolution")
@Default
@Description("""
The resolution at which to sample biomes.
Larger values are quadratically faster, but produce lower quality results.
For example, a value of 3 would sample every 3 blocks.""")
protected @Meta int resolution = 1;
@Value("blend.sampler")
@Default
@Description("A sampler to use for blending the edges of biomes via domain warping.")
protected @Meta NoiseSampler blend = NoiseSampler.zero();
@Value("blend.amplitude")
@Default
@Description("The amplitude at which to perform blending.")
protected @Meta double blendAmp = 0d;
}
@@ -1,4 +1,4 @@
package com.dfsek.terra.addons.biome.pipeline.v2.config; package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.depth.DepthTracker; import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException; import com.dfsek.tectonic.api.exception.LoadException;
@@ -8,25 +8,25 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType; import java.lang.reflect.AnnotatedType;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome; import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.world.biome.Biome; 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,34 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import com.dfsek.terra.addons.biome.pipeline.source.SamplerSource;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class SamplerSourceTemplate extends SourceTemplate {
@Value("sampler")
@Description("The sampler used to distribute biomes.")
private @Meta NoiseSampler noise;
@Value("biomes")
@Description("The biomes to be distributed.")
private @Meta ProbabilityCollection<@Meta BiomeDelegate> biomes;
@Override
public BiomeSource get() {
return new SamplerSource(biomes, noise);
}
}
@@ -1,17 +0,0 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
public abstract class SourceTemplate implements ObjectTemplate<BiomeSource> {
}

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