mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-01 23:47:50 +00:00
Reformat all code
Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
This commit is contained in:
parent
1655381413
commit
c445a0434d
@ -2,32 +2,41 @@
|
|||||||
|
|
||||||
# TL;DR
|
# TL;DR
|
||||||
|
|
||||||
Polyhedral Development is dedicated to providing a harassment-free experience for everyone, regardless of gender, gender identity and
|
Polyhedral Development is dedicated to providing a harassment-free experience
|
||||||
expression, preferred pronouns, sexual orientation, disability, physical appearance, age, race, religion, etc. We do not tolerate harassment
|
for everyone, regardless of gender, gender identity and expression, preferred
|
||||||
of participants in any form.
|
pronouns, sexual orientation, disability, physical appearance, age, race,
|
||||||
|
religion, etc. We do not tolerate harassment of participants in any form.
|
||||||
|
|
||||||
This code of conduct applies to all Terra community spaces, including the github discussions tab, our
|
This code of conduct applies to all Terra community spaces, including the github
|
||||||
[community discord server](https://discord.gg/PXUEbbF), the [community subreddit](https://reddit.com/r/TerraGenerator), or any other Terra
|
discussions tab, our [community discord server](https://discord.gg/PXUEbbF),
|
||||||
space, both online and off. Anyone in violation of this code, as determined by the applicable moderators, may be subject to verbal warning,
|
the [community subreddit](https://reddit.com/r/TerraGenerator), or any other
|
||||||
expulsion from these spaces, or future events and activities for an undetermined amount of time.
|
Terra space, both online and off. Anyone in violation of this code, as
|
||||||
|
determined by the applicable moderators, may be subject to verbal warning,
|
||||||
|
expulsion from these spaces, or future events and activities for an undetermined
|
||||||
|
amount of time.
|
||||||
|
|
||||||
Some Terra community spaces may have additional rules in place, which will be made clearly available to all participants. Participants are
|
Some Terra community spaces may have additional rules in place, which will be
|
||||||
responsible for knowing and abiding by these rules.
|
made clearly available to all participants. Participants are responsible for
|
||||||
|
knowing and abiding by these rules.
|
||||||
|
|
||||||
# Longer version
|
# Longer version
|
||||||
|
|
||||||
Polyhedral Development is dedicated to providing a harassment-free experience for everyone. We do not tolerate harassment of participants in
|
Polyhedral Development is dedicated to providing a harassment-free experience
|
||||||
any form.
|
for everyone. We do not tolerate harassment of participants in any form.
|
||||||
|
|
||||||
## When and How to Use These Guidelines
|
## When and How to Use These Guidelines
|
||||||
|
|
||||||
This code of conduct applies to all Terra community spaces, both online and off. This applies to the github discussion tab,
|
This code of conduct applies to all Terra community spaces, both online and off.
|
||||||
the [Polyhedral Development community discord server](https://discord.gg/PXUEbbF), and any other Terra community. In addition, we may choose
|
This applies to the github discussion tab, the
|
||||||
to invoke them in instances of harassment outside the Terra communities, and we will punish the responsible individuals appropriately. We
|
[Polyhedral Development community discord server](https://discord.gg/PXUEbbF),
|
||||||
will not tolerate harassment in any form, even outside of Terra.
|
and any other Terra community. In addition, we may choose to invoke them in
|
||||||
|
instances of harassment outside the Terra communities, and we will punish the
|
||||||
|
responsible individuals appropriately. We will not tolerate harassment in any
|
||||||
|
form, even outside of Terra.
|
||||||
|
|
||||||
Some Terra spaces may have additional rules in place, which will be made clearly available to participants. Participants are responsible for
|
Some Terra spaces may have additional rules in place, which will be made clearly
|
||||||
knowing and abiding by these rules, in addition to this code of conduct.
|
available to participants. Participants are responsible for knowing and abiding
|
||||||
|
by these rules, in addition to this code of conduct.
|
||||||
|
|
||||||
## Expected Behavior
|
## Expected Behavior
|
||||||
|
|
||||||
@ -35,33 +44,43 @@ The following behaviors are expected of all members of the Terra community:
|
|||||||
|
|
||||||
### Be Respectful
|
### Be Respectful
|
||||||
|
|
||||||
Value each other's ideas, styles and viewpoints. We may not always agree, but disagreement is no excuse for poor manners. Be open to
|
Value each other's ideas, styles and viewpoints. We may not always agree, but
|
||||||
different possibilities and to being wrong. Be respectful in all interactions and communications, especially when debating the merits of
|
disagreement is no excuse for poor manners. Be open to different possibilities
|
||||||
different options. Be aware of your impact and how intense interactions may be affecting people. Be direct, constructive and positive. Take
|
and to being wrong. Be respectful in all interactions and communications,
|
||||||
responsibility for your impact, and your mistakes – if someone says they have been harmed through your words or actions, listen carefully,
|
especially when debating the merits of different options. Be aware of your
|
||||||
apologize sincerely, and correct the behavior going forward.
|
impact and how intense interactions may be affecting people. Be direct,
|
||||||
|
constructive and positive. Take responsibility for your impact, and your
|
||||||
|
mistakes – if someone says they have been harmed through your words or actions,
|
||||||
|
listen carefully, apologize sincerely, and correct the behavior going forward.
|
||||||
|
|
||||||
#### Be Prepared to Admit When You are Wrong
|
#### Be Prepared to Admit When You are Wrong
|
||||||
|
|
||||||
Any member of the Terra community should always be open to new ideas and must always be open to the possibility of being wrong. Nobody can
|
Any member of the Terra community should always be open to new ideas and must
|
||||||
always be right, and we are only human; we are [fallible](https://www.merriam-webster.com/dictionary/fallible) by nature. It is okay to make
|
always be open to the possibility of being wrong. Nobody can always be right,
|
||||||
mistakes, but we must be willing to admit when we make one.
|
and we are only human; we are
|
||||||
|
[fallible](https://www.merriam-webster.com/dictionary/fallible) by nature.
|
||||||
|
It is okay to make mistakes, but we must be willing to admit when we make one.
|
||||||
|
|
||||||
### Be Direct but Professional
|
### Be Direct but Professional
|
||||||
|
|
||||||
We are likely to have some discussions about if and when criticism is respectful and when it's not. We must be able to speak directly when
|
We are likely to have some discussions about if and when criticism is respectful
|
||||||
we disagree and when we think we need to improve. We cannot withhold hard truths. Doing so respectfully is hard, doing so when others don't
|
and when it's not. We must be able to speak directly when we disagree and when
|
||||||
seem to be listening is harder, and hearing such comments when one is the recipient can be even harder still. We need to be honest and
|
we think we need to improve. We cannot withhold hard truths. Doing so
|
||||||
direct, as well as respectful.
|
respectfully is hard, doing so when others don't seem to be listening is harder,
|
||||||
|
and hearing such comments when one is the recipient can be even harder still. We
|
||||||
|
need to be honest and direct, as well as respectful.
|
||||||
|
|
||||||
### Be Inclusive
|
### Be Inclusive
|
||||||
|
|
||||||
Seek diverse perspectives. Diversity of views and of people on teams powers innovation, even if it is not always comfortable. Encourage all
|
Seek diverse perspectives. Diversity of views and of people on teams powers
|
||||||
voices. Help new perspectives be heard and listen actively. If you find yourself dominating a discussion, it is especially important to step
|
innovation, even if it is not always comfortable. Encourage all voices. Help new
|
||||||
back and encourage other voices to join in. Be aware of how much time is taken up by dominant members of the group. Provide alternative ways
|
perspectives be heard and listen actively. If you find yourself dominating a
|
||||||
to contribute or participate when possible.
|
discussion, it is especially important to step back and encourage other voices
|
||||||
|
to join in. Be aware of how much time is taken up by dominant members of the
|
||||||
|
group. Provide alternative ways to contribute or participate when possible.
|
||||||
|
|
||||||
Be inclusive of everyone in an interaction, respecting and facilitating people's participation whether they are:
|
Be inclusive of everyone in an interaction, respecting and facilitating people's
|
||||||
|
participation whether they are:
|
||||||
|
|
||||||
- Not native language speakers
|
- Not native language speakers
|
||||||
- Coming from a different culture
|
- Coming from a different culture
|
||||||
@ -70,47 +89,60 @@ Be inclusive of everyone in an interaction, respecting and facilitating people's
|
|||||||
- Facing other challenges to participate
|
- Facing other challenges to participate
|
||||||
- Or anything else. Be respectful of *everyone* at *all times*.
|
- Or anything else. Be respectful of *everyone* at *all times*.
|
||||||
|
|
||||||
Think about how you might facilitate alternative ways to contribute or participate. If you find yourself dominating a discussion, step back.
|
Think about how you might facilitate alternative ways to contribute or
|
||||||
Make way for other voices and listen actively to them.
|
participate. If you find yourself dominating a discussion, step back. Make way
|
||||||
|
for other voices and listen actively to them.
|
||||||
|
|
||||||
### Understand Different Perspectives
|
### Understand Different Perspectives
|
||||||
|
|
||||||
Our goal should not be to "win" every disagreement or argument. A more productive goal is to be open to ideas that make our own ideas
|
Our goal should not be to "win" every disagreement or argument. A more
|
||||||
better. Strive to be an example for inclusive thinking. "Winning" is when different perspectives make our work richer and stronger. That
|
productive goal is to be open to ideas that make our own ideas better. Strive to
|
||||||
means, you must pay attention to all ideas proposed. Don't disregard one without giving it the attention it deserves.
|
be an example for inclusive thinking. "Winning" is when different perspectives
|
||||||
|
make our work richer and stronger. That means, you must pay attention to all
|
||||||
|
ideas proposed. Don't disregard one without giving it the attention it deserves.
|
||||||
|
|
||||||
### Appreciate and Accommodate Our Similarities and Differences
|
### Appreciate and Accommodate Our Similarities and Differences
|
||||||
|
|
||||||
People come from many cultures and backgrounds. Cultural differences can encompass everything from official religious observances to
|
People come from many cultures and backgrounds. Cultural differences can
|
||||||
personal habits to clothing. Be respectful of anyone with different cultural practices, attitudes and beliefs. Work to eliminate your own
|
encompass everything from official religious observances to personal habits to
|
||||||
biases, prejudices and discriminatory practices. Think of others' needs from their point of view. Use preferred titles (including
|
clothing. Be respectful of anyone with different cultural practices, attitudes
|
||||||
pronouns<sup>[\[1\]](#1)</sup>) and the appropriate tone of voice. Respect people's right to privacy and confidentiality. Be open to
|
and beliefs. Work to eliminate your own biases, prejudices and discriminatory
|
||||||
learning from and educating others as well as educating yourself; it is unrealistic to expect someone to know the cultural practices of
|
practices. Think of others' needs from their point of view. Use preferred
|
||||||
every ethnic and cultural group. Therefore we must be ready to correct someone if they make a mistake, and must be ready ourselves to change
|
titles (including pronouns<sup>[\[1\]](#1)</sup>) and the appropriate tone of
|
||||||
and learn if we make a mistake.
|
voice. Respect people's right to privacy and confidentiality. Be open to
|
||||||
|
learning from and educating others as well as educating yourself; it is
|
||||||
|
unrealistic to expect someone to know the cultural practices of every ethnic and
|
||||||
|
cultural group. Therefore we must be ready to correct someone if they make a
|
||||||
|
mistake, and must be ready ourselves to change and learn if we make a mistake.
|
||||||
|
|
||||||
### Lead by Example
|
### Lead by Example
|
||||||
|
|
||||||
By matching your actions with your words, you become a person others want to follow. Your actions influence others to behave and respond in
|
By matching your actions with your words, you become a person others want to
|
||||||
ways that are valuable and appropriate for our organizational outcomes. Design your community and your work for inclusion. Hold yourself and
|
follow. Your actions influence others to behave and respond in ways that are
|
||||||
others accountable for inclusive behaviors.
|
valuable and appropriate for our organizational outcomes. Design your community
|
||||||
|
and your work for inclusion. Hold yourself and others accountable for inclusive
|
||||||
|
behaviors.
|
||||||
|
|
||||||
## Behavior That Will Not Be Tolerated
|
## Behavior That Will Not Be Tolerated
|
||||||
|
|
||||||
The following behaviors are considered to be unacceptable and will not be tolerated:
|
The following behaviors are considered to be unacceptable and will not be
|
||||||
|
tolerated:
|
||||||
|
|
||||||
### Violence and Threats of Violence
|
### Violence and Threats of Violence
|
||||||
|
|
||||||
Violence and threats of violence are not acceptable - online or offline. This includes incitement of violence toward any individual,
|
Violence and threats of violence are not acceptable - online or offline. This
|
||||||
including encouraging a person to commit self-harm, engage in self-harm, or put themselves in a negative position (e.g. one which can lead
|
includes incitement of violence toward any individual, including encouraging a
|
||||||
to an increase of depression, etc.).
|
person to commit self-harm, engage in self-harm, or put themselves in a negative
|
||||||
|
position (e.g. one which can lead to an increase of depression, etc.).
|
||||||
|
|
||||||
### Personal Attacks
|
### Personal Attacks
|
||||||
|
|
||||||
Conflicts will inevitably arise, but frustration should never turn into a personal attack. It is not okay to insult, demean or belittle
|
Conflicts will inevitably arise, but frustration should never turn into a
|
||||||
others. Attacking someone for their opinions, beliefs and ideas is not acceptable. It is important to speak directly when we disagree and
|
personal attack. It is not okay to insult, demean or belittle others. Attacking
|
||||||
when we think we need to improve, but such discussions must be conducted respectfully and professionally, remaining focused on the issue at
|
someone for their opinions, beliefs and ideas is not acceptable. It is important
|
||||||
hand.
|
to speak directly when we disagree and when we think we need to improve, but
|
||||||
|
such discussions must be conducted respectfully and professionally, remaining
|
||||||
|
focused on the issue at hand.
|
||||||
|
|
||||||
### Derogatory Language
|
### Derogatory Language
|
||||||
|
|
||||||
@ -135,30 +167,40 @@ Offensive, unwelcome, or hurtful comments related to:
|
|||||||
- Socioeconomic status
|
- Socioeconomic status
|
||||||
- Religion
|
- Religion
|
||||||
- Employment
|
- Employment
|
||||||
- Or anything really. Just don't be offensive towards people, insult them, or make unwanted comments.
|
- Or anything really. Just don't be offensive towards people, insult them, or
|
||||||
|
make unwanted comments.
|
||||||
|
|
||||||
is not acceptable. This includes deliberately referring to someone by a gender that they do not identify with, and/or questioning the
|
is not acceptable. This includes deliberately referring to someone by a gender
|
||||||
legitimacy of an individual's gender identity. If you're unsure if a word is derogatory, don't use it. This also includes repeated subtle
|
that they do not identify with, and/or questioning the legitimacy of an
|
||||||
and/or indirect discrimination; when asked to stop, stop the behavior in question.
|
individual's gender identity. If you're unsure if a word is derogatory, don't
|
||||||
|
use it. This also includes repeated subtle and/or indirect discrimination; when
|
||||||
|
asked to stop, stop the behavior in question.
|
||||||
|
|
||||||
### Unwelcome Sexual Attention or Physical Contact
|
### Unwelcome Sexual Attention or Physical Contact
|
||||||
|
|
||||||
Unwelcome sexual attention or unwelcome physical contact is not acceptable. This includes sexualized comments, jokes or imagery in
|
Unwelcome sexual attention or unwelcome physical contact is not acceptable. This
|
||||||
interactions, communications or presentation materials, as well as inappropriate touching, groping, or sexual advances. Additionally,
|
includes sexualized comments, jokes or imagery in interactions, communications
|
||||||
touching a person without permission, including sensitive areas such as their hair, pregnant stomach, mobility device (wheelchair, scooter,
|
or presentation materials, as well as inappropriate touching, groping, or sexual
|
||||||
etc) or tattoos is unacceptable. This includes physically blocking or intimidating another person. Physical contact or simulated physical
|
advances. Additionally, touching a person without permission, including
|
||||||
contact (e.g. emojis like ":​kiss:", ":hug:", or ":kiss_mark:", textual descriptions like "\*hug\*", "\*backrub\*", or "\*kisses
|
sensitive areas such as their hair, pregnant stomach, mobility device (
|
||||||
you\*", etc.) without affirmative consent or after a request to stop will not be accepted.
|
wheelchair, scooter, etc) or tattoos is unacceptable. This includes physically
|
||||||
|
blocking or intimidating another person. Physical contact or simulated physical
|
||||||
|
contact (e.g. emojis like ":​kiss:", ":hug:", or ":kiss_mark:", textual
|
||||||
|
descriptions like "\*hug\*", "\*backrub\*", or "\*kisses you\*", etc.) without
|
||||||
|
affirmative consent or after a request to stop will not be accepted.
|
||||||
|
|
||||||
### Sexual Behaviour Where it is Not Appropriate
|
### Sexual Behaviour Where it is Not Appropriate
|
||||||
|
|
||||||
Uninvited or off-topic sexual images, text, or behaviour in spaces where they're not appropriate will not be accepted whatsoever. We are an
|
Uninvited or off-topic sexual images, text, or behaviour in spaces where they're
|
||||||
open community, which means spaces must be appropriate for all ages, and everybody must feel comfortable. Discussion of sexual things, will
|
not appropriate will not be accepted whatsoever. We are an open community, which
|
||||||
be prohibited unless otherwise noted.
|
means spaces must be appropriate for all ages, and everybody must feel
|
||||||
|
comfortable. Discussion of sexual things, will be prohibited unless otherwise
|
||||||
|
noted.
|
||||||
|
|
||||||
### Discussion of Sensitive Topics
|
### Discussion of Sensitive Topics
|
||||||
|
|
||||||
Discussion of sensitive topics when asked to stop, or when not appropriate. Including, but not limited to:
|
Discussion of sensitive topics when asked to stop, or when not appropriate.
|
||||||
|
Including, but not limited to:
|
||||||
|
|
||||||
- Anything sexual
|
- Anything sexual
|
||||||
- Gore
|
- Gore
|
||||||
@ -167,171 +209,241 @@ Discussion of sensitive topics when asked to stop, or when not appropriate. Incl
|
|||||||
- Anything related to death
|
- Anything related to death
|
||||||
- Or really anything that someone may be sensitive about.
|
- Or really anything that someone may be sensitive about.
|
||||||
|
|
||||||
shall not be tolerated. As a community for all ages and all kinds of people, we must cater to everyone, and must make sure everyone feels
|
shall not be tolerated. As a community for all ages and all kinds of people, we
|
||||||
comfortable here. Repeatedly breaking someone else's boundaries will not be tolerated.
|
must cater to everyone, and must make sure everyone feels comfortable here.
|
||||||
|
Repeatedly breaking someone else's boundaries will not be tolerated.
|
||||||
|
|
||||||
### Disruptive Behavior
|
### Disruptive Behavior
|
||||||
|
|
||||||
Sustained disruption of events, forums, or meetings, online or otherwise, including talks and presentations, will not be tolerated. This
|
Sustained disruption of events, forums, or meetings, online or otherwise,
|
||||||
includes:
|
including talks and presentations, will not be tolerated. This includes:
|
||||||
|
|
||||||
- 'Talking over', 'heckling', or otherwise disrupting speakers.
|
- 'Talking over', 'heckling', or otherwise disrupting speakers.
|
||||||
- Making derogatory comments about someone else's choices, pushing people to do something they do not wish to do, talking about their
|
- Making derogatory comments about someone else's choices, pushing people to do
|
||||||
choices or personal preferences to others, or pressuring them to do something they don't wish to - physically or through jeering.
|
something they do not wish to do, talking about their choices or personal
|
||||||
|
preferences to others, or pressuring them to do something they don't wish to -
|
||||||
|
physically or through jeering.
|
||||||
- Behaviour that intentionally disrupts an event.
|
- Behaviour that intentionally disrupts an event.
|
||||||
- Otherwise influencing actions that may cause hostility in the session.
|
- Otherwise influencing actions that may cause hostility in the session.
|
||||||
|
|
||||||
### Influencing Unacceptable Behavior
|
### Influencing Unacceptable Behavior
|
||||||
|
|
||||||
We will treat influencing or leading such activities the same way we treat the activities themselves, and thus the same consequences apply.
|
We will treat influencing or leading such activities the same way we treat the
|
||||||
To make someone do something bad is the same thing as if you were to do it yourself, and we will not tolerate it.
|
activities themselves, and thus the same consequences apply. To make someone do
|
||||||
|
something bad is the same thing as if you were to do it yourself, and we will
|
||||||
|
not tolerate it.
|
||||||
|
|
||||||
### Stalking or Following
|
### Stalking or Following
|
||||||
|
|
||||||
Stalking or following in any form (offline or online) is unnacceptable. In addition, you may not take pictures or record video of others
|
Stalking or following in any form (offline or online) is unnacceptable. In
|
||||||
without their express permission or when asked to stop. Any individual may also request for you to delete all footage you have of them, even
|
addition, you may not take pictures or record video of others without their
|
||||||
if you took it with their prior consent.
|
express permission or when asked to stop. Any individual may also request for
|
||||||
|
you to delete all footage you have of them, even if you took it with their prior
|
||||||
|
consent.
|
||||||
|
|
||||||
### Publication of Personal Information
|
### Publication of Personal Information
|
||||||
|
|
||||||
The publication of personally identifying information (commonly known as "[doxxing](https://en.wikipedia.org/wiki/Doxing)") is directly
|
The publication of personally identifying information (commonly known
|
||||||
prohibited. You may not publish information that someone wants to keep private, unless it is necessary to protect vulnerable people from
|
as "[doxxing](https://en.wikipedia.org/wiki/Doxing)") is directly prohibited.
|
||||||
intentional abuse. Addditionally, you may not deliberately "out" any aspect of a person's identity without their consent, this includes
|
You may not publish information that someone wants to keep private, unless it is
|
||||||
gender, pronouns, sexual identity, etc.
|
necessary to protect vulnerable people from intentional abuse. Addditionally,
|
||||||
|
you may not deliberately "out" any aspect of a person's identity without their
|
||||||
|
consent, this includes gender, pronouns, sexual identity, etc.
|
||||||
|
|
||||||
Unless it pretains to a case of harassment, as outlined here, in which case some personally identifying information may need to be brought
|
Unless it pretains to a case of harassment, as outlined here, in which case some
|
||||||
up in private with the appropriate moderation team to help aid our efforts in keeping the community safe.
|
personally identifying information may need to be brought up in private with the
|
||||||
|
appropriate moderation team to help aid our efforts in keeping the community
|
||||||
|
safe.
|
||||||
|
|
||||||
### Deliberate Misuse of Pronouns<sup>[\[1\]](#1)</sup> or Names
|
### Deliberate Misuse of Pronouns<sup>[\[1\]](#1)</sup> or Names
|
||||||
|
|
||||||
As an inclusive community, we must respect everyone. That means respecting the pronouns or names they wish for us to use. Deliberate
|
As an inclusive community, we must respect everyone. That means respecting the
|
||||||
misgendering, misuse of preferred pronouns<sup>[\[1\]](#1)</sup>, or use of 'dead' or rejected names is not to be tolerated. (If someone
|
pronouns or names they wish for us to use. Deliberate misgendering, misuse of
|
||||||
*accidentally* uses the incorrect pronouns, gender, or name, politely ask them to use the correct pronouns/gender/name. But if they are to
|
preferred pronouns<sup>[\[1\]](#1)</sup>, or use of 'dead' or rejected names is
|
||||||
continue using the incorrect pronouns, gender, or name, then you should escalate and report them to us.)
|
not to be tolerated. (If someone
|
||||||
|
*accidentally* uses the incorrect pronouns, gender, or name, politely ask them
|
||||||
|
to use the correct pronouns/gender/name. But if they are to continue using the
|
||||||
|
incorrect pronouns, gender, or name, then you should escalate and report them to
|
||||||
|
us.)
|
||||||
|
|
||||||
### Not Stopping After Multiple Requests
|
### Not Stopping After Multiple Requests
|
||||||
|
|
||||||
If someone asks you to stop doing something, then you should stop. Continuing to do it may be considered harassment, and can lead you to be
|
If someone asks you to stop doing something, then you should stop. Continuing to
|
||||||
removed from our community.
|
do it may be considered harassment, and can lead you to be removed from our
|
||||||
|
community.
|
||||||
|
|
||||||
## Complains We May Ignore
|
## Complains We May Ignore
|
||||||
|
|
||||||
Additionally, Terra prioritizes marginalized people's safety over privileged people's comfort. We reserve the right to ignore complaints
|
Additionally, Terra prioritizes marginalized people's safety over privileged
|
||||||
regarding:
|
people's comfort. We reserve the right to ignore complaints regarding:
|
||||||
|
|
||||||
- Claims of discrimination against non-marginalized or oppressed groups (eg. being 'superphobic', meaning to not support people who are
|
- Claims of discrimination against non-marginalized or oppressed groups (eg.
|
||||||
'superstraight', which is a dog whistle for transphobic groups, or being 'cisphobic' without large amounts of evidence, etc.), or claims
|
being 'superphobic', meaning to not support people who are
|
||||||
of discrimination with no evidence. (Basically, don't report 'cisphobia' to us, because it doesn't exist. But if someone is mocking you or
|
'superstraight', which is a dog whistle for transphobic groups, or being '
|
||||||
making fun of you for being cis, and it is *really* getting out of hand, then do tell us.)
|
cisphobic' without large amounts of evidence, etc.), or claims of
|
||||||
- Reasonable communication of boundaries, such as "leave me alone," "go away," or "I'm not discussing this with you." (If someone is asking
|
discrimination with no evidence. (Basically, don't report 'cisphobia' to us,
|
||||||
you to stop, that is not reason for you to report them as harassing you.)
|
because it doesn't exist. But if someone is mocking you or making fun of you
|
||||||
- Communicating in a 'tone' you don't find [congenial](https://www.thefreedictionary.com/congenial). (You may not report someone for
|
for being cis, and it is *really* getting out of hand, then do tell us.)
|
||||||
harassment for being 'annoyed with you' or 'talking sternly to you')
|
- Reasonable communication of boundaries, such as "leave me alone," "go away,"
|
||||||
- Criticizing or calling out racist, sexist, discriminatory, or otherwise oppressive behavior or assumptions. (You may not say that someone
|
or "I'm not discussing this with you." (If someone is asking you to stop, that
|
||||||
is harassing you if they are telling you to stop discriminating against someone.)
|
is not reason for you to report them as harassing you.)
|
||||||
- Disagreements that do not qualify as harassment. If you have a simple disagreement with someone, and they have not been discriminating to
|
- Communicating in a 'tone' you don't
|
||||||
anyone, in any form, then we will not take action against them. Two people are allowed to disagree on things without it getting toxic.
|
find [congenial](https://www.thefreedictionary.com/congenial). (You may not
|
||||||
|
report someone for harassment for being 'annoyed with you' or 'talking sternly
|
||||||
|
to you')
|
||||||
|
- Criticizing or calling out racist, sexist, discriminatory, or otherwise
|
||||||
|
oppressive behavior or assumptions. (You may not say that someone is harassing
|
||||||
|
you if they are telling you to stop discriminating against someone.)
|
||||||
|
- Disagreements that do not qualify as harassment. If you have a simple
|
||||||
|
disagreement with someone, and they have not been discriminating to anyone, in
|
||||||
|
any form, then we will not take action against them. Two people are allowed to
|
||||||
|
disagree on things without it getting toxic.
|
||||||
|
|
||||||
We may also additionally choose to enact punishment for submitting a complaint in bad-faith or without adequate justification, if we deem
|
We may also additionally choose to enact punishment for submitting a complaint
|
||||||
necessary; if you're submitting a complaint just to troll or to annoy people, we may choose to have you banned or removed from the community
|
in bad-faith or without adequate justification, if we deem necessary; if you're
|
||||||
spaces. Don't waste our time.
|
submitting a complaint just to troll or to annoy people, we may choose to have
|
||||||
|
you banned or removed from the community spaces. Don't waste our time.
|
||||||
|
|
||||||
In order to protect volunteers from abuse and burnout, we reserve the right to reject any report we believe to have been made in bad faith
|
In order to protect volunteers from abuse and burnout, we reserve the right to
|
||||||
or with misintent. Reports intended to silence legitimate criticism may be deleted without response.
|
reject any report we believe to have been made in bad faith or with misintent.
|
||||||
|
Reports intended to silence legitimate criticism may be deleted without
|
||||||
|
response.
|
||||||
|
|
||||||
## Reporting
|
## Reporting
|
||||||
|
|
||||||
Terra has a global moderation team which is currently comprised of the following members:
|
Terra has a global moderation team which is currently comprised of the following
|
||||||
|
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)
|
||||||
|
|
||||||
\* The preferred method of communication is through discord. Although we will still be responsive on the other platforms, we will be more
|
\* The preferred method of communication is through discord. Although we will
|
||||||
responsive on discord.
|
still be responsive on the other platforms, we will be more responsive on
|
||||||
|
discord.
|
||||||
|
|
||||||
These are people you can contact for anything regarding this code of conduct.
|
These are people you can contact for anything regarding this code of conduct.
|
||||||
|
|
||||||
If you are being harassed by a member of the Terra community, or by someone in a Terra community space, notice that someone else is being
|
If you are being harassed by a member of the Terra community, or by someone in a
|
||||||
harassed, or have any other concerns, please contact a moderator of the platform it occurred on, or someone on the global moderation team.
|
Terra community space, notice that someone else is being harassed, or have any
|
||||||
If the person who is harassing you is on the global moderation team, they will [recuse](https://www.thefreedictionary.com/recuse) themselves
|
other concerns, please contact a moderator of the platform it occurred on, or
|
||||||
from handling your incident. (Meaning: if you are reporting someone on the team, they will not be involved in the discussion.) We will
|
someone on the global moderation team. If the person who is harassing you is on
|
||||||
respond within a reasonable time frame, but generally within about 1 day.
|
the global moderation team, they
|
||||||
|
will [recuse](https://www.thefreedictionary.com/recuse) themselves from handling
|
||||||
|
your incident. (Meaning: if you are reporting someone on the team, they will not
|
||||||
|
be involved in the discussion.) We will respond within a reasonable time frame,
|
||||||
|
but generally within about 1 day.
|
||||||
|
|
||||||
This code of conduct applies to Terra community spaces, but if you are being harassed by a member of Terra *outside* our spaces, we still
|
This code of conduct applies to Terra community spaces, but if you are being
|
||||||
want to know about it as we may choose to take action within our community. We will take all good-faith reports seriously and will always
|
harassed by a member of Terra *outside* our spaces, we still want to know about
|
||||||
attempt to handle them appropriately. This includes harassment outside our spaces and harassment that took place at any point in time. The
|
it as we may choose to take action within our community. We will take all
|
||||||
moderation team reserves the right to exclude people from Terra communities based on their past behavior, including behavior outside Terra
|
good-faith reports seriously and will always attempt to handle them
|
||||||
spaces and behavior towards people who are not in Terra.
|
appropriately. This includes harassment outside our spaces and harassment that
|
||||||
|
took place at any point in time. The moderation team reserves the right to
|
||||||
|
exclude people from Terra communities based on their past behavior, including
|
||||||
|
behavior outside Terra spaces and behavior towards people who are not in Terra.
|
||||||
|
|
||||||
Note: although we only have the ability to moderate official community spaces, if you are being harassed by someone in a non-official
|
Note: although we only have the ability to moderate official community spaces,
|
||||||
community space, and the moderation team of that platform refuses to do anything to help you (or even if they *do* help you), then you
|
if you are being harassed by someone in a non-official community space, and the
|
||||||
should notify us so that we may take appropriate action.
|
moderation team of that platform refuses to do anything to help you (or even if
|
||||||
|
they *do* help you), then you should notify us so that we may take appropriate
|
||||||
|
action.
|
||||||
|
|
||||||
We will respect confidentiality requests for the purpose of protecting victims of abuse. At our discretion, we may publicly name a person
|
We will respect confidentiality requests for the purpose of protecting victims
|
||||||
which we have received harassment complaints about, or privately warn third parties about them, but only if we believe that doing so will
|
of abuse. At our discretion, we may publicly name a person which we have
|
||||||
increase the safety of Terra community members or the general public. We will not name harassment victims or reporters of harassment
|
received harassment complaints about, or privately warn third parties about
|
||||||
(assuming the report was made in good-faith) without their explicit consent; all reports will remain anonymous by default.
|
them, but only if we believe that doing so will increase the safety of Terra
|
||||||
|
community members or the general public. We will not name harassment victims or
|
||||||
|
reporters of harassment
|
||||||
|
(assuming the report was made in good-faith) without their explicit consent; all
|
||||||
|
reports will remain anonymous by default.
|
||||||
|
|
||||||
## Consequences of Unacceptable Behavior
|
## Consequences of Unacceptable Behavior
|
||||||
|
|
||||||
Participants asked to stop any harassing behavior are expected to comply immediately. Whether or not you comply immediately, you may still
|
Participants asked to stop any harassing behavior are expected to comply
|
||||||
face consequences for you actions, but if the harasser doesn't comply immediately then we may choose to take additional actions to protect
|
immediately. Whether or not you comply immediately, you may still face
|
||||||
the Terra community members or the individual being harassed.
|
consequences for you actions, but if the harasser doesn't comply immediately
|
||||||
|
then we may choose to take additional actions to protect the Terra community
|
||||||
|
members or the individual being harassed.
|
||||||
|
|
||||||
Violation of this code can result in being asked to leave an event or online space, either temporarily or for the duration of the event, or
|
Violation of this code can result in being asked to leave an event or online
|
||||||
being banned from participation in spaces, or future events and activities in perpetuity. If a participant engages in harassing behavior,
|
space, either temporarily or for the duration of the event, or being banned from
|
||||||
the global moderation team may take any action they deem appropriate, up to and including expulsion from all Terra community spaces and
|
participation in spaces, or future events and activities in perpetuity. If a
|
||||||
identification of the participant as a harasser to other Terra community members or the general public. Bad behavior from any community
|
participant engages in harassing behavior, the global moderation team may take
|
||||||
|
any action they deem appropriate, up to and including expulsion from all Terra
|
||||||
|
community spaces and identification of the participant as a harasser to other
|
||||||
|
Terra community members or the general public. Bad behavior from any community
|
||||||
member, including those with decision-making authority, will not be tolerated.
|
member, including those with decision-making authority, will not be tolerated.
|
||||||
|
|
||||||
In addition, any participants who abuse the reporting process will be considered to be in violation of these guidelines and subject to
|
In addition, any participants who abuse the reporting process will be considered
|
||||||
consequences. False reporting, especially to retaliate or exclude, will not be accepted or tolerated.
|
to be in violation of these guidelines and subject to consequences. False
|
||||||
|
reporting, especially to retaliate or exclude, will not be accepted or
|
||||||
|
tolerated.
|
||||||
|
|
||||||
## Questions
|
## Questions
|
||||||
|
|
||||||
if you have further questions for anything not addressed here, you may open an issue on this github repo, or contact a member of the global
|
if you have further questions for anything not addressed here, you may open an
|
||||||
moderation team.
|
issue on this github repo, or contact a member of the global moderation team.
|
||||||
|
|
||||||
## License and Attribution
|
## License and Attribution
|
||||||
|
|
||||||
This set of guidelines is distributed under a
|
This set of guidelines is distributed under a
|
||||||
[Creative Commons Attribution-ShareAlike license](https://creativecommons.org/licenses/by-sa/3.0/).
|
[Creative Commons Attribution-ShareAlike license](https://creativecommons.org/licenses/by-sa/3.0/)
|
||||||
|
.
|
||||||
|
|
||||||
These guidelines have been adapted from
|
These guidelines have been adapted from
|
||||||
[Mozilla's Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/), which were adapted
|
[Mozilla's Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/)
|
||||||
from:
|
, which were adapted from:
|
||||||
|
|
||||||
- Mozilla's original Community Participation Guidelines
|
- 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/)
|
-
|
||||||
- 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
|
Mozilla's [View Source Conference Code of Conduct](https://viewsourceconf.org/berlin-2016/code-of-conduct/)
|
||||||
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/).
|
- 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
|
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.
|
the [LGBTQ in Technology Code of Conduct](https://lgbtq.technology/coc.html) and
|
||||||
|
a few other sources.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
#### \[1\]
|
#### \[1\]
|
||||||
|
|
||||||
You provide a set of pronouns that everyone is comfortable addressing you with. Although some people are comfortable
|
You provide a set of pronouns that everyone is comfortable addressing you with.
|
||||||
using [neopronouns](https://www.mypronouns.org/neopronouns), not everyone is. Therefore, if you use neopronouns, you should have at *least*
|
Although some people are comfortable
|
||||||
one set of more common pronouns (One of he/him, she/her, or they/them; it doesn't matter which one. Anyone who doesn't respect your basic
|
using [neopronouns](https://www.mypronouns.org/neopronouns), not everyone is.
|
||||||
pronouns will be removed from the community.) that people may use, should they so choose, as some people are not comfortable
|
Therefore, if you use neopronouns, you should have at *least*
|
||||||
using [neopronouns](https://www.mypronouns.org/neopronouns). But if someone refuses to use your more common pronouns, you should report them
|
one set of more common pronouns (One of he/him, she/her, or they/them; it
|
||||||
to us. Additionally, you may not ask people to use unreasonable pronouns, such as 'acab/acabself', 'that/bitch', 'ur/mom', or
|
doesn't matter which one. Anyone who doesn't respect your basic pronouns will be
|
||||||
'dream/dreamself' (pronouns related to real people, eg. the minecraft youtuber 'dreamwastaken'). Doing so will be considered mockery of
|
removed from the community.) that people may use, should they so choose, as some
|
||||||
individuals who use non-standard pronouns and is very disrespectful.
|
people are not comfortable
|
||||||
|
using [neopronouns](https://www.mypronouns.org/neopronouns). But if someone
|
||||||
|
refuses to use your more common pronouns, you should report them to us.
|
||||||
|
Additionally, you may not ask people to use unreasonable pronouns, such as '
|
||||||
|
acab/acabself', 'that/bitch', 'ur/mom', or
|
||||||
|
'dream/dreamself' (pronouns related to real people, eg. the minecraft youtuber '
|
||||||
|
dreamwastaken'). Doing so will be considered mockery of individuals who use
|
||||||
|
non-standard pronouns and is very disrespectful.
|
303
CONTRIBUTING.md
303
CONTRIBUTING.md
@ -1,17 +1,22 @@
|
|||||||
# Contributing to Terra
|
# Contributing to Terra
|
||||||
|
|
||||||
First off, thank you for considering contributing to Terra. It's people like you that make Terra such a great tool.
|
First off, thank you for considering contributing to Terra. It's people like you
|
||||||
|
that make Terra such a great tool.
|
||||||
|
|
||||||
Following these guidelines helps to effectively use the time of the developers managing and developing this open source project, making it
|
Following these guidelines helps to effectively use the time of the developers
|
||||||
more enjoyable for all of us.
|
managing and developing this open source project, making it more enjoyable for
|
||||||
|
all of us.
|
||||||
|
|
||||||
Terra is an open source project and we love to receive contributions from our community, you! There are many ways to contribute, from
|
Terra is an open source project and we love to receive contributions from our
|
||||||
writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be
|
community, you! There are many ways to contribute, from writing tutorials or
|
||||||
incorporated into Terra.
|
blog posts, improving the documentation, submitting bug reports and feature
|
||||||
|
requests or writing code which can be incorporated into Terra.
|
||||||
|
|
||||||
The following is a set of guidelines for contributing to Terra and its packages, which are hosted in
|
The following is a set of guidelines for contributing to Terra and its packages,
|
||||||
the [PolyhedralDev Organization](https://github.com/PolyhedralDev) on GitHub. These are mostly guidelines, not rules. Use your best
|
which are hosted in
|
||||||
judgment, and feel free to propose changes to this document in a pull request.
|
the [PolyhedralDev Organization](https://github.com/PolyhedralDev) on GitHub.
|
||||||
|
These are mostly guidelines, not rules. Use your best judgment, and feel free to
|
||||||
|
propose changes to this document in a pull request.
|
||||||
|
|
||||||
#### Table Of Contents
|
#### Table Of Contents
|
||||||
|
|
||||||
@ -51,8 +56,10 @@ judgment, and feel free to propose changes to this document in a pull request.
|
|||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
|
|
||||||
This project and everyone participating in it is governed by the [Terra of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected
|
This project and everyone participating in it is governed by
|
||||||
to uphold this code. Please report unacceptable behavior to [Terra global moderation team](CODE_OF_CONDUCT.md#Reporting).
|
the [Terra of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected
|
||||||
|
to uphold this code. Please report unacceptable behavior
|
||||||
|
to [Terra global moderation team](CODE_OF_CONDUCT.md#Reporting).
|
||||||
|
|
||||||
## I don't want to read this whole thing I just have a question!!!
|
## I don't want to read this whole thing I just have a question!!!
|
||||||
|
|
||||||
@ -66,160 +73,219 @@ We have an official discord server where you can request help from various users
|
|||||||
|
|
||||||
### Your First Contribution
|
### Your First Contribution
|
||||||
|
|
||||||
Unsure where to begin contributing to Terra? You can start by looking through "beginner" and "help wanted" issues:
|
Unsure where to begin contributing to Terra? You can start by looking through "
|
||||||
|
beginner" and "help wanted" issues:
|
||||||
|
|
||||||
- [Beginner issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Good%20First%20Issue) - issues which should be friendly to
|
- [Beginner issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Good%20First%20Issue)
|
||||||
anyone new to terra.
|
- issues which should be friendly to anyone new to terra.
|
||||||
- [Help wanted issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Help%20Wanted) - issues which should be a bit more involved
|
- [Help wanted issues](https://github.com/PolyhedralDev/Terra/labels/Note%3A%20Help%20Wanted)
|
||||||
than "beginner" issues.
|
- issues which should be a bit more involved than "beginner" issues.
|
||||||
|
|
||||||
New to github? Working on your first Pull Request? Check
|
New to github? Working on your first Pull Request? Check
|
||||||
out [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github)
|
out [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github)
|
||||||
to get you up on your feet.
|
to get you up on your feet.
|
||||||
|
|
||||||
At this point, you're ready to make your changes! Feel free to ask for help; everyone is a beginner at first!
|
At this point, you're ready to make your changes! Feel free to ask for help;
|
||||||
|
everyone is a beginner at first!
|
||||||
|
|
||||||
If a maintainer asks you to "rebase" your PR, they're saying that a lot of code has changed, and that you need to update your branch so it's
|
If a maintainer asks you to "rebase" your PR, they're saying that a lot of code
|
||||||
easier to merge.
|
has changed, and that you need to update your branch so it's easier to merge.
|
||||||
|
|
||||||
### Reporting Bugs
|
### Reporting Bugs
|
||||||
|
|
||||||
This section guides you through submitting a bug report for Terra. Following these guidelines helps maintainers and the community understand
|
This section guides you through submitting a bug report for Terra. Following
|
||||||
your report, and spend their time fixing the issue instead of understanding what you mean.
|
these guidelines helps maintainers and the community understand your report, and
|
||||||
|
spend their time fixing the issue instead of understanding what you mean.
|
||||||
|
|
||||||
Before creating bug reports, please check [this list](#before-submitting-a-bug-report) as you might find out that you don't need to create
|
Before creating bug reports, please
|
||||||
one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report).
|
check [this list](#before-submitting-a-bug-report) as you might find out that
|
||||||
|
you don't need to create one. When you are creating a bug report,
|
||||||
|
please [include as many details as possible](#how-do-i-submit-a-good-bug-report)
|
||||||
|
.
|
||||||
|
|
||||||
> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
|
> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
|
||||||
|
|
||||||
#### Before Submitting A Bug Report
|
#### Before Submitting A Bug Report
|
||||||
|
|
||||||
- Join the [discord server](https://discord.dfsek.com) to help resolve simple issues.
|
- Join the [discord server](https://discord.dfsek.com) to help resolve simple
|
||||||
- You must be on the LATEST version of Terra to receive any support. There is no support for older versions of Terra.
|
issues.
|
||||||
- Make sure that this is not a *specific* compatibility issue with another terrain generation mod. Do not request *specific* compatibility
|
- You must be on the LATEST version of Terra to receive any support. There is no
|
||||||
with mods or plugins (e.g. "Compatibility with TechCraft v7"). That should be implemented in an addon, **not** in the main project.
|
support for older versions of Terra.
|
||||||
*General* compatibility (e.g. "Ability to pull Vanilla/Modded features from parent biomes") will be considered in the main project.
|
- Make sure that this is not a *specific* compatibility issue with another
|
||||||
- Search for any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+) open with your problem. If you open
|
terrain generation mod. Do not request *specific* compatibility with mods or
|
||||||
a duplicate, it will be closed as such.
|
plugins (e.g. "Compatibility with TechCraft v7"). That should be implemented
|
||||||
- Make sure that it is actually Terra causing the issue, and not another mod/plugin. You can do this by testing to see if you can recreate
|
in an addon, **not** in the main project.
|
||||||
the issue without Terra installed.
|
*General* compatibility (e.g. "Ability to pull Vanilla/Modded features from
|
||||||
- Double check that this is not an issue with a specific Terra *pack* or Terra *addon*, and instead applies to all of Terra.
|
parent biomes") will be considered in the main project.
|
||||||
- Include a copy of the latest.log file. Putting *just* the exception is not enough. We need to be able to check that there wasn't anything
|
- Search for
|
||||||
else before that caused it.
|
any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+)
|
||||||
- Be sure to fill out all the required information and give descriptions of everything.
|
open with your problem. If you open a duplicate, it will be closed as such.
|
||||||
|
- Make sure that it is actually Terra causing the issue, and not another
|
||||||
|
mod/plugin. You can do this by testing to see if you can recreate the issue
|
||||||
|
without Terra installed.
|
||||||
|
- Double check that this is not an issue with a specific Terra *pack* or Terra *
|
||||||
|
addon*, and instead applies to all of Terra.
|
||||||
|
- Include a copy of the latest.log file. Putting *just* the exception is not
|
||||||
|
enough. We need to be able to check that there wasn't anything else before
|
||||||
|
that caused it.
|
||||||
|
- Be sure to fill out all the required information and give descriptions of
|
||||||
|
everything.
|
||||||
|
|
||||||
#### How Do I Submit A (Good) Bug Report?
|
#### How Do I Submit A (Good) Bug Report?
|
||||||
|
|
||||||
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/)
|
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/)
|
||||||
. [Create an issue](https://github.com/PolyhedralDev/Terra/issues/new) and provide the prerequisite information by filling in the Bug Report
|
. [Create an issue](https://github.com/PolyhedralDev/Terra/issues/new) and
|
||||||
template.
|
provide the prerequisite information by filling in the Bug Report template.
|
||||||
|
|
||||||
Explain the problem and include additional details to help maintainers reproduce the problem:
|
Explain the problem and include additional details to help maintainers reproduce
|
||||||
|
the problem:
|
||||||
|
|
||||||
- **Use a clear and descriptive title** for the issue to identify the problem.
|
- **Use a clear and descriptive title** for the issue to identify the problem.
|
||||||
- **Describe the exact steps which reproduce the problem** in as many details as possible. When listing steps, **don't just say what you
|
- **Describe the exact steps which reproduce the problem** in as many details as
|
||||||
did, but explain how you did it**.
|
possible. When listing steps, **don't just say what you did, but explain how
|
||||||
|
you did it**.
|
||||||
- **Provide specific examples to demonstrate the steps**.
|
- **Provide specific examples to demonstrate the steps**.
|
||||||
- **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
|
- **Describe the behavior you observed after following the steps** and point out
|
||||||
|
what exactly is the problem with that behavior.
|
||||||
- **Explain which behavior you expected to see instead and why.**
|
- **Explain which behavior you expected to see instead and why.**
|
||||||
- **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more
|
- **If the problem wasn't triggered by a specific action**, describe what you
|
||||||
information using the guidelines below.
|
were doing before the problem happened and share more information using the
|
||||||
|
guidelines below.
|
||||||
|
|
||||||
Include details about your configuration and environment:
|
Include details about your configuration and environment:
|
||||||
|
|
||||||
- **Which version of Terra are you using?** You can get the exact version by running `/te version`.
|
- **Which version of Terra are you using?** You can get the exact version by
|
||||||
- **What's the name and version of the platform you're using**? (eg. Spigot, Fabric, Paper, etc.)
|
running `/te version`.
|
||||||
|
- **What's the name and version of the platform you're using**? (eg. Spigot,
|
||||||
|
Fabric, Paper, etc.)
|
||||||
- **Which external plugins or mods do you have installed?**
|
- **Which external plugins or mods do you have installed?**
|
||||||
- **Which Terra packs do you have installed?** You can get that list by running `/te packs`.
|
- **Which Terra packs do you have installed?** You can get that list by
|
||||||
- **Which Terra addons do you have installed?** You can get that list by running `/te addons`.
|
running `/te packs`.
|
||||||
|
- **Which Terra addons do you have installed?** You can get that list by
|
||||||
|
running `/te addons`.
|
||||||
|
|
||||||
### Suggesting Enhancements
|
### Suggesting Enhancements
|
||||||
|
|
||||||
This section guides you through submitting an enhancement suggestion for Terra, including completely new features and minor improvements to
|
This section guides you through submitting an enhancement suggestion for Terra,
|
||||||
existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related
|
including completely new features and minor improvements to existing
|
||||||
suggestions.
|
functionality. Following these guidelines helps maintainers and the community
|
||||||
|
understand your suggestion and find related suggestions.
|
||||||
|
|
||||||
Before creating enhancement suggestions, please check [this list](#before-submitting-an-enhancement-suggestion) as you might find out that
|
Before creating enhancement suggestions, please
|
||||||
you don't need to create one. When you are creating an enhancement suggestion,
|
check [this list](#before-submitting-an-enhancement-suggestion) as you might
|
||||||
please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion).
|
find out that you don't need to create one. When you are creating an enhancement
|
||||||
|
suggestion,
|
||||||
|
please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion)
|
||||||
|
.
|
||||||
|
|
||||||
#### Before Submitting An Enhancement Suggestion
|
#### Before Submitting An Enhancement Suggestion
|
||||||
|
|
||||||
- You must be on the **LATEST** version of Terra to make sure your feature hasn't been added yet.
|
- You must be on the **LATEST** version of Terra to make sure your feature
|
||||||
- Search for any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+) (Including closed!) with your
|
hasn't been added yet.
|
||||||
problem. If you open a duplicate, it will be closed as such.
|
- Search for
|
||||||
|
any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+) (
|
||||||
|
Including closed!) with your problem. If you open a duplicate, it will be
|
||||||
|
closed as such.
|
||||||
- Verify that this is actually within the scope of Terra.
|
- Verify that this is actually within the scope of Terra.
|
||||||
- Be sure that this is not a feature request that should be made for a specific Terra *pack*, and instead applies to all of Terra.
|
- Be sure that this is not a feature request that should be made for a specific
|
||||||
- Be sure that this is not something that should be implemented as a Terra addon, and instead applies to all of Terra.
|
Terra *pack*, and instead applies to all of Terra.
|
||||||
- Make sure that you attach a copy of the latest.log file, if there are any exceptions thrown in the console. Putting *just* the exception
|
- Be sure that this is not something that should be implemented as a Terra
|
||||||
**is not enough**. We need to be able to check that there wasn't anything else before that caused it.
|
addon, and instead applies to all of Terra.
|
||||||
|
- Make sure that you attach a copy of the latest.log file, if there are any
|
||||||
|
exceptions thrown in the console. Putting *just* the exception
|
||||||
|
**is not enough**. We need to be able to check that there wasn't anything else
|
||||||
|
before that caused it.
|
||||||
|
|
||||||
#### How Do I Submit A (Good) Enhancement Suggestion?
|
#### How Do I Submit A (Good) Enhancement Suggestion?
|
||||||
|
|
||||||
Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). Create an issue on our main repository
|
Enhancement suggestions are tracked
|
||||||
and provide the following information:
|
as [GitHub issues](https://guides.github.com/features/issues/). Create an issue
|
||||||
|
on our main repository and provide the following information:
|
||||||
|
|
||||||
- **Use a clear and descriptive title** for the issue to identify the suggestion.
|
- **Use a clear and descriptive title** for the issue to identify the
|
||||||
- **Provide a step-by-step description of the suggested enhancement** in as many details as possible.
|
suggestion.
|
||||||
|
- **Provide a step-by-step description of the suggested enhancement** in as many
|
||||||
|
details as possible.
|
||||||
- **Provide specific examples to demonstrate the steps**.
|
- **Provide specific examples to demonstrate the steps**.
|
||||||
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
|
- **Describe the current behavior** and **explain which behavior you expected to
|
||||||
- **Explain why this enhancement would be useful** to most Terra users and isn't something that can or should be implemented as an addon.
|
see instead** and why.
|
||||||
|
- **Explain why this enhancement would be useful** to most Terra users and isn't
|
||||||
|
something that can or should be implemented as an addon.
|
||||||
|
|
||||||
### Pull Requests
|
### Pull Requests
|
||||||
|
|
||||||
This section guides you through submitting a pull request for Terra.
|
This section guides you through submitting a pull request for Terra.
|
||||||
|
|
||||||
While the prerequisites above must be satisfied prior to having your pull request reviewed, the reviewer(s) may ask you to complete
|
While the prerequisites above must be satisfied prior to having your pull
|
||||||
additional design work, tests, or other changes before your pull request can be ultimately accepted.
|
request reviewed, the reviewer(s) may ask you to complete additional design
|
||||||
|
work, tests, or other changes before your pull request can be ultimately
|
||||||
|
accepted.
|
||||||
|
|
||||||
#### Before Submitting A Pull Request
|
#### Before Submitting A Pull Request
|
||||||
|
|
||||||
- You must be on the **LATEST** version of Terra to make sure your feature hasn't been added yet.
|
- You must be on the **LATEST** version of Terra to make sure your feature
|
||||||
- Search for any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+) (Including closed!) with your
|
hasn't been added yet.
|
||||||
problem. If you open a duplicate, it will be closed as such.
|
- Search for
|
||||||
|
any [already existing issues](https://github.com/PolyhedralDev/Terra/issues?q=is%3Aissue+) (
|
||||||
|
Including closed!) with your problem. If you open a duplicate, it will be
|
||||||
|
closed as such.
|
||||||
- Verify that this is actually within the scope of Terra.
|
- Verify that this is actually within the scope of Terra.
|
||||||
- Be sure that this is not a feature request that should be made for a specific Terra *pack*, and instead applies to all of Terra.
|
- Be sure that this is not a feature request that should be made for a specific
|
||||||
- Be sure that this is not something that should be implemented as a Terra addon, and instead applies to all of Terra.
|
Terra *pack*, and instead applies to all of Terra.
|
||||||
- Make sure that you attach a copy of the latest.log file, if there are any exceptions thrown in the console. Putting *just* the
|
- Be sure that this is not something that should be implemented as a Terra
|
||||||
exception **is not enough**. We need to be able to check that there wasn't anything else before that caused it.
|
addon, and instead applies to all of Terra.
|
||||||
|
- Make sure that you attach a copy of the latest.log file, if there are any
|
||||||
|
exceptions thrown in the console. Putting *just* the exception **is not
|
||||||
|
enough**. We need to be able to check that there wasn't anything else before
|
||||||
|
that caused it.
|
||||||
|
|
||||||
#### How Do I Submit A (Good) Pull Request?
|
#### How Do I Submit A (Good) Pull Request?
|
||||||
|
|
||||||
Pull Requests are tracked as [GitHub Pull Requests](https://guides.github.com/activities/forking/#making-a-pull-request). Create a pr on our
|
Pull Requests are tracked
|
||||||
main repository and provide the following information:
|
as [GitHub Pull Requests](https://guides.github.com/activities/forking/#making-a-pull-request)
|
||||||
|
. Create a pr on our main repository and provide the following information:
|
||||||
|
|
||||||
- **Use a clear and descriptive title** to identify the pull request.
|
- **Use a clear and descriptive title** to identify the pull request.
|
||||||
- **State what this pull request adds/fixes**.
|
- **State what this pull request adds/fixes**.
|
||||||
- **Be sure that you are the owner of the code you contributed** or that it can be licensed under the GPLv3.
|
- **Be sure that you are the owner of the code you contributed** or that it can
|
||||||
- **Provide a description goals and non-goals of the pull request** in as many details as possible.
|
be licensed under the GPLv3.
|
||||||
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
|
- **Provide a description goals and non-goals of the pull request** in as many
|
||||||
- **Explain why this enhancement would be useful** to most Terra users and isn't something that can or should be implemented as an addon.
|
details as possible.
|
||||||
|
- **Describe the current behavior** and **explain which behavior you expected to
|
||||||
|
see instead** and why.
|
||||||
|
- **Explain why this enhancement would be useful** to most Terra users and isn't
|
||||||
|
something that can or should be implemented as an addon.
|
||||||
|
|
||||||
## Styleguides
|
## Styleguides
|
||||||
|
|
||||||
### Git Commits
|
### Git Commits
|
||||||
|
|
||||||
Following this is not mandatory, but rather a set of guidelines. As long as your commit messages aren't absolutely awful, it's probably
|
Following this is not mandatory, but rather a set of guidelines. As long as your
|
||||||
fine. But it would be nice if you followed them.
|
commit messages aren't absolutely awful, it's probably fine. But it would be
|
||||||
|
nice if you followed them.
|
||||||
|
|
||||||
#### Committing
|
#### Committing
|
||||||
|
|
||||||
When you commit code, try to avoid committing large amounts of code in a single go. Splitting up code into smaller commits is much nicer and
|
When you commit code, try to avoid committing large amounts of code in a single
|
||||||
makes it easier to trace a feature to a single commit.
|
go. Splitting up code into smaller commits is much nicer and makes it easier to
|
||||||
|
trace a feature to a single commit.
|
||||||
|
|
||||||
Try to stick to one feature/fix/etc. per commit. A good rule of thumb is if you need to use the word "and" in the subject line, then it
|
Try to stick to one feature/fix/etc. per commit. A good rule of thumb is if you
|
||||||
should probably™ be two commits.
|
need to use the word "and" in the subject line, then it should probably™ be two
|
||||||
|
commits.
|
||||||
|
|
||||||
#### Git Commit Messages
|
#### Git Commit Messages
|
||||||
|
|
||||||
- Subject line must fit the following format: `<type>: <short summary>`. Type must be one of the following:
|
- Subject line must fit the following format: `<type>: <short summary>`. Type
|
||||||
|
must be one of the following:
|
||||||
- Build: Changes that affect the build system or external dependencies.
|
- Build: Changes that affect the build system or external dependencies.
|
||||||
- Docs: Documentation only changes.
|
- Docs: Documentation only changes.
|
||||||
- Feat: A new feature.
|
- Feat: A new feature.
|
||||||
- Fix: A bug fix.
|
- Fix: A bug fix.
|
||||||
- Perf: Performance improvements.
|
- Perf: Performance improvements.
|
||||||
- Refactor: Refactoring sections of the codebase.
|
- Refactor: Refactoring sections of the codebase.
|
||||||
- Repo: Changes to the repository structure that do not affect code. (Eg. modification of the `README.md` file, etc.)
|
- Repo: Changes to the repository structure that do not affect code. (Eg.
|
||||||
|
modification of the `README.md` file, etc.)
|
||||||
- Revert: Revert a previous commit.
|
- Revert: Revert a previous commit.
|
||||||
- Style: Code style updates.
|
- Style: Code style updates.
|
||||||
- Test: Anything related to testing.
|
- Test: Anything related to testing.
|
||||||
@ -266,7 +332,8 @@ should probably™ be two commits.
|
|||||||
|
|
||||||
### Code Styleguide
|
### Code Styleguide
|
||||||
|
|
||||||
Use an IDE with support for `.editorconfig` files. There is an included editorconfig file in the base of the project so that your IDE should
|
Use an IDE with support for `.editorconfig` files. There is an included
|
||||||
|
editorconfig file in the base of the project so that your IDE should
|
||||||
automatically use the correct code style settings.
|
automatically use the correct code style settings.
|
||||||
|
|
||||||
### Documentation Styleguide
|
### Documentation Styleguide
|
||||||
@ -279,41 +346,55 @@ TODO
|
|||||||
|
|
||||||
#### General Compatibility
|
#### General Compatibility
|
||||||
|
|
||||||
General compatibility (example: injection of Vanilla structures/features/carvers into packs) is acceptable in the main project.
|
General compatibility (example: injection of Vanilla structures/features/carvers
|
||||||
|
into packs) is acceptable in the main project.
|
||||||
|
|
||||||
- General compatibility features should be *disabled by default*. Having things auto-injected causes unpredictable behaviour that is
|
- General compatibility features should be *disabled by default*. Having things
|
||||||
annoying to diagnose. General-compatibility options should have config values attached which are disabled by default.
|
auto-injected causes unpredictable behaviour that is annoying to diagnose.
|
||||||
- These config options should also be *simple to use*. Think of the people who will be using these compatibility options. They want to flick
|
General-compatibility options should have config values attached which are
|
||||||
a switch and have things be compatible. That means that a majority of compatibility options should stay in `pack.yml`, to make it simple
|
disabled by default.
|
||||||
to go into a pack and turn on specific compatibilities. This does *not* mean that more advanced compatibility options are off the table,
|
- These config options should also be *simple to use*. Think of the people who
|
||||||
for example, look at Feature compatibility, where features can either be automatically injected, *or* configured individually per Terra
|
will be using these compatibility options. They want to flick a switch and
|
||||||
biome, depending on how much control the user wants.
|
have things be compatible. That means that a majority of compatibility options
|
||||||
|
should stay in `pack.yml`, to make it simple to go into a pack and turn on
|
||||||
|
specific compatibilities. This does *not* mean that more advanced
|
||||||
|
compatibility options are off the table, for example, look at Feature
|
||||||
|
compatibility, where features can either be automatically injected, *or*
|
||||||
|
configured individually per Terra biome, depending on how much control the
|
||||||
|
user wants.
|
||||||
|
|
||||||
#### Specific Compatibility
|
#### Specific Compatibility
|
||||||
|
|
||||||
Specific compatibility should *not* be put in the main project. (Example: Adding the ability to generate TechCraft v7's doo-dads with a
|
Specific compatibility should *not* be put in the main project. (Example: Adding
|
||||||
TerraScript function)
|
the ability to generate TechCraft v7's doo-dads with a TerraScript function)
|
||||||
|
|
||||||
Having specific compatibilities leads to tons of extra dependencies to keep track of, as well as adding lots of additional stuff to
|
Having specific compatibilities leads to tons of extra dependencies to keep
|
||||||
maintain. It quickly becomes a mess. Especially when most users will never need to use this feature.
|
track of, as well as adding lots of additional stuff to maintain. It quickly
|
||||||
|
becomes a mess. Especially when most users will never need to use this feature.
|
||||||
|
|
||||||
We have designed an addon API for exactly this purpose. **Specific compatibilities are welcome and encouraged, in the form of addons.**
|
We have designed an addon API for exactly this purpose. **Specific
|
||||||
|
compatibilities are welcome and encouraged, in the form of addons.**
|
||||||
|
|
||||||
### Platform-Agnostic Design
|
### Platform-Agnostic Design
|
||||||
|
|
||||||
Terra must, at all times, remain platform agnostic. This means it must be able to run on theoretically any voxel based platform. Including
|
Terra must, at all times, remain platform agnostic. This means it must be able
|
||||||
non-minecraft games like Terasology.
|
to run on theoretically any voxel based platform. Including non-minecraft games
|
||||||
|
like Terasology.
|
||||||
|
|
||||||
When adding a new feature to `common`, make no assumptions about what platform it'll be running on.
|
When adding a new feature to `common`, make no assumptions about what platform
|
||||||
|
it'll be running on.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- Don't assume the world height is 256.
|
- Don't assume the world height is 256.
|
||||||
- Don't assume that a specific block, item, or entity exists. (Eg. don't assume there exists a block called `minecraft:grass_block`)
|
- Don't assume that a specific block, item, or entity exists. (Eg. don't assume
|
||||||
|
there exists a block called `minecraft:grass_block`)
|
||||||
|
|
||||||
### Data-Driven
|
### Data-Driven
|
||||||
|
|
||||||
When adding a new feature, make it abstract. Don't make assumptions about "specific use cases." If you can only think of a few use cases,
|
When adding a new feature, make it abstract. Don't make assumptions about "
|
||||||
your idea should probably be generalized.
|
specific use cases." If you can only think of a few use cases, your idea should
|
||||||
|
probably be generalized.
|
||||||
|
|
||||||
You must use configs effectively. Make configs that are *powerful* but also *make sense* and are \[easy\] to use.
|
You must use configs effectively. Make configs that are *powerful* but also *
|
||||||
|
make sense* and are \[easy\] to use.
|
39
README.md
39
README.md
@ -1,19 +1,23 @@
|
|||||||
# Terra
|
# Terra
|
||||||
|
|
||||||
Terra is an incredibly powerful free & open-source data-driven, platform-agnostic world generator. It allows you to create a world exactly
|
Terra is an incredibly powerful free & open-source data-driven,
|
||||||
to your specifications, with no knowledge of Java required.
|
platform-agnostic world generator. It allows you to create a world exactly to
|
||||||
|
your specifications, with no knowledge of Java required.
|
||||||
|
|
||||||
## Downloads:
|
## Downloads:
|
||||||
|
|
||||||
* Paper+ servers (Paper, Tuinity, Purpur, etc): [SpigotMC](https://www.spigotmc.org/resources/85151/)
|
* Paper+ servers (Paper, Tuinity, Purpur,
|
||||||
* Fabric: [Modrinth](https://modrinth.com/mod/terra) / [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
etc): [SpigotMC](https://www.spigotmc.org/resources/85151/)
|
||||||
* Forge **(ALPHA - NOT PRODUCTION-READY)**: [Modrinth](https://modrinth.com/mod/terra)
|
* Fabric: [Modrinth](https://modrinth.com/mod/terra)
|
||||||
|
/ [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
||||||
|
* Forge **(ALPHA - NOT
|
||||||
|
PRODUCTION-READY)**: [Modrinth](https://modrinth.com/mod/terra)
|
||||||
/ [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
/ [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
|
||||||
|
|
||||||
## Building and Running Terra
|
## Building and Running Terra
|
||||||
|
|
||||||
To build, simply run `./gradlew build` (`gradlew.bat build` on Windows). This will build all platforms, and produce JARs
|
To build, simply run `./gradlew build` (`gradlew.bat build` on Windows). This
|
||||||
in `platforms/<platform>/build/libs`
|
will build all platforms, and produce JARs in `platforms/<platform>/build/libs`
|
||||||
|
|
||||||
### Production JARs:
|
### Production JARs:
|
||||||
|
|
||||||
@ -32,10 +36,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
|
||||||
* `installPaper` - Install a [Paper](https://github.com/PaperMC/Paper) test server. (Only needs to be run once).
|
* `installPaper` - Install a [Paper](https://github.com/PaperMC/Paper) test
|
||||||
* `installPurpur` - Install a [Purpur](https://github.com/pl3xgaming/Purpur) test server. (Only needs to be run once).
|
server. (Only needs to be run once).
|
||||||
* `runPaper` - Run the Paper test server with Terra (`installPaper` must have been run previously).
|
* `installPurpur` - Install a [Purpur](https://github.com/pl3xgaming/Purpur)
|
||||||
* `runPurpur` - Run the Purpur test server with Terra (`installPurpur` must have been run previously).
|
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.
|
||||||
@ -45,9 +53,12 @@ To run Minecraft with Terra in the IDE (for testing) use the following tasks:
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are welcome! If you want to see a feature in Terra, please, open an issue, or implement it yourself and submit a PR!
|
Contributions are welcome! If you want to see a feature in Terra, please, open
|
||||||
Join the discord [here](https://discord.gg/PXUEbbF) if you would like to talk more about the project!
|
an issue, or implement it yourself and submit a PR!
|
||||||
|
Join the discord [here](https://discord.gg/PXUEbbF) if you would like to talk
|
||||||
|
more about the project!
|
||||||
|
|
||||||
## Beta
|
## Beta
|
||||||
|
|
||||||
Terra is still in beta! While it is stable, it is not feature-complete. There is a lot to be added!
|
Terra is still in beta! While it is stable, it is not feature-complete. There is
|
||||||
|
a lot to be added!
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
import com.dfsek.terra.*
|
import com.dfsek.terra.configureCompilation
|
||||||
|
import com.dfsek.terra.configureDependencies
|
||||||
|
import com.dfsek.terra.configureDistribution
|
||||||
|
import com.dfsek.terra.configurePublishing
|
||||||
|
import com.dfsek.terra.getGitHash
|
||||||
|
|
||||||
val versionObj = Version("6", "0", "0", true)
|
val versionObj = Version("6", "0", "0", true)
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
version = versionObj
|
version = versionObj
|
||||||
group = "com.dfsek.terra"
|
group = "com.dfsek.terra"
|
||||||
|
|
||||||
configureDependencies()
|
configureDependencies()
|
||||||
configureCompilation()
|
configureCompilation()
|
||||||
configurePublishing()
|
configurePublishing()
|
||||||
|
|
||||||
tasks.withType<JavaCompile>().configureEach {
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
options.isFork = true
|
options.isFork = true
|
||||||
options.isIncremental = true
|
options.isIncremental = true
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Test>().configureEach {
|
tasks.withType<Test>().configureEach {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
|
|
||||||
maxHeapSize = "2G"
|
maxHeapSize = "2G"
|
||||||
ignoreFailures = false
|
ignoreFailures = false
|
||||||
failFast = true
|
failFast = true
|
||||||
maxParallelForks = (Runtime.getRuntime().availableProcessors() - 1).takeIf { it > 0 } ?: 1
|
maxParallelForks = (Runtime.getRuntime().availableProcessors() - 1).takeIf { it > 0 } ?: 1
|
||||||
|
|
||||||
reports.html.required.set(false)
|
reports.html.required.set(false)
|
||||||
reports.junitXml.required.set(false)
|
reports.junitXml.required.set(false)
|
||||||
}
|
}
|
||||||
@ -39,7 +43,7 @@ afterEvaluate {
|
|||||||
*/
|
*/
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
class Version(val major: String, val minor: String, val revision: String, val preRelease: Boolean = false) {
|
class Version(val major: String, val minor: String, val revision: String, val preRelease: Boolean = false) {
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return if (!preRelease)
|
return if (!preRelease)
|
||||||
"$major.$minor.$revision"
|
"$major.$minor.$revision"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.dfsek.terra
|
package com.dfsek.terra
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.util.function.Predicate
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import java.io.File
|
|
||||||
import java.util.function.Predicate
|
|
||||||
import kotlin.streams.asStream
|
import kotlin.streams.asStream
|
||||||
|
|
||||||
|
|
||||||
@ -22,13 +22,13 @@ fun Project.addonDir(dir: File, task: Task) {
|
|||||||
}
|
}
|
||||||
project(":common:addons").subprojects.forEach { addonProject ->
|
project(":common:addons").subprojects.forEach { addonProject ->
|
||||||
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
||||||
|
|
||||||
val target = File(dir, jar.archiveFileName.get())
|
val target = File(dir, jar.archiveFileName.get())
|
||||||
|
|
||||||
val base = "${jar.archiveBaseName.get()}-${project.version}"
|
val base = "${jar.archiveBaseName.get()}-${project.version}"
|
||||||
|
|
||||||
println("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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.dfsek.terra
|
package com.dfsek.terra
|
||||||
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
import org.gradle.api.Project
|
||||||
|
|
||||||
fun Project.getGitHash(): String {
|
fun Project.getGitHash(): String {
|
||||||
val stdout = ByteArrayOutputStream()
|
val stdout = ByteArrayOutputStream()
|
||||||
|
@ -6,7 +6,12 @@ import org.gradle.api.plugins.JavaPluginExtension
|
|||||||
import org.gradle.api.tasks.bundling.Jar
|
import org.gradle.api.tasks.bundling.Jar
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
import org.gradle.api.tasks.javadoc.Javadoc
|
import org.gradle.api.tasks.javadoc.Javadoc
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.apply
|
||||||
|
import org.gradle.kotlin.dsl.configure
|
||||||
|
import org.gradle.kotlin.dsl.filter
|
||||||
|
import org.gradle.kotlin.dsl.getByName
|
||||||
|
import org.gradle.kotlin.dsl.register
|
||||||
|
import org.gradle.kotlin.dsl.withType
|
||||||
import org.gradle.language.jvm.tasks.ProcessResources
|
import org.gradle.language.jvm.tasks.ProcessResources
|
||||||
|
|
||||||
fun Project.configureCompilation() {
|
fun Project.configureCompilation() {
|
||||||
@ -14,46 +19,46 @@ fun Project.configureCompilation() {
|
|||||||
apply(plugin = "java")
|
apply(plugin = "java")
|
||||||
apply(plugin = "java-library")
|
apply(plugin = "java-library")
|
||||||
apply(plugin = "idea")
|
apply(plugin = "idea")
|
||||||
|
|
||||||
configure<JavaPluginExtension> {
|
configure<JavaPluginExtension> {
|
||||||
sourceCompatibility = JavaVersion.VERSION_16
|
sourceCompatibility = JavaVersion.VERSION_16
|
||||||
targetCompatibility = JavaVersion.VERSION_16
|
targetCompatibility = JavaVersion.VERSION_16
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<JavaCompile> {
|
tasks.withType<JavaCompile> {
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
doFirst {
|
doFirst {
|
||||||
options.compilerArgs.add("-Xlint:all")
|
options.compilerArgs.add("-Xlint:all")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<ProcessResources> {
|
tasks.withType<ProcessResources> {
|
||||||
include("**/*.*")
|
include("**/*.*")
|
||||||
filter<org.apache.tools.ant.filters.ReplaceTokens>(
|
filter<org.apache.tools.ant.filters.ReplaceTokens>(
|
||||||
"tokens" to mapOf(
|
"tokens" to mapOf(
|
||||||
"VERSION" to project.version.toString(),
|
"VERSION" to project.version.toString(),
|
||||||
"DESCRIPTION" to project.properties["terra.description"],
|
"DESCRIPTION" to project.properties["terra.description"],
|
||||||
"WIKI" to project.properties["terra.wiki"],
|
"WIKI" to project.properties["terra.wiki"],
|
||||||
"SOURCE" to project.properties["terra.source"],
|
"SOURCE" to project.properties["terra.source"],
|
||||||
"ISSUES" to project.properties["terra.issues"],
|
"ISSUES" to project.properties["terra.issues"],
|
||||||
"LICENSE" to project.properties["terra.license"]
|
"LICENSE" to project.properties["terra.license"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Javadoc> {
|
tasks.withType<Javadoc> {
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Jar> {
|
tasks.withType<Jar> {
|
||||||
archiveBaseName.set("Terra-${archiveBaseName.get()}")
|
archiveBaseName.set("Terra-${archiveBaseName.get()}")
|
||||||
from("../LICENSE", "../../LICENSE")
|
from("../LICENSE", "../../LICENSE")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<Jar>("sourcesJar") {
|
tasks.register<Jar>("sourcesJar") {
|
||||||
archiveClassifier.set("sources")
|
archiveClassifier.set("sources")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<Jar>("javadocJar") {
|
tasks.register<Jar>("javadocJar") {
|
||||||
dependsOn("javadoc")
|
dependsOn("javadoc")
|
||||||
archiveClassifier.set("javadoc")
|
archiveClassifier.set("javadoc")
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package com.dfsek.terra
|
package com.dfsek.terra
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.apply
|
||||||
|
import org.gradle.kotlin.dsl.dependencies
|
||||||
|
import org.gradle.kotlin.dsl.invoke
|
||||||
|
import org.gradle.kotlin.dsl.project
|
||||||
|
import org.gradle.kotlin.dsl.repositories
|
||||||
|
|
||||||
fun Project.configureDependencies() {
|
fun Project.configureDependencies() {
|
||||||
apply(plugin = "java")
|
apply(plugin = "java")
|
||||||
apply(plugin = "java-library")
|
apply(plugin = "java-library")
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
val shaded = create("shaded")
|
val shaded = create("shaded")
|
||||||
val shadedApi = create("shadedApi")
|
val shadedApi = create("shadedApi")
|
||||||
@ -16,7 +20,7 @@ fun Project.configureDependencies() {
|
|||||||
shaded.extendsFrom(shadedImplementation)
|
shaded.extendsFrom(shadedImplementation)
|
||||||
getByName("implementation").extendsFrom(shadedImplementation)
|
getByName("implementation").extendsFrom(shadedImplementation)
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url = uri("https://maven.enginehub.org/repo/") }
|
maven { url = uri("https://maven.enginehub.org/repo/") }
|
||||||
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
|
||||||
@ -25,16 +29,16 @@ fun Project.configureDependencies() {
|
|||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||||
"testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
"testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||||
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
||||||
|
|
||||||
"compileOnly"("com.google.guava:guava:30.0-jre")
|
"compileOnly"("com.google.guava:guava:30.0-jre")
|
||||||
"testImplementation"("com.google.guava:guava:30.0-jre")
|
"testImplementation"("com.google.guava:guava:30.0-jre")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (project(":common:addons").subprojects.contains(this)) { // If this is an addon project, depend on the API.
|
if (project(":common:addons").subprojects.contains(this)) { // If this is an addon project, depend on the API.
|
||||||
dependencies {
|
dependencies {
|
||||||
"compileOnly"(project(":common:api"))
|
"compileOnly"(project(":common:api"))
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
package com.dfsek.terra
|
package com.dfsek.terra
|
||||||
|
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.FileWriter
|
||||||
|
import java.net.URL
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipOutputStream
|
||||||
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
|
||||||
@ -11,29 +18,22 @@ 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 java.io.File
|
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.FileWriter
|
|
||||||
import java.net.URL
|
|
||||||
import java.util.zip.ZipEntry
|
|
||||||
import java.util.zip.ZipOutputStream
|
|
||||||
|
|
||||||
fun Project.configureDistribution() {
|
fun Project.configureDistribution() {
|
||||||
apply(plugin = "com.github.johnrengelman.shadow")
|
apply(plugin = "com.github.johnrengelman.shadow")
|
||||||
|
|
||||||
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
|
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
|
||||||
group = "terra"
|
group = "terra"
|
||||||
doFirst {
|
doFirst {
|
||||||
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
||||||
|
|
||||||
val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/default.zip")
|
val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/default.zip")
|
||||||
downloadPack(defaultPackUrl, project)
|
downloadPack(defaultPackUrl, project)
|
||||||
val netherPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/nether.zip")
|
val netherPackUrl = URL("https://github.com/PolyhedralDev/TerraDefaultConfig/releases/download/latest/nether.zip")
|
||||||
downloadPack(netherPackUrl, project)
|
downloadPack(netherPackUrl, project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val installAddons = tasks.create("installAddons") {
|
val installAddons = tasks.create("installAddons") {
|
||||||
group = "terra"
|
group = "terra"
|
||||||
project(":common:addons").subprojects.forEach {
|
project(":common:addons").subprojects.forEach {
|
||||||
@ -41,7 +41,7 @@ fun Project.configureDistribution() {
|
|||||||
dependsOn(it.tasks.getByName("build")) // Depend on addon JARs
|
dependsOn(it.tasks.getByName("build")) // Depend on addon JARs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
// The addons are copied into a JAR because of a ShadowJar bug
|
// The addons are copied into a JAR because of a ShadowJar bug
|
||||||
// which expands *all* JARs, even resource ones, into the fat JAR.
|
// which expands *all* JARs, even resource ones, into the fat JAR.
|
||||||
@ -52,13 +52,13 @@ fun Project.configureDistribution() {
|
|||||||
// https://github.com/johnrengelman/shadow/issues/111
|
// https://github.com/johnrengelman/shadow/issues/111
|
||||||
val dest = File(buildDir, "/resources/main/addons.jar")
|
val dest = File(buildDir, "/resources/main/addons.jar")
|
||||||
dest.parentFile.mkdirs()
|
dest.parentFile.mkdirs()
|
||||||
|
|
||||||
val zip = ZipOutputStream(FileOutputStream(dest))
|
val zip = ZipOutputStream(FileOutputStream(dest))
|
||||||
|
|
||||||
project(":common:addons").subprojects.forEach { addonProject ->
|
project(":common:addons").subprojects.forEach { addonProject ->
|
||||||
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
val jar = (addonProject.tasks.named("jar").get() as Jar)
|
||||||
println("Packaging addon ${jar.archiveFileName.get()} to ${dest.absolutePath}.")
|
println("Packaging addon ${jar.archiveFileName.get()} to ${dest.absolutePath}.")
|
||||||
|
|
||||||
val entry = ZipEntry("addons/${jar.archiveFileName.get()}")
|
val entry = ZipEntry("addons/${jar.archiveFileName.get()}")
|
||||||
zip.putNextEntry(entry)
|
zip.putNextEntry(entry)
|
||||||
FileInputStream(jar.archiveFile.get().asFile).copyTo(zip)
|
FileInputStream(jar.archiveFile.get().asFile).copyTo(zip)
|
||||||
@ -67,7 +67,7 @@ fun Project.configureDistribution() {
|
|||||||
zip.close()
|
zip.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val generateResourceManifest = tasks.create("generateResourceManifest") {
|
val generateResourceManifest = tasks.create("generateResourceManifest") {
|
||||||
group = "terra"
|
group = "terra"
|
||||||
dependsOn(downloadDefaultPacks)
|
dependsOn(downloadDefaultPacks)
|
||||||
@ -75,24 +75,24 @@ fun Project.configureDistribution() {
|
|||||||
doFirst {
|
doFirst {
|
||||||
val resources = HashMap<String, MutableList<String>>()
|
val resources = HashMap<String, MutableList<String>>()
|
||||||
val packsDir = File("${project.buildDir}/resources/main/packs/")
|
val packsDir = File("${project.buildDir}/resources/main/packs/")
|
||||||
|
|
||||||
packsDir.walkTopDown().forEach {
|
packsDir.walkTopDown().forEach {
|
||||||
if (it.isDirectory || !it.name.endsWith(".zip")) return@forEach
|
if (it.isDirectory || !it.name.endsWith(".zip")) return@forEach
|
||||||
resources.computeIfAbsent("packs") { ArrayList() }.add(it.name)
|
resources.computeIfAbsent("packs") { ArrayList() }.add(it.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
val langDir = File("${project(":common:implementation").buildDir}/resources/main/lang/")
|
val langDir = File("${project(":common:implementation").buildDir}/resources/main/lang/")
|
||||||
|
|
||||||
langDir.walkTopDown().forEach {
|
langDir.walkTopDown().forEach {
|
||||||
if (it.isDirectory || !it.name.endsWith(".yml")) return@forEach
|
if (it.isDirectory || !it.name.endsWith(".yml")) return@forEach
|
||||||
resources.computeIfAbsent("lang") { ArrayList() }.add(it.name)
|
resources.computeIfAbsent("lang") { ArrayList() }.add(it.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
project(":common:addons").subprojects.forEach { addonProject ->
|
project(":common:addons").subprojects.forEach { addonProject ->
|
||||||
val jar = (addonProject.tasks.named("jar").get() as Jar).archiveFileName.get()
|
val jar = (addonProject.tasks.named("jar").get() as Jar).archiveFileName.get()
|
||||||
resources.computeIfAbsent("addons") { ArrayList() }.add(jar)
|
resources.computeIfAbsent("addons") { ArrayList() }.add(jar)
|
||||||
}
|
}
|
||||||
|
|
||||||
val options = DumperOptions()
|
val options = DumperOptions()
|
||||||
options.indent = 2
|
options.indent = 2
|
||||||
options.indentWithIndicator = true
|
options.indentWithIndicator = true
|
||||||
@ -100,25 +100,25 @@ fun Project.configureDistribution() {
|
|||||||
options.isPrettyFlow = true
|
options.isPrettyFlow = true
|
||||||
options.defaultFlowStyle = DumperOptions.FlowStyle.BLOCK
|
options.defaultFlowStyle = DumperOptions.FlowStyle.BLOCK
|
||||||
options.defaultScalarStyle = DumperOptions.ScalarStyle.DOUBLE_QUOTED
|
options.defaultScalarStyle = DumperOptions.ScalarStyle.DOUBLE_QUOTED
|
||||||
|
|
||||||
val yaml = Yaml(options)
|
val yaml = Yaml(options)
|
||||||
|
|
||||||
val manifest = File("${project.buildDir}/resources/main/resources.yml")
|
val manifest = File("${project.buildDir}/resources/main/resources.yml")
|
||||||
|
|
||||||
if (manifest.exists()) manifest.delete()
|
if (manifest.exists()) manifest.delete()
|
||||||
manifest.createNewFile()
|
manifest.createNewFile()
|
||||||
yaml.dump(resources, FileWriter(manifest))
|
yaml.dump(resources, FileWriter(manifest))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks["processResources"].dependsOn(generateResourceManifest)
|
tasks["processResources"].dependsOn(generateResourceManifest)
|
||||||
|
|
||||||
tasks.named<ShadowJar>("shadowJar") {
|
tasks.named<ShadowJar>("shadowJar") {
|
||||||
// Tell shadow to download the packs
|
// Tell shadow to download the packs
|
||||||
dependsOn(downloadDefaultPacks)
|
dependsOn(downloadDefaultPacks)
|
||||||
|
|
||||||
configurations = listOf(project.configurations["shaded"])
|
configurations = listOf(project.configurations["shaded"])
|
||||||
|
|
||||||
archiveClassifier.set("shaded")
|
archiveClassifier.set("shaded")
|
||||||
setVersion(project.version)
|
setVersion(project.version)
|
||||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||||
@ -126,11 +126,11 @@ fun Project.configureDistribution() {
|
|||||||
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")
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<BasePluginExtension> {
|
configure<BasePluginExtension> {
|
||||||
archivesName.set(project.name)
|
archivesName.set(project.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named<DefaultTask>("build") {
|
tasks.named<DefaultTask>("build") {
|
||||||
dependsOn(tasks["shadowJar"])
|
dependsOn(tasks["shadowJar"])
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,11 @@ package com.dfsek.terra
|
|||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.publish.PublishingExtension
|
import org.gradle.api.publish.PublishingExtension
|
||||||
import org.gradle.api.publish.maven.MavenPublication
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.configure
|
||||||
|
import org.gradle.kotlin.dsl.create
|
||||||
|
import org.gradle.kotlin.dsl.get
|
||||||
|
import org.gradle.kotlin.dsl.maven
|
||||||
|
import org.gradle.kotlin.dsl.provideDelegate
|
||||||
|
|
||||||
fun Project.configurePublishing() {
|
fun Project.configurePublishing() {
|
||||||
configure<PublishingExtension> {
|
configure<PublishingExtension> {
|
||||||
@ -13,11 +17,11 @@ fun Project.configurePublishing() {
|
|||||||
artifact(tasks["jar"])
|
artifact(tasks["jar"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||||
//val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
//val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||||
|
|
||||||
maven(mavenUrl) {
|
maven(mavenUrl) {
|
||||||
val mavenUsername: String? by project
|
val mavenUsername: String? by project
|
||||||
val mavenPassword: String? by project
|
val mavenPassword: String? by project
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
# Core Addons
|
# Core Addons
|
||||||
|
|
||||||
This directory contains the modularized "core addons" that implement Terra's default behavior.
|
This directory contains the modularized "core addons" that implement Terra's
|
||||||
|
default behavior.
|
@ -1,8 +1,10 @@
|
|||||||
# api-features
|
# api-features
|
||||||
|
|
||||||
Contains the API for feature generation.
|
Contains the API for feature generation.
|
||||||
|
|
||||||
This API implemented in:
|
This API implemented in:
|
||||||
* `config-feature`
|
|
||||||
* `generation-stage-feature`
|
* `config-feature`
|
||||||
* `config-locators`
|
* `generation-stage-feature`
|
||||||
* `config-distributors`
|
* `config-locators`
|
||||||
|
* `config-distributors`
|
@ -1,6 +1,6 @@
|
|||||||
# biome-provider-image
|
# biome-provider-image
|
||||||
|
|
||||||
Implements and registers the `IMAGE` biome provider, a biome provider which generates
|
Implements and registers the `IMAGE` biome provider, a biome provider which
|
||||||
biomes from an image, using the `color` attribute of biomes.
|
generates biomes from an image, using the `color` attribute of biomes.
|
||||||
|
|
||||||
This addon registers the provider type, and all associated config options.
|
This addon registers the provider type, and all associated config options.
|
@ -1,57 +1,64 @@
|
|||||||
package com.dfsek.terra.addons.biome.image;
|
package com.dfsek.terra.addons.biome.image;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
public class ImageBiomeProvider implements BiomeProvider {
|
public class ImageBiomeProvider implements BiomeProvider {
|
||||||
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
|
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
|
||||||
private final BufferedImage image;
|
private final BufferedImage image;
|
||||||
private final int resolution;
|
private final int resolution;
|
||||||
private final Align align;
|
private final Align align;
|
||||||
|
|
||||||
public ImageBiomeProvider(Set<TerraBiome> registry, BufferedImage image, int resolution, Align align) {
|
public ImageBiomeProvider(Set<TerraBiome> registry, BufferedImage image, int resolution, Align align) {
|
||||||
this.image = image;
|
this.image = image;
|
||||||
this.resolution = resolution;
|
this.resolution = resolution;
|
||||||
this.align = align;
|
this.align = align;
|
||||||
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
|
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int distance(Color a, Color b) {
|
private static int distance(Color a, Color b) {
|
||||||
return FastMath.abs(a.getRed() - b.getRed()) + FastMath.abs(a.getGreen() - b.getGreen()) + FastMath.abs(a.getBlue() - b.getBlue());
|
return FastMath.abs(a.getRed() - b.getRed()) + FastMath.abs(a.getGreen() - b.getGreen()) + FastMath.abs(a.getBlue() - b.getBlue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBiome(int x, int z, long seed) {
|
public TerraBiome getBiome(int x, int z, long seed) {
|
||||||
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().stream().reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new), (running, element) -> {
|
return colorBiomeMap.get(colorBiomeMap.keySet()
|
||||||
int d1 = distance(color, running);
|
.stream()
|
||||||
int d2 = distance(color, element);
|
.reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new),
|
||||||
return d1 < d2 ? running : element;
|
(running, element) -> {
|
||||||
}));
|
int d1 = distance(color, running);
|
||||||
|
int d2 = distance(color, element);
|
||||||
|
return d1 < d2 ? running : element;
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Align {
|
public enum Align {
|
||||||
CENTER {
|
CENTER {
|
||||||
@Override
|
@Override
|
||||||
public Color getColor(BufferedImage image, int x, int z) {
|
public Color getColor(BufferedImage image, int x, int z) {
|
||||||
return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()), FastMath.floorMod(z - image.getHeight() / 2, image.getHeight())));
|
return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()),
|
||||||
|
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(FastMath.floorMod(x, image.getWidth()), FastMath.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,6 +1,9 @@
|
|||||||
package com.dfsek.terra.addons.biome.image;
|
package com.dfsek.terra.addons.biome.image;
|
||||||
|
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.addon.TerraAddon;
|
import com.dfsek.terra.api.addon.TerraAddon;
|
||||||
import com.dfsek.terra.api.addon.annotations.Addon;
|
import com.dfsek.terra.api.addon.annotations.Addon;
|
||||||
@ -14,26 +17,27 @@ import com.dfsek.terra.api.util.reflection.TypeKey;
|
|||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Addon("biome-provider-image")
|
@Addon("biome-provider-image")
|
||||||
@Author("Terra")
|
@Author("Terra")
|
||||||
@Version("1.0.0")
|
@Version("1.0.0")
|
||||||
public class ImageBiomeProviderAddon extends TerraAddon {
|
public class ImageBiomeProviderAddon extends TerraAddon {
|
||||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {};
|
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
main.getEventManager()
|
main.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigPackPreLoadEvent.class)
|
.register(this, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(PROVIDER_REGISTRY_KEY);
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||||
providerRegistry.register("IMAGE", () -> new ImageProviderTemplate(event.getPack().getRegistry(TerraBiome.class)));
|
PROVIDER_REGISTRY_KEY);
|
||||||
})
|
providerRegistry.register("IMAGE", () -> new ImageProviderTemplate(event.getPack().getRegistry(TerraBiome.class)));
|
||||||
.failThrough();
|
})
|
||||||
|
.failThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,29 +3,29 @@ package com.dfsek.terra.addons.biome.image;
|
|||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
import com.dfsek.terra.api.registry.Registry;
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||||
private final Registry<TerraBiome> biomes;
|
private final Registry<TerraBiome> biomes;
|
||||||
@Value("image.name")
|
|
||||||
private BufferedImage image;
|
|
||||||
|
|
||||||
@Value("image.align")
|
|
||||||
private ImageBiomeProvider.Align align;
|
|
||||||
|
|
||||||
@Value("resolution")
|
@Value("resolution")
|
||||||
@Default
|
@Default
|
||||||
private int resolution = 1;
|
private final int resolution = 1;
|
||||||
|
@Value("image.name")
|
||||||
|
private BufferedImage image;
|
||||||
|
@Value("image.align")
|
||||||
|
private ImageBiomeProvider.Align align;
|
||||||
|
|
||||||
public ImageProviderTemplate(Registry<TerraBiome> set) {
|
public ImageProviderTemplate(Registry<TerraBiome> 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);
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
Implements the Biome Pipeline, a procedural biome provider that uses a series
|
Implements the Biome Pipeline, a procedural biome provider that uses a series
|
||||||
of "stages" to apply "mutations" to a 2D grid of biomes.
|
of "stages" to apply "mutations" to a 2D grid of biomes.
|
||||||
|
|
||||||
|
This addon registers the `PIPELINE` biome provider type, and all associated
|
||||||
This addon registers the `PIPELINE` biome provider type, and all associated configurations.
|
configurations.
|
@ -3,16 +3,17 @@ package com.dfsek.terra.addons.biome.pipeline;
|
|||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||||
import com.dfsek.terra.api.vector.Vector2;
|
import com.dfsek.terra.api.vector.Vector2;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
|
||||||
|
|
||||||
public class BiomeHolderImpl implements BiomeHolder {
|
public class BiomeHolderImpl implements BiomeHolder {
|
||||||
private final Vector2 origin;
|
private final Vector2 origin;
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int offset;
|
private final int offset;
|
||||||
private TerraBiome[][] biomes;
|
private TerraBiome[][] biomes;
|
||||||
|
|
||||||
public BiomeHolderImpl(int width, Vector2 origin) {
|
public BiomeHolderImpl(int width, Vector2 origin) {
|
||||||
width += 4;
|
width += 4;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
@ -20,35 +21,38 @@ public class BiomeHolderImpl implements BiomeHolder {
|
|||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.offset = 2;
|
this.offset = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BiomeHolderImpl(TerraBiome[][] biomes, Vector2 origin, int width, int offset) {
|
private BiomeHolderImpl(TerraBiome[][] biomes, Vector2 origin, int width, int offset) {
|
||||||
this.biomes = biomes;
|
this.biomes = biomes;
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.offset = 2 * offset;
|
this.offset = 2 * offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeHolder expand(BiomeExpander expander, long seed) {
|
public BiomeHolder expand(BiomeExpander expander, long seed) {
|
||||||
TerraBiome[][] old = biomes;
|
TerraBiome[][] old = biomes;
|
||||||
int newWidth = width * 2 - 1;
|
int newWidth = width * 2 - 1;
|
||||||
|
|
||||||
biomes = new TerraBiome[newWidth][newWidth];
|
biomes = new TerraBiome[newWidth][newWidth];
|
||||||
|
|
||||||
for(int x = 0; x < width; x++) {
|
for(int x = 0; x < width; x++) {
|
||||||
for(int z = 0; z < width; z++) {
|
for(int z = 0; z < width; z++) {
|
||||||
biomes[x * 2][z * 2] = old[x][z];
|
biomes[x * 2][z * 2] = old[x][z];
|
||||||
if(z != width - 1)
|
if(z != width - 1)
|
||||||
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z], old[x][z + 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)
|
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]);
|
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)
|
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]);
|
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);
|
return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mutate(BiomeMutator mutator, long seed) {
|
public void mutate(BiomeMutator mutator, long seed) {
|
||||||
for(int x = 0; x < width; x++) {
|
for(int x = 0; x < width; x++) {
|
||||||
@ -58,7 +62,7 @@ public class BiomeHolderImpl implements BiomeHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fill(BiomeSource source, long seed) {
|
public void fill(BiomeSource source, long seed) {
|
||||||
for(int x = 0; x < width; x++) {
|
for(int x = 0; x < width; x++) {
|
||||||
@ -67,14 +71,14 @@ public class BiomeHolderImpl implements BiomeHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBiome(int x, int z) {
|
public TerraBiome getBiome(int x, int z) {
|
||||||
x += offset;
|
x += offset;
|
||||||
z += offset;
|
z += offset;
|
||||||
return getBiomeRaw(x, z);
|
return getBiomeRaw(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBiomeRaw(int x, int z) {
|
public TerraBiome getBiomeRaw(int x, int z) {
|
||||||
if(x >= width || z >= width || x < 0 || z < 0) return null;
|
if(x >= width || z >= width || x < 0 || z < 0) return null;
|
||||||
|
@ -1,31 +1,33 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
|
||||||
import com.dfsek.terra.api.vector.Vector2;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||||
|
import com.dfsek.terra.api.vector.Vector2;
|
||||||
|
|
||||||
|
|
||||||
public class BiomePipeline {
|
public class BiomePipeline {
|
||||||
private final BiomeSource source;
|
private final BiomeSource source;
|
||||||
private final List<Stage> stages;
|
private final List<Stage> stages;
|
||||||
private final int size;
|
private final int size;
|
||||||
private final int init;
|
private final int init;
|
||||||
|
|
||||||
private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) {
|
private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.stages = stages;
|
this.stages = stages;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.init = init;
|
this.init = init;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get biomes in a chunk
|
* Get biomes in a chunk
|
||||||
*
|
*
|
||||||
* @param x Chunk X coord
|
* @param x Chunk X coord
|
||||||
* @param z Chunk Z coord
|
* @param z Chunk Z coord
|
||||||
|
*
|
||||||
* @return BiomeHolder containing biomes.
|
* @return BiomeHolder containing biomes.
|
||||||
*/
|
*/
|
||||||
public BiomeHolder getBiomes(int x, int z, long seed) {
|
public BiomeHolder getBiomes(int x, int z, long seed) {
|
||||||
@ -34,29 +36,29 @@ public class BiomePipeline {
|
|||||||
for(Stage stage : stages) holder = stage.apply(holder, seed);
|
for(Stage stage : stages) holder = stage.apply(holder, seed);
|
||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class BiomePipelineBuilder {
|
public static final class BiomePipelineBuilder {
|
||||||
private final int init;
|
private final int init;
|
||||||
List<Stage> stages = new ArrayList<>();
|
List<Stage> stages = new ArrayList<>();
|
||||||
private int expand;
|
private int expand;
|
||||||
|
|
||||||
public BiomePipelineBuilder(int init) {
|
public BiomePipelineBuilder(int init) {
|
||||||
this.init = init;
|
this.init = init;
|
||||||
expand = init;
|
expand = init;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BiomePipeline build(BiomeSource source) {
|
public BiomePipeline build(BiomeSource source) {
|
||||||
for(Stage stage : stages) {
|
for(Stage stage : stages) {
|
||||||
if(stage.isExpansion()) expand = expand * 2 - 1;
|
if(stage.isExpansion()) expand = expand * 2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BiomePipeline(source, stages, expand, init);
|
return new BiomePipeline(source, stages, expand, init);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BiomePipelineBuilder addStage(Stage stage) {
|
public BiomePipelineBuilder addStage(Stage stage) {
|
||||||
stages.add(stage);
|
stages.add(stage);
|
||||||
return this;
|
return this;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
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.BiomeProviderLoader;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.NoiseSourceTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.NoiseSourceTemplate;
|
||||||
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.BorderListMutatorTemplate;
|
||||||
@ -11,6 +13,7 @@ import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderMutatorT
|
|||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListMutatorTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListMutatorTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceMutatorTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceMutatorTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothMutatorTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothMutatorTemplate;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.addon.TerraAddon;
|
import com.dfsek.terra.api.addon.TerraAddon;
|
||||||
import com.dfsek.terra.api.addon.annotations.Addon;
|
import com.dfsek.terra.api.addon.annotations.Addon;
|
||||||
@ -22,44 +25,47 @@ import com.dfsek.terra.api.injection.annotations.Inject;
|
|||||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Addon("biome-provider-pipeline")
|
@Addon("biome-provider-pipeline")
|
||||||
@Author("Terra")
|
@Author("Terra")
|
||||||
@Version("1.0.0")
|
@Version("1.0.0")
|
||||||
public class BiomePipelineAddon extends TerraAddon {
|
public class BiomePipelineAddon extends TerraAddon {
|
||||||
|
|
||||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {};
|
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {};
|
|
||||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_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
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
main.getEventManager()
|
main.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigPackPreLoadEvent.class)
|
.register(this, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(PROVIDER_REGISTRY_KEY);
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||||
providerRegistry.register("PIPELINE", () -> new BiomePipelineTemplate(main));
|
PROVIDER_REGISTRY_KEY);
|
||||||
})
|
providerRegistry.register("PIPELINE", () -> new BiomePipelineTemplate(main));
|
||||||
.then(event -> {
|
})
|
||||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry(SOURCE_REGISTRY_KEY);
|
.then(event -> {
|
||||||
sourceRegistry.register("NOISE", NoiseSourceTemplate::new);
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry(
|
||||||
})
|
SOURCE_REGISTRY_KEY);
|
||||||
.then(event -> {
|
sourceRegistry.register("NOISE", NoiseSourceTemplate::new);
|
||||||
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(STAGE_REGISTRY_KEY);
|
})
|
||||||
stageRegistry.register("FRACTAL_EXPAND", ExpanderStageTemplate::new);
|
.then(event -> {
|
||||||
stageRegistry.register("SMOOTH", SmoothMutatorTemplate::new);
|
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(STAGE_REGISTRY_KEY);
|
||||||
stageRegistry.register("REPLACE", ReplaceMutatorTemplate::new);
|
stageRegistry.register("FRACTAL_EXPAND", ExpanderStageTemplate::new);
|
||||||
stageRegistry.register("REPLACE_LIST", ReplaceListMutatorTemplate::new);
|
stageRegistry.register("SMOOTH", SmoothMutatorTemplate::new);
|
||||||
stageRegistry.register("BORDER", BorderMutatorTemplate::new);
|
stageRegistry.register("REPLACE", ReplaceMutatorTemplate::new);
|
||||||
stageRegistry.register("BORDER_LIST", BorderListMutatorTemplate::new);
|
stageRegistry.register("REPLACE_LIST", ReplaceListMutatorTemplate::new);
|
||||||
})
|
stageRegistry.register("BORDER", BorderMutatorTemplate::new);
|
||||||
.failThrough();
|
stageRegistry.register("BORDER_LIST", BorderListMutatorTemplate::new);
|
||||||
|
})
|
||||||
|
.failThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline;
|
package com.dfsek.terra.addons.biome.pipeline;
|
||||||
|
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import net.jafama.FastMath;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class BiomePipelineProvider implements BiomeProvider {
|
public class BiomePipelineProvider implements BiomeProvider {
|
||||||
private final LoadingCache<SeededVector, BiomeHolder> holderCache;
|
private final LoadingCache<SeededVector, BiomeHolder> holderCache;
|
||||||
@ -17,50 +19,51 @@ public class BiomePipelineProvider implements BiomeProvider {
|
|||||||
private final int resolution;
|
private final int resolution;
|
||||||
private final NoiseSampler mutator;
|
private final NoiseSampler mutator;
|
||||||
private final double noiseAmp;
|
private final double noiseAmp;
|
||||||
|
|
||||||
public BiomePipelineProvider(BiomePipeline pipeline, TerraPlugin main, int resolution, NoiseSampler mutator, double noiseAmp) {
|
public BiomePipelineProvider(BiomePipeline pipeline, TerraPlugin main, int resolution, NoiseSampler mutator, double noiseAmp) {
|
||||||
this.resolution = resolution;
|
this.resolution = resolution;
|
||||||
this.mutator = mutator;
|
this.mutator = mutator;
|
||||||
this.noiseAmp = noiseAmp;
|
this.noiseAmp = noiseAmp;
|
||||||
holderCache = CacheBuilder.newBuilder()
|
holderCache = CacheBuilder.newBuilder()
|
||||||
.maximumSize(main == null ? 32 : main.getTerraConfig().getProviderCache())
|
.maximumSize(main == null ? 32 : main.getTerraConfig().getProviderCache())
|
||||||
.build(
|
.build(
|
||||||
new CacheLoader<SeededVector, BiomeHolder>() {
|
new CacheLoader<SeededVector, BiomeHolder>() {
|
||||||
@Override
|
@Override
|
||||||
public BiomeHolder load(@NotNull SeededVector key) {
|
public BiomeHolder load(@NotNull SeededVector key) {
|
||||||
return pipeline.getBiomes(key.x, key.z, key.seed);
|
return pipeline.getBiomes(key.x, key.z, key.seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.pipeline = pipeline;
|
this.pipeline = pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBiome(int x, int z, long seed) {
|
public TerraBiome getBiome(int x, int z, long seed) {
|
||||||
x += mutator.getNoiseSeeded(seed + 1, x, z) * noiseAmp;
|
x += mutator.getNoiseSeeded(seed + 1, x, z) * noiseAmp;
|
||||||
z += mutator.getNoiseSeeded(seed + 2, x, z) * noiseAmp;
|
z += mutator.getNoiseSeeded(seed + 2, x, z) * noiseAmp;
|
||||||
|
|
||||||
|
|
||||||
x = FastMath.floorToInt(FastMath.floorDiv(x, resolution));
|
x = FastMath.floorToInt(FastMath.floorDiv(x, resolution));
|
||||||
|
|
||||||
z = FastMath.floorToInt(FastMath.floorDiv(z, resolution));
|
z = FastMath.floorToInt(FastMath.floorDiv(z, resolution));
|
||||||
|
|
||||||
int fdX = FastMath.floorDiv(x, pipeline.getSize());
|
int fdX = FastMath.floorDiv(x, pipeline.getSize());
|
||||||
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
|
||||||
return holderCache.getUnchecked(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
|
return holderCache.getUnchecked(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(),
|
||||||
|
z - fdZ * pipeline.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SeededVector {
|
private static final class SeededVector {
|
||||||
private final int x;
|
private final int x;
|
||||||
private final int z;
|
private final int z;
|
||||||
private final long seed;
|
private final long seed;
|
||||||
|
|
||||||
private SeededVector(int x, int z, long seed) {
|
private SeededVector(int x, int z, long seed) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -69,12 +72,12 @@ public class BiomePipelineProvider implements BiomeProvider {
|
|||||||
result = 31 * result + z;
|
result = 31 * result + z;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if(!(obj instanceof SeededVector)) return false;
|
if(!(obj instanceof SeededVector)) return false;
|
||||||
SeededVector that = (SeededVector) obj;
|
SeededVector that = (SeededVector) obj;
|
||||||
|
|
||||||
return this.seed == that.seed && this.x == that.x && this.z == that.z;
|
return this.seed == that.seed && this.x == that.x && this.z == that.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.dfsek.terra.addons.biome.pipeline.api;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public interface BiomeExpander {
|
public interface BiomeExpander {
|
||||||
TerraBiome getBetween(double x, double z, long seed, TerraBiome... others);
|
TerraBiome getBetween(double x, double z, long seed, TerraBiome... others);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.api;
|
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||||
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public interface BiomeHolder {
|
public interface BiomeHolder {
|
||||||
BiomeHolder expand(BiomeExpander expander, long seed);
|
BiomeHolder expand(BiomeExpander expander, long seed);
|
||||||
|
|
||||||
void mutate(BiomeMutator mutator, long seed);
|
void mutate(BiomeMutator mutator, long seed);
|
||||||
|
|
||||||
void fill(BiomeSource source, long seed);
|
void fill(BiomeSource source, long seed);
|
||||||
|
|
||||||
TerraBiome getBiome(int x, int z);
|
TerraBiome getBiome(int x, int z);
|
||||||
|
|
||||||
TerraBiome getBiomeRaw(int x, int z);
|
TerraBiome getBiomeRaw(int x, int z);
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,22 @@ package com.dfsek.terra.addons.biome.pipeline.api;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public interface BiomeMutator {
|
public interface BiomeMutator {
|
||||||
TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed);
|
TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed);
|
||||||
|
|
||||||
class ViewPoint {
|
class ViewPoint {
|
||||||
private final BiomeHolder biomes;
|
private final BiomeHolder biomes;
|
||||||
private final int offX;
|
private final int offX;
|
||||||
private final int offZ;
|
private final int offZ;
|
||||||
|
|
||||||
public ViewPoint(BiomeHolder biomes, int offX, int offZ) {
|
public ViewPoint(BiomeHolder biomes, int offX, int offZ) {
|
||||||
this.biomes = biomes;
|
this.biomes = biomes;
|
||||||
this.offX = offX;
|
this.offX = offX;
|
||||||
this.offZ = offZ;
|
this.offZ = offZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public TerraBiome getBiome(int x, int z) {
|
public TerraBiome getBiome(int x, int z) {
|
||||||
return biomes.getBiomeRaw(x + offX, z + offZ);
|
return biomes.getBiomeRaw(x + offX, z + offZ);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.api;
|
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||||
|
|
||||||
public interface Stage {
|
public interface Stage {
|
||||||
boolean isExpansion();
|
|
||||||
|
|
||||||
BiomeHolder apply(BiomeHolder in, long seed);
|
BiomeHolder apply(BiomeHolder in, long seed);
|
||||||
|
|
||||||
|
boolean isExpansion();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,33 +2,35 @@ package com.dfsek.terra.addons.biome.pipeline.config;
|
|||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.BiomePipeline;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
import com.dfsek.terra.addons.biome.pipeline.BiomePipeline;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
|
||||||
public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
@Value("pipeline.initial-size")
|
@Value("pipeline.initial-size")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int initialSize = 2;
|
private @Meta int initialSize = 2;
|
||||||
|
|
||||||
@Value("pipeline.stages")
|
@Value("pipeline.stages")
|
||||||
private @Meta List<@Meta Stage> stages;
|
private @Meta List<@Meta Stage> stages;
|
||||||
|
|
||||||
@Value("pipeline.source")
|
@Value("pipeline.source")
|
||||||
private @Meta BiomeSource source;
|
private @Meta BiomeSource source;
|
||||||
|
|
||||||
public BiomePipelineTemplate(TerraPlugin main) {
|
public BiomePipelineTemplate(TerraPlugin main) {
|
||||||
this.main = main;
|
this.main = main;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeProvider get() {
|
public BiomeProvider get() {
|
||||||
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize);
|
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize);
|
||||||
|
@ -3,10 +3,12 @@ package com.dfsek.terra.addons.biome.pipeline.config;
|
|||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
|
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
import java.lang.reflect.AnnotatedType;
|
|
||||||
|
|
||||||
public class BiomeProviderLoader implements TypeLoader<BiomeProvider> {
|
public class BiomeProviderLoader implements TypeLoader<BiomeProvider> {
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,10 +3,12 @@ package com.dfsek.terra.addons.biome.pipeline.config;
|
|||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||||
@Value("resolution")
|
@Value("resolution")
|
||||||
@Default
|
@Default
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.config;
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.NoiseSource;
|
import com.dfsek.terra.addons.biome.pipeline.source.NoiseSource;
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
|
||||||
|
|
||||||
public class NoiseSourceTemplate extends SourceTemplate {
|
public class NoiseSourceTemplate extends SourceTemplate {
|
||||||
@Value("noise")
|
@Value("noise")
|
||||||
private @Meta NoiseSampler noise;
|
private @Meta NoiseSampler noise;
|
||||||
|
|
||||||
@Value("biomes")
|
@Value("biomes")
|
||||||
private @Meta ProbabilityCollection<@Meta TerraBiome> biomes;
|
private @Meta ProbabilityCollection<@Meta TerraBiome> biomes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeSource get() {
|
public BiomeSource get() {
|
||||||
return new NoiseSource(biomes, noise);
|
return new NoiseSource(biomes, noise);
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.config;
|
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||||
|
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||||
|
|
||||||
public abstract class SourceTemplate implements ObjectTemplate<BiomeSource>{
|
|
||||||
|
public abstract class SourceTemplate implements ObjectTemplate<BiomeSource> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ package com.dfsek.terra.addons.biome.pipeline.config.stage;
|
|||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
public abstract class StageTemplate implements ObjectTemplate<Stage> {
|
public abstract class StageTemplate implements ObjectTemplate<Stage> {
|
||||||
@Value("noise")
|
@Value("noise")
|
||||||
protected @Meta NoiseSampler noise;
|
protected @Meta NoiseSampler noise;
|
||||||
|
@ -5,6 +5,7 @@ import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
|||||||
import com.dfsek.terra.addons.biome.pipeline.expand.FractalExpander;
|
import com.dfsek.terra.addons.biome.pipeline.expand.FractalExpander;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.stages.ExpanderStage;
|
import com.dfsek.terra.addons.biome.pipeline.stages.ExpanderStage;
|
||||||
|
|
||||||
|
|
||||||
public class ExpanderStageTemplate extends StageTemplate {
|
public class ExpanderStageTemplate extends StageTemplate {
|
||||||
@Override
|
@Override
|
||||||
public Stage get() {
|
public Stage get() {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderListMutator;
|
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderListMutator;
|
||||||
@ -9,23 +12,22 @@ import com.dfsek.terra.api.config.meta.Meta;
|
|||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class BorderListMutatorTemplate extends StageTemplate {
|
public class BorderListMutatorTemplate extends StageTemplate {
|
||||||
@Value("from")
|
@Value("from")
|
||||||
private @Meta String from;
|
private @Meta String from;
|
||||||
|
|
||||||
@Value("default-replace")
|
@Value("default-replace")
|
||||||
private @Meta String defaultReplace;
|
private @Meta String defaultReplace;
|
||||||
|
|
||||||
@Value("default-to")
|
@Value("default-to")
|
||||||
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
|
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
|
||||||
|
|
||||||
@Value("replace")
|
@Value("replace")
|
||||||
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
|
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stage get() {
|
public Stage get() {
|
||||||
return new MutatorStage(new BorderListMutator(replace, from, defaultReplace, noise, defaultTo));
|
return new MutatorStage(new BorderListMutator(replace, from, defaultReplace, noise, defaultTo));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderMutator;
|
import com.dfsek.terra.addons.biome.pipeline.mutator.BorderMutator;
|
||||||
@ -10,17 +10,18 @@ import com.dfsek.terra.api.config.meta.Meta;
|
|||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class BorderMutatorTemplate extends StageTemplate {
|
public class BorderMutatorTemplate extends StageTemplate {
|
||||||
@Value("from")
|
@Value("from")
|
||||||
private @Meta String from;
|
private @Meta String from;
|
||||||
|
|
||||||
@Value("replace")
|
@Value("replace")
|
||||||
private @Meta String replace;
|
private @Meta String replace;
|
||||||
|
|
||||||
@Value("to")
|
@Value("to")
|
||||||
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
|
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stage get() {
|
public Stage get() {
|
||||||
return new MutatorStage(new BorderMutator(from, replace, noise, to));
|
return new MutatorStage(new BorderMutator(from, replace, noise, to));
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceListMutator;
|
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceListMutator;
|
||||||
@ -10,19 +12,18 @@ import com.dfsek.terra.api.config.meta.Meta;
|
|||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ReplaceListMutatorTemplate extends StageTemplate {
|
public class ReplaceListMutatorTemplate extends StageTemplate {
|
||||||
@Value("default-from")
|
@Value("default-from")
|
||||||
private @Meta String defaultFrom;
|
private @Meta String defaultFrom;
|
||||||
|
|
||||||
@Value("default-to")
|
@Value("default-to")
|
||||||
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
|
private @Meta ProbabilityCollection<@Meta TerraBiome> defaultTo;
|
||||||
|
|
||||||
@Value("to")
|
@Value("to")
|
||||||
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
|
private @Meta Map<@Meta TerraBiome, @Meta ProbabilityCollection<@Meta TerraBiome>> replace;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stage get() {
|
public Stage get() {
|
||||||
return new MutatorStage(new ReplaceListMutator(replace, defaultFrom, defaultTo, noise));
|
return new MutatorStage(new ReplaceListMutator(replace, defaultFrom, defaultTo, noise));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceMutator;
|
import com.dfsek.terra.addons.biome.pipeline.mutator.ReplaceMutator;
|
||||||
@ -10,14 +10,15 @@ import com.dfsek.terra.api.config.meta.Meta;
|
|||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ReplaceMutatorTemplate extends StageTemplate {
|
public class ReplaceMutatorTemplate extends StageTemplate {
|
||||||
@Value("from")
|
@Value("from")
|
||||||
private @Meta String from;
|
private @Meta String from;
|
||||||
|
|
||||||
@Value("to")
|
@Value("to")
|
||||||
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
|
private @Meta ProbabilityCollection<@Meta TerraBiome> to;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stage get() {
|
public Stage get() {
|
||||||
return new MutatorStage(new ReplaceMutator(from, to, noise));
|
return new MutatorStage(new ReplaceMutator(from, to, noise));
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.config.stage.mutator;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.mutator.SmoothMutator;
|
import com.dfsek.terra.addons.biome.pipeline.mutator.SmoothMutator;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
|
import com.dfsek.terra.addons.biome.pipeline.stages.MutatorStage;
|
||||||
|
|
||||||
|
|
||||||
public class SmoothMutatorTemplate extends StageTemplate {
|
public class SmoothMutatorTemplate extends StageTemplate {
|
||||||
@Override
|
@Override
|
||||||
public Stage get() {
|
public Stage get() {
|
||||||
|
@ -5,13 +5,14 @@ import com.dfsek.terra.api.noise.NoiseSampler;
|
|||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public class FractalExpander implements BiomeExpander {
|
public class FractalExpander implements BiomeExpander {
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
public FractalExpander(NoiseSampler sampler) {
|
public FractalExpander(NoiseSampler sampler) {
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBetween(double x, double z, long seed, TerraBiome... others) {
|
public TerraBiome getBetween(double x, double z, long seed, TerraBiome... others) {
|
||||||
return others[MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), others.length)];
|
return others[MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), others.length)];
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class BorderListMutator implements BiomeMutator {
|
public class BorderListMutator implements BiomeMutator {
|
||||||
private final String border;
|
private final String border;
|
||||||
@ -13,15 +14,16 @@ public class BorderListMutator implements BiomeMutator {
|
|||||||
private final ProbabilityCollection<TerraBiome> replaceDefault;
|
private final ProbabilityCollection<TerraBiome> replaceDefault;
|
||||||
private final String defaultReplace;
|
private final String defaultReplace;
|
||||||
private final Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
|
private final Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
|
||||||
|
|
||||||
public BorderListMutator(Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace, String border, String defaultReplace, NoiseSampler noiseSampler, ProbabilityCollection<TerraBiome> replaceDefault) {
|
public BorderListMutator(Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace, String border, String defaultReplace,
|
||||||
|
NoiseSampler noiseSampler, ProbabilityCollection<TerraBiome> replaceDefault) {
|
||||||
this.border = border;
|
this.border = border;
|
||||||
this.noiseSampler = noiseSampler;
|
this.noiseSampler = noiseSampler;
|
||||||
this.replaceDefault = replaceDefault;
|
this.replaceDefault = replaceDefault;
|
||||||
this.defaultReplace = defaultReplace;
|
this.defaultReplace = defaultReplace;
|
||||||
this.replace = replace;
|
this.replace = replace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
||||||
TerraBiome origin = viewPoint.getBiome(0, 0);
|
TerraBiome origin = viewPoint.getBiome(0, 0);
|
||||||
|
@ -5,19 +5,20 @@ import com.dfsek.terra.api.noise.NoiseSampler;
|
|||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public class BorderMutator implements BiomeMutator {
|
public class BorderMutator implements BiomeMutator {
|
||||||
private final String border;
|
private final String border;
|
||||||
private final NoiseSampler noiseSampler;
|
private final NoiseSampler noiseSampler;
|
||||||
private final ProbabilityCollection<TerraBiome> replace;
|
private final ProbabilityCollection<TerraBiome> replace;
|
||||||
private final String replaceTag;
|
private final String replaceTag;
|
||||||
|
|
||||||
public BorderMutator(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<TerraBiome> replace) {
|
public BorderMutator(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<TerraBiome> replace) {
|
||||||
this.border = border;
|
this.border = border;
|
||||||
this.noiseSampler = noiseSampler;
|
this.noiseSampler = noiseSampler;
|
||||||
this.replace = replace;
|
this.replace = replace;
|
||||||
this.replaceTag = replaceTag;
|
this.replaceTag = replaceTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
||||||
TerraBiome origin = viewPoint.getBiome(0, 0);
|
TerraBiome origin = viewPoint.getBiome(0, 0);
|
||||||
|
@ -1,25 +1,27 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ReplaceListMutator implements BiomeMutator {
|
public class ReplaceListMutator implements BiomeMutator {
|
||||||
private final Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
|
private final Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace;
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
private final ProbabilityCollection<TerraBiome> replaceDefault;
|
private final ProbabilityCollection<TerraBiome> replaceDefault;
|
||||||
private final String defaultTag;
|
private final String defaultTag;
|
||||||
|
|
||||||
public ReplaceListMutator(Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace, String defaultTag, ProbabilityCollection<TerraBiome> replaceDefault, NoiseSampler sampler) {
|
public ReplaceListMutator(Map<TerraBiome, ProbabilityCollection<TerraBiome>> replace, String defaultTag,
|
||||||
|
ProbabilityCollection<TerraBiome> replaceDefault, NoiseSampler sampler) {
|
||||||
this.replace = replace;
|
this.replace = replace;
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
this.defaultTag = defaultTag;
|
this.defaultTag = defaultTag;
|
||||||
this.replaceDefault = replaceDefault;
|
this.replaceDefault = replaceDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
||||||
TerraBiome center = viewPoint.getBiome(0, 0);
|
TerraBiome center = viewPoint.getBiome(0, 0);
|
||||||
|
@ -5,17 +5,18 @@ import com.dfsek.terra.api.noise.NoiseSampler;
|
|||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public class ReplaceMutator implements BiomeMutator {
|
public class ReplaceMutator implements BiomeMutator {
|
||||||
private final String replaceableTag;
|
private final String replaceableTag;
|
||||||
private final ProbabilityCollection<TerraBiome> replace;
|
private final ProbabilityCollection<TerraBiome> replace;
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
public ReplaceMutator(String replaceable, ProbabilityCollection<TerraBiome> replace, NoiseSampler sampler) {
|
public ReplaceMutator(String replaceable, ProbabilityCollection<TerraBiome> replace, NoiseSampler sampler) {
|
||||||
this.replaceableTag = replaceable;
|
this.replaceableTag = replaceable;
|
||||||
this.replace = replace;
|
this.replace = replace;
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
||||||
if(viewPoint.getBiome(0, 0).getTags().contains(replaceableTag)) {
|
if(viewPoint.getBiome(0, 0).getTags().contains(replaceableTag)) {
|
||||||
|
@ -1,38 +1,39 @@
|
|||||||
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
package com.dfsek.terra.addons.biome.pipeline.mutator;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class SmoothMutator implements BiomeMutator {
|
public class SmoothMutator implements BiomeMutator {
|
||||||
|
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
public SmoothMutator(NoiseSampler sampler) {
|
public SmoothMutator(NoiseSampler sampler) {
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
|
||||||
TerraBiome top = viewPoint.getBiome(1, 0);
|
TerraBiome top = viewPoint.getBiome(1, 0);
|
||||||
TerraBiome bottom = viewPoint.getBiome(-1, 0);
|
TerraBiome bottom = viewPoint.getBiome(-1, 0);
|
||||||
TerraBiome left = viewPoint.getBiome(0, 1);
|
TerraBiome left = viewPoint.getBiome(0, 1);
|
||||||
TerraBiome right = viewPoint.getBiome(0, -1);
|
TerraBiome right = viewPoint.getBiome(0, -1);
|
||||||
|
|
||||||
|
|
||||||
boolean vert = Objects.equals(top, bottom) && top != null;
|
boolean vert = Objects.equals(top, bottom) && top != null;
|
||||||
boolean horiz = Objects.equals(left, right) && left != null;
|
boolean horiz = Objects.equals(left, right) && left != null;
|
||||||
|
|
||||||
if(vert && horiz) {
|
if(vert && horiz) {
|
||||||
return MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), 2) == 0 ? left : top;
|
return MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), 2) == 0 ? left : top;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vert) return top;
|
if(vert) return top;
|
||||||
if(horiz) return left;
|
if(horiz) return left;
|
||||||
|
|
||||||
return viewPoint.getBiome(0, 0);
|
return viewPoint.getBiome(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.dfsek.terra.addons.biome.pipeline.source;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public interface BiomeSource {
|
public interface BiomeSource {
|
||||||
TerraBiome getBiome(double x, double z, long seed);
|
TerraBiome getBiome(double x, double z, long seed);
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,16 @@ import com.dfsek.terra.api.noise.NoiseSampler;
|
|||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public class NoiseSource implements BiomeSource {
|
public class NoiseSource implements BiomeSource {
|
||||||
private final ProbabilityCollection<TerraBiome> biomes;
|
private final ProbabilityCollection<TerraBiome> biomes;
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
public NoiseSource(ProbabilityCollection<TerraBiome> biomes, NoiseSampler sampler) {
|
public NoiseSource(ProbabilityCollection<TerraBiome> biomes, NoiseSampler sampler) {
|
||||||
this.biomes = biomes;
|
this.biomes = biomes;
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBiome(double x, double z, long seed) {
|
public TerraBiome getBiome(double x, double z, long seed) {
|
||||||
return biomes.get(sampler, x, z, seed);
|
return biomes.get(sampler, x, z, seed);
|
||||||
|
@ -4,23 +4,24 @@ import com.dfsek.terra.addons.biome.pipeline.api.BiomeExpander;
|
|||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
|
||||||
|
|
||||||
public class ExpanderStage implements Stage {
|
public class ExpanderStage implements Stage {
|
||||||
private final BiomeExpander expander;
|
private final BiomeExpander expander;
|
||||||
|
|
||||||
public ExpanderStage(BiomeExpander expander) {
|
public ExpanderStage(BiomeExpander expander) {
|
||||||
this.expander = expander;
|
this.expander = expander;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isExpansion() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeHolder apply(BiomeHolder in, long seed) {
|
public BiomeHolder apply(BiomeHolder in, long seed) {
|
||||||
return in.expand(expander, seed);
|
return in.expand(expander, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExpansion() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
FRACTAL
|
FRACTAL
|
||||||
}
|
}
|
||||||
|
@ -4,25 +4,30 @@ import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
|||||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
|
||||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||||
|
|
||||||
|
|
||||||
public class MutatorStage implements Stage {
|
public class MutatorStage implements Stage {
|
||||||
private final BiomeMutator mutator;
|
private final BiomeMutator mutator;
|
||||||
|
|
||||||
public MutatorStage(BiomeMutator mutator) {
|
public MutatorStage(BiomeMutator mutator) {
|
||||||
this.mutator = mutator;
|
this.mutator = mutator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isExpansion() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeHolder apply(BiomeHolder in, long seed) {
|
public BiomeHolder apply(BiomeHolder in, long seed) {
|
||||||
in.mutate(mutator, seed);
|
in.mutate(mutator, seed);
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExpansion() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
REPLACE, REPLACE_LIST, BORDER, BORDER_LIST, SMOOTH
|
REPLACE,
|
||||||
|
REPLACE_LIST,
|
||||||
|
BORDER,
|
||||||
|
BORDER_LIST,
|
||||||
|
SMOOTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,14 @@ package com.dfsek.terra.addons.biome.single;
|
|||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
public class SingleBiomeProvider implements BiomeProvider {
|
public class SingleBiomeProvider implements BiomeProvider {
|
||||||
private final TerraBiome biome;
|
private final TerraBiome biome;
|
||||||
|
|
||||||
public SingleBiomeProvider(TerraBiome biome) {
|
public SingleBiomeProvider(TerraBiome biome) {
|
||||||
this.biome = biome;
|
this.biome = biome;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome getBiome(int x, int z, long seed) {
|
public TerraBiome getBiome(int x, int z, long seed) {
|
||||||
return biome;
|
return biome;
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.dfsek.terra.addons.biome.single;
|
package com.dfsek.terra.addons.biome.single;
|
||||||
|
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.addon.TerraAddon;
|
import com.dfsek.terra.api.addon.TerraAddon;
|
||||||
import com.dfsek.terra.api.addon.annotations.Addon;
|
import com.dfsek.terra.api.addon.annotations.Addon;
|
||||||
@ -13,26 +16,27 @@ import com.dfsek.terra.api.registry.CheckedRegistry;
|
|||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Addon("biome-provider-single")
|
@Addon("biome-provider-single")
|
||||||
@Author("Terra")
|
@Author("Terra")
|
||||||
@Version("1.0.0")
|
@Version("1.0.0")
|
||||||
public class SingleBiomeProviderAddon extends TerraAddon {
|
public class SingleBiomeProviderAddon extends TerraAddon {
|
||||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {};
|
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||||
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
main.getEventManager()
|
main.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigPackPreLoadEvent.class)
|
.register(this, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(PROVIDER_REGISTRY_KEY);
|
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||||
providerRegistry.register("SINGLE", SingleBiomeProviderTemplate::new);
|
PROVIDER_REGISTRY_KEY);
|
||||||
})
|
providerRegistry.register("SINGLE", SingleBiomeProviderTemplate::new);
|
||||||
.failThrough();
|
})
|
||||||
|
.failThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,16 @@ package com.dfsek.terra.addons.biome.single;
|
|||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
public class SingleBiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
public class SingleBiomeProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||||
@Value("biome")
|
@Value("biome")
|
||||||
private @Meta TerraBiome biome;
|
private @Meta TerraBiome biome;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeProvider get() {
|
public BiomeProvider get() {
|
||||||
return new SingleBiomeProvider(biome);
|
return new SingleBiomeProvider(biome);
|
||||||
|
@ -3,26 +3,26 @@ package com.dfsek.terra.addons.chunkgenerator;
|
|||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
public class BiomePaletteTemplate implements ObjectTemplate<PaletteInfo> {
|
|
||||||
@Value("palette")
|
|
||||||
private @Meta PaletteHolder palette;
|
|
||||||
|
|
||||||
|
public class BiomePaletteTemplate implements ObjectTemplate<PaletteInfo> {
|
||||||
@Value("slant")
|
@Value("slant")
|
||||||
@Default
|
@Default
|
||||||
private @Meta SlantHolder slant = null;
|
private final @Meta SlantHolder slant;
|
||||||
|
@Value("palette")
|
||||||
|
private @Meta PaletteHolder palette;
|
||||||
@Value("ocean.level")
|
@Value("ocean.level")
|
||||||
private @Meta int seaLevel;
|
private @Meta int seaLevel;
|
||||||
|
|
||||||
@Value("ocean.palette")
|
@Value("ocean.palette")
|
||||||
private @Meta Palette oceanPalette;
|
private @Meta Palette oceanPalette;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaletteInfo get() {
|
public PaletteInfo get() {
|
||||||
return new PaletteInfo(palette, slant, oceanPalette, seaLevel);
|
return new PaletteInfo(palette, slant, oceanPalette, seaLevel);
|
||||||
|
@ -17,34 +17,36 @@ import com.dfsek.terra.api.injection.annotations.Inject;
|
|||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider;
|
import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider;
|
||||||
|
|
||||||
|
|
||||||
@Addon("chunk-generator-noise-3d")
|
@Addon("chunk-generator-noise-3d")
|
||||||
@Author("Terra")
|
@Author("Terra")
|
||||||
@Version("1.0.0")
|
@Version("1.0.0")
|
||||||
public class NoiseChunkGenerator3DAddon extends TerraAddon {
|
public class NoiseChunkGenerator3DAddon extends TerraAddon {
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
main.getEventManager()
|
main.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigPackPreLoadEvent.class)
|
.register(this, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
event.getPack().getOrCreateRegistry(ChunkGeneratorProvider.class).register("NOISE_3D", pack -> new NoiseChunkGenerator3D(pack, main));
|
event.getPack().getOrCreateRegistry(ChunkGeneratorProvider.class).register("NOISE_3D",
|
||||||
event.getPack()
|
pack -> new NoiseChunkGenerator3D(pack, main));
|
||||||
.applyLoader(SlantHolder.class, new SlantHolderLoader())
|
event.getPack()
|
||||||
.applyLoader(PaletteHolder.class, new PaletteHolderLoader());
|
.applyLoader(SlantHolder.class, new SlantHolderLoader())
|
||||||
})
|
.applyLoader(PaletteHolder.class, new PaletteHolderLoader());
|
||||||
.failThrough();
|
})
|
||||||
|
.failThrough();
|
||||||
|
|
||||||
main.getEventManager()
|
main.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigurationLoadEvent.class)
|
.register(this, ConfigurationLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
if(event.is(TerraBiome.class)) {
|
if(event.is(TerraBiome.class)) {
|
||||||
event.getLoadedObject(TerraBiome.class).getContext().put(event.load(new BiomePaletteTemplate()).get());
|
event.getLoadedObject(TerraBiome.class).getContext().put(event.load(new BiomePaletteTemplate()).get());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.failThrough();
|
.failThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.dfsek.terra.api.world.biome.GenerationSettings;
|
|||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
import com.dfsek.terra.api.world.generator.Sampler;
|
import com.dfsek.terra.api.world.generator.Sampler;
|
||||||
|
|
||||||
|
|
||||||
public final class PaletteUtil {
|
public final class PaletteUtil {
|
||||||
public static Palette getPalette(int x, int y, int z, GenerationSettings c, Sampler sampler, PaletteInfo paletteInfo) {
|
public static Palette getPalette(int x, int y, int z, GenerationSettings c, Sampler sampler, PaletteInfo paletteInfo) {
|
||||||
SlantHolder slant = paletteInfo.getSlantHolder();
|
SlantHolder slant = paletteInfo.getSlantHolder();
|
||||||
@ -16,7 +17,7 @@ public final class PaletteUtil {
|
|||||||
return slant.getPalette(slope).getPalette(y);
|
return slant.getPalette(slope).getPalette(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return paletteInfo.getPaletteHolder().getPalette(y);
|
return paletteInfo.getPaletteHolder().getPalette(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,12 @@
|
|||||||
package com.dfsek.terra.addons.chunkgenerator.generation.generators;
|
package com.dfsek.terra.addons.chunkgenerator.generation.generators;
|
||||||
|
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.PaletteUtil;
|
import com.dfsek.terra.addons.chunkgenerator.PaletteUtil;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
|
||||||
@ -16,32 +23,27 @@ import com.dfsek.terra.api.world.biome.GenerationSettings;
|
|||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generator.ChunkData;
|
import com.dfsek.terra.api.world.generator.ChunkData;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
|
||||||
import com.dfsek.terra.api.world.generator.Sampler;
|
|
||||||
import com.dfsek.terra.api.world.generator.ChunkGenerator;
|
import com.dfsek.terra.api.world.generator.ChunkGenerator;
|
||||||
import com.dfsek.terra.api.world.generator.GenerationStage;
|
import com.dfsek.terra.api.world.generator.GenerationStage;
|
||||||
import net.jafama.FastMath;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import com.dfsek.terra.api.world.generator.Sampler;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class NoiseChunkGenerator3D implements ChunkGenerator {
|
public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||||
private final ConfigPack configPack;
|
private final ConfigPack configPack;
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
private final List<GenerationStage> generationStages = new ArrayList<>();
|
private final List<GenerationStage> generationStages = new ArrayList<>();
|
||||||
|
|
||||||
private final BlockState air;
|
private final BlockState air;
|
||||||
|
|
||||||
public NoiseChunkGenerator3D(ConfigPack c, TerraPlugin main) {
|
public NoiseChunkGenerator3D(ConfigPack c, TerraPlugin main) {
|
||||||
this.configPack = c;
|
this.configPack = c;
|
||||||
this.main = main;
|
this.main = main;
|
||||||
this.air = main.getWorldHandle().air();
|
this.air = main.getWorldHandle().air();
|
||||||
c.getStages().forEach(stage -> generationStages.add(stage.newInstance(c)));
|
c.getStages().forEach(stage -> generationStages.add(stage.newInstance(c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"try"})
|
@SuppressWarnings("try")
|
||||||
static void biomes(@NotNull World world, int chunkX, int chunkZ, @NotNull BiomeGrid biome, TerraPlugin main) {
|
static void biomes(@NotNull World world, int chunkX, int chunkZ, @NotNull BiomeGrid biome, TerraPlugin main) {
|
||||||
try(ProfileFrame ignore = main.getProfiler().profile("biomes")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("biomes")) {
|
||||||
int xOrig = (chunkX << 4);
|
int xOrig = (chunkX << 4);
|
||||||
@ -53,73 +55,64 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
|||||||
int cx = xOrig + (x << 2);
|
int cx = xOrig + (x << 2);
|
||||||
int cz = zOrig + (z << 2);
|
int cz = zOrig + (z << 2);
|
||||||
TerraBiome b = grid.getBiome(cx, cz, seed);
|
TerraBiome b = grid.getBiome(cx, cz, seed);
|
||||||
|
|
||||||
biome.setBiome(cx, cz, b.getVanillaBiomes().get(b.getGenerator().getBiomeNoise(), cx, 0, cz, world.getSeed()));
|
biome.setBiome(cx, cz, b.getVanillaBiomes().get(b.getGenerator().getBiomeNoise(), cx, 0, cz, world.getSeed()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigPack getConfigPack() {
|
@SuppressWarnings("try")
|
||||||
return configPack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TerraPlugin getMain() {
|
|
||||||
return main;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings({"try"})
|
|
||||||
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
|
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
|
||||||
try(ProfileFrame ignore = main.getProfiler().profile("chunk_base_3d")) {
|
try(ProfileFrame ignore = main.getProfiler().profile("chunk_base_3d")) {
|
||||||
BiomeProvider grid = world.getBiomeProvider();
|
BiomeProvider grid = world.getBiomeProvider();
|
||||||
|
|
||||||
int xOrig = (chunkX << 4);
|
int xOrig = (chunkX << 4);
|
||||||
int zOrig = (chunkZ << 4);
|
int zOrig = (chunkZ << 4);
|
||||||
|
|
||||||
Sampler sampler = world.getConfig().getSamplerCache().getChunk(chunkX, chunkZ);
|
Sampler sampler = world.getConfig().getSamplerCache().getChunk(chunkX, chunkZ);
|
||||||
|
|
||||||
long seed = world.getSeed();
|
long seed = world.getSeed();
|
||||||
|
|
||||||
for(int x = 0; x < 16; x++) {
|
for(int x = 0; x < 16; x++) {
|
||||||
for(int z = 0; z < 16; z++) {
|
for(int z = 0; z < 16; z++) {
|
||||||
int paletteLevel = 0;
|
int paletteLevel = 0;
|
||||||
|
|
||||||
int cx = xOrig + x;
|
int cx = xOrig + x;
|
||||||
int cz = zOrig + z;
|
int cz = zOrig + z;
|
||||||
|
|
||||||
TerraBiome biome = grid.getBiome(cx, cz, seed);
|
TerraBiome biome = grid.getBiome(cx, cz, seed);
|
||||||
|
|
||||||
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
||||||
|
|
||||||
if(paletteInfo == null) {
|
if(paletteInfo == null) {
|
||||||
main.logger().info("null palette: " + biome.getID());
|
main.logger().info("null palette: " + biome.getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerationSettings generationSettings = biome.getGenerator();
|
GenerationSettings generationSettings = biome.getGenerator();
|
||||||
|
|
||||||
int sea = paletteInfo.getSeaLevel();
|
int sea = paletteInfo.getSeaLevel();
|
||||||
Palette seaPalette = paletteInfo.getOcean();
|
Palette seaPalette = paletteInfo.getOcean();
|
||||||
|
|
||||||
boolean justSet = false;
|
boolean justSet = false;
|
||||||
BlockState data = null;
|
BlockState data = null;
|
||||||
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
|
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
|
||||||
if(sampler.sample(x, y, z) > 0) {
|
if(sampler.sample(x, y, z) > 0) {
|
||||||
justSet = true;
|
justSet = true;
|
||||||
|
|
||||||
data = PaletteUtil.getPalette(x, y, z, generationSettings, sampler, paletteInfo).get(paletteLevel, cx, y, cz, seed);
|
data = PaletteUtil.getPalette(x, y, z, generationSettings, sampler, paletteInfo).get(paletteLevel, cx, y, cz,
|
||||||
|
seed);
|
||||||
chunk.setBlock(x, y, z, data);
|
chunk.setBlock(x, y, z, data);
|
||||||
|
|
||||||
paletteLevel++;
|
paletteLevel++;
|
||||||
} else if(y <= sea) {
|
} else if(y <= sea) {
|
||||||
chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig, seed));
|
chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig, seed));
|
||||||
|
|
||||||
justSet = false;
|
justSet = false;
|
||||||
paletteLevel = 0;
|
paletteLevel = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
justSet = false;
|
justSet = false;
|
||||||
paletteLevel = 0;
|
paletteLevel = 0;
|
||||||
}
|
}
|
||||||
@ -129,47 +122,38 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean placeStair(BlockState orig, ChunkData chunk, Vector3 block, double thresh, Sampler sampler, BlockState stairNew) {
|
|
||||||
|
|
||||||
if(sampler.sample(block.getBlockX() - 0.55, block.getY(), block.getZ()) > thresh) {
|
|
||||||
stairNew.set(Properties.DIRECTION, Direction.WEST);
|
|
||||||
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() - 0.55) > thresh) {
|
|
||||||
stairNew.set(Properties.DIRECTION, Direction.NORTH);
|
|
||||||
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() + 0.55) > thresh) {
|
|
||||||
stairNew.set(Properties.DIRECTION, Direction.SOUTH);
|
|
||||||
} else if(sampler.sample(block.getX() + 0.55, block.getY(), block.getZ()) > thresh) {
|
|
||||||
stairNew.set(Properties.DIRECTION, Direction.EAST);
|
|
||||||
} else stairNew = null;
|
|
||||||
if(stairNew != null) {
|
|
||||||
stairNew.setIfPresent(Properties.WATERLOGGED, orig.getBlockType().isWater());
|
|
||||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), stairNew);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateBiomes(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, @NotNull BiomeGrid biome) {
|
public void generateBiomes(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, @NotNull BiomeGrid biome) {
|
||||||
biomes(world, chunkX, chunkZ, biome, main);
|
biomes(world, chunkX, chunkZ, biome, main);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth) {
|
public Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth) {
|
||||||
return new Sampler3D(chunkX, chunkZ, provider, world, elevationSmooth);
|
return new Sampler3D(chunkX, chunkZ, provider, world, elevationSmooth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigPack getConfigPack() {
|
||||||
|
return configPack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TerraPlugin getMain() {
|
||||||
|
return main;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<GenerationStage> getGenerationStages() {
|
public List<GenerationStage> getGenerationStages() {
|
||||||
return generationStages;
|
return generationStages;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(World world, int x, int y, int z) {
|
public BlockState getBlock(World world, int x, int y, int z) {
|
||||||
BiomeProvider provider = world.getBiomeProvider();
|
BiomeProvider provider = world.getBiomeProvider();
|
||||||
TerraBiome biome = provider.getBiome(x, z, world.getSeed());
|
TerraBiome biome = provider.getBiome(x, z, world.getSeed());
|
||||||
Sampler sampler = world.getConfig().getSamplerCache().get(x, z);
|
Sampler sampler = world.getConfig().getSamplerCache().get(x, z);
|
||||||
|
|
||||||
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
||||||
Palette palette = PaletteUtil.getPalette(x, y, z, biome.getGenerator(), sampler, paletteInfo);
|
Palette palette = PaletteUtil.getPalette(x, y, z, biome.getGenerator(), sampler, paletteInfo);
|
||||||
int fdX = FastMath.floorMod(x, 16);
|
int fdX = FastMath.floorMod(x, 16);
|
||||||
@ -186,4 +170,23 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
|||||||
return paletteInfo.getOcean().get(paletteInfo.getSeaLevel() - y, x, y, z, world.getSeed());
|
return paletteInfo.getOcean().get(paletteInfo.getSeaLevel() - y, x, y, z, world.getSeed());
|
||||||
} else return air;
|
} else return air;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean placeStair(BlockState orig, ChunkData chunk, Vector3 block, double thresh, Sampler sampler, BlockState stairNew) {
|
||||||
|
|
||||||
|
if(sampler.sample(block.getBlockX() - 0.55, block.getY(), block.getZ()) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.WEST);
|
||||||
|
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() - 0.55) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.NORTH);
|
||||||
|
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() + 0.55) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.SOUTH);
|
||||||
|
} else if(sampler.sample(block.getX() + 0.55, block.getY(), block.getZ()) > thresh) {
|
||||||
|
stairNew.set(Properties.DIRECTION, Direction.EAST);
|
||||||
|
} else stairNew = null;
|
||||||
|
if(stairNew != null) {
|
||||||
|
stairNew.setIfPresent(Properties.WATERLOGGED, orig.getBlockType().isWater());
|
||||||
|
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), stairNew);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generator.ChunkInterpolator;
|
import com.dfsek.terra.api.world.generator.ChunkInterpolator;
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to abstract away the Interpolators needed to generate a chunk.<br>
|
* Class to abstract away the Interpolators needed to generate a chunk.<br>
|
||||||
@ -19,7 +21,7 @@ import java.util.function.BiFunction;
|
|||||||
public class ChunkInterpolator2D implements ChunkInterpolator {
|
public class ChunkInterpolator2D implements ChunkInterpolator {
|
||||||
private final Interpolator[][] interpGrid = new Interpolator[4][4];
|
private final Interpolator[][] interpGrid = new Interpolator[4][4];
|
||||||
private final BiFunction<GenerationSettings, Vector3, Double> noiseGetter;
|
private final BiFunction<GenerationSettings, Vector3, Double> noiseGetter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a 3D ChunkInterpolator3D at a pair of chunk coordinates.
|
* Instantiates a 3D ChunkInterpolator3D at a pair of chunk coordinates.
|
||||||
*
|
*
|
||||||
@ -27,33 +29,36 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
|
|||||||
* @param chunkZ Z coordinate of the chunk.
|
* @param chunkZ Z coordinate of the chunk.
|
||||||
* @param provider Biome Provider to use for biome fetching.
|
* @param provider Biome Provider to use for biome fetching.
|
||||||
*/
|
*/
|
||||||
public ChunkInterpolator2D(World w, int chunkX, int chunkZ, BiomeProvider provider, BiFunction<GenerationSettings, Vector3, Double> noiseGetter) {
|
public ChunkInterpolator2D(World w, int chunkX, int chunkZ, BiomeProvider provider,
|
||||||
|
BiFunction<GenerationSettings, Vector3, Double> noiseGetter) {
|
||||||
this.noiseGetter = noiseGetter;
|
this.noiseGetter = noiseGetter;
|
||||||
int xOrigin = chunkX << 4;
|
int xOrigin = chunkX << 4;
|
||||||
int zOrigin = chunkZ << 4;
|
int zOrigin = chunkZ << 4;
|
||||||
|
|
||||||
long seed = w.getSeed();
|
long seed = w.getSeed();
|
||||||
|
|
||||||
double[][] noiseStorage = new double[5][5];
|
double[][] noiseStorage = new double[5][5];
|
||||||
|
|
||||||
for(int x = 0; x < 5; x++) {
|
for(int x = 0; x < 5; x++) {
|
||||||
for(int z = 0; z < 5; z++) {
|
for(int z = 0; z < 5; z++) {
|
||||||
GenerationSettings generationSettings = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator();
|
GenerationSettings generationSettings = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator();
|
||||||
Map<GenerationSettings, MutableInteger> genMap = new HashMap<>();
|
Map<GenerationSettings, MutableInteger> genMap = new HashMap<>();
|
||||||
|
|
||||||
int step = generationSettings.getBlendStep();
|
int step = generationSettings.getBlendStep();
|
||||||
int blend = generationSettings.getBlendDistance();
|
int blend = generationSettings.getBlendDistance();
|
||||||
|
|
||||||
for(int xi = -blend; xi <= blend; xi++) {
|
for(int xi = -blend; xi <= blend; xi++) {
|
||||||
for(int zi = -blend; zi <= blend; zi++) {
|
for(int zi = -blend; zi <= blend; zi++) {
|
||||||
genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(), g -> new MutableInteger(0)).increment(); // Increment by 1
|
genMap.computeIfAbsent(
|
||||||
|
provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(),
|
||||||
|
g -> new MutableInteger(0)).increment(); // Increment by 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
noiseStorage[x][z] = computeNoise(genMap, (x << 2) + xOrigin, 0, (z << 2) + zOrigin);
|
noiseStorage[x][z] = computeNoise(genMap, (x << 2) + xOrigin, 0, (z << 2) + zOrigin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < 4; x++) {
|
for(int x = 0; x < 4; x++) {
|
||||||
for(int z = 0; z < 4; z++) {
|
for(int z = 0; z < 4; z++) {
|
||||||
interpGrid[x][z] = new Interpolator(
|
interpGrid[x][z] = new Interpolator(
|
||||||
@ -64,27 +69,28 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int reRange(int value, int high) {
|
private static int reRange(int value, int high) {
|
||||||
return FastMath.max(FastMath.min(value, high), 0);
|
return FastMath.max(FastMath.min(value, high), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double computeNoise(GenerationSettings generationSettings, double x, double y, double z) {
|
public double computeNoise(GenerationSettings generationSettings, double x, double y, double z) {
|
||||||
return noiseGetter.apply(generationSettings, new Vector3(x, y, z));
|
return noiseGetter.apply(generationSettings, new Vector3(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the noise at a pair of internal chunk coordinates.
|
* Gets the noise at a pair of internal chunk coordinates.
|
||||||
*
|
*
|
||||||
* @param x The internal X coordinate (0-15).
|
* @param x The internal X coordinate (0-15).
|
||||||
* @param z The internal Z coordinate (0-15).
|
* @param z The internal Z coordinate (0-15).
|
||||||
|
*
|
||||||
* @return double - The interpolated noise at the coordinates.
|
* @return double - The interpolated noise at the coordinates.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public double getNoise(double x, double y, double z) {
|
public double getNoise(double x, double y, double z) {
|
||||||
return interpGrid[reRange(((int) x) / 4, 3)][reRange(((int) z) / 4, 3)].bilerp((x % 4) / 4, (z % 4) / 4);
|
return interpGrid[reRange(((int) x) / 4, 3)][reRange(((int) z) / 4, 3)].bilerp((x % 4) / 4, (z % 4) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getNoise(int x, int y, int z) {
|
public double getNoise(int x, int y, int z) {
|
||||||
return interpGrid[x / 4][z / 4].bilerp((double) (x % 4) / 4, (double) (z % 4) / 4);
|
return interpGrid[x / 4][z / 4].bilerp((double) (x % 4) / 4, (double) (z % 4) / 4);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generator.ChunkInterpolator;
|
import com.dfsek.terra.api.world.generator.ChunkInterpolator;
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to abstract away the Interpolators needed to generate a chunk.<br>
|
* Class to abstract away the Interpolators needed to generate a chunk.<br>
|
||||||
@ -19,10 +21,10 @@ import java.util.function.BiFunction;
|
|||||||
public class ChunkInterpolator3D implements ChunkInterpolator {
|
public class ChunkInterpolator3D implements ChunkInterpolator {
|
||||||
private final Interpolator3[][][] interpGrid;
|
private final Interpolator3[][][] interpGrid;
|
||||||
private final BiFunction<GenerationSettings, Vector3, Double> noiseGetter;
|
private final BiFunction<GenerationSettings, Vector3, Double> noiseGetter;
|
||||||
|
|
||||||
private final int min;
|
private final int min;
|
||||||
private final int max;
|
private final int max;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a 3D ChunkInterpolator3D at a pair of chunk coordinates.
|
* Instantiates a 3D ChunkInterpolator3D at a pair of chunk coordinates.
|
||||||
*
|
*
|
||||||
@ -30,43 +32,46 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
|
|||||||
* @param chunkZ Z coordinate of the chunk.
|
* @param chunkZ Z coordinate of the chunk.
|
||||||
* @param provider Biome Provider to use for biome fetching.
|
* @param provider Biome Provider to use for biome fetching.
|
||||||
*/
|
*/
|
||||||
public ChunkInterpolator3D(World w, int chunkX, int chunkZ, BiomeProvider provider, BiFunction<GenerationSettings, Vector3, Double> noiseGetter) {
|
public ChunkInterpolator3D(World w, int chunkX, int chunkZ, BiomeProvider provider,
|
||||||
|
BiFunction<GenerationSettings, Vector3, Double> noiseGetter) {
|
||||||
this.noiseGetter = noiseGetter;
|
this.noiseGetter = noiseGetter;
|
||||||
int xOrigin = chunkX << 4;
|
int xOrigin = chunkX << 4;
|
||||||
int zOrigin = chunkZ << 4;
|
int zOrigin = chunkZ << 4;
|
||||||
|
|
||||||
this.max = w.getMaxHeight();
|
this.max = w.getMaxHeight();
|
||||||
this.min = w.getMinHeight();
|
this.min = w.getMinHeight();
|
||||||
int range = max - min + 1;
|
int range = max - min + 1;
|
||||||
|
|
||||||
int size = range >> 2;
|
int size = range >> 2;
|
||||||
|
|
||||||
interpGrid = new Interpolator3[4][size][4];
|
interpGrid = new Interpolator3[4][size][4];
|
||||||
|
|
||||||
double[][][] noiseStorage = new double[5][5][size + 1];
|
double[][][] noiseStorage = new double[5][5][size + 1];
|
||||||
|
|
||||||
long seed = w.getSeed();
|
long seed = w.getSeed();
|
||||||
|
|
||||||
for(int x = 0; x < 5; x++) {
|
for(int x = 0; x < 5; x++) {
|
||||||
for(int z = 0; z < 5; z++) {
|
for(int z = 0; z < 5; z++) {
|
||||||
GenerationSettings generationSettings = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator();
|
GenerationSettings generationSettings = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator();
|
||||||
Map<GenerationSettings, MutableInteger> genMap = new HashMap<>();
|
Map<GenerationSettings, MutableInteger> genMap = new HashMap<>();
|
||||||
|
|
||||||
int step = generationSettings.getBlendStep();
|
int step = generationSettings.getBlendStep();
|
||||||
int blend = generationSettings.getBlendDistance();
|
int blend = generationSettings.getBlendDistance();
|
||||||
|
|
||||||
for(int xi = -blend; xi <= blend; xi++) {
|
for(int xi = -blend; xi <= blend; xi++) {
|
||||||
for(int zi = -blend; zi <= blend; zi++) {
|
for(int zi = -blend; zi <= blend; zi++) {
|
||||||
genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(), g -> new MutableInteger(0)).increment(); // Increment by 1
|
genMap.computeIfAbsent(
|
||||||
|
provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(),
|
||||||
|
g -> new MutableInteger(0)).increment(); // Increment by 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int y = 0; y < size + 1; y++) {
|
for(int y = 0; y < size + 1; y++) {
|
||||||
noiseStorage[x][z][y] = computeNoise(genMap, (x << 2) + xOrigin, (y << 2) + min, (z << 2) + zOrigin);
|
noiseStorage[x][z][y] = computeNoise(genMap, (x << 2) + xOrigin, (y << 2) + min, (z << 2) + zOrigin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = 0; x < 4; x++) {
|
for(int x = 0; x < 4; x++) {
|
||||||
for(int z = 0; z < 4; z++) {
|
for(int z = 0; z < 4; z++) {
|
||||||
for(int y = 0; y < size; y++) {
|
for(int y = 0; y < size; y++) {
|
||||||
@ -83,27 +88,30 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int reRange(int value, int high) {
|
private static int reRange(int value, int high) {
|
||||||
return FastMath.max(FastMath.min(value, high), 0);
|
return FastMath.max(FastMath.min(value, high), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double computeNoise(GenerationSettings generationSettings, double x, double y, double z) {
|
public double computeNoise(GenerationSettings generationSettings, double x, double y, double z) {
|
||||||
return noiseGetter.apply(generationSettings, new Vector3(x, y, z));
|
return noiseGetter.apply(generationSettings, new Vector3(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the noise at a pair of internal chunk coordinates.
|
* Gets the noise at a pair of internal chunk coordinates.
|
||||||
*
|
*
|
||||||
* @param x The internal X coordinate (0-15).
|
* @param x The internal X coordinate (0-15).
|
||||||
* @param z The internal Z coordinate (0-15).
|
* @param z The internal Z coordinate (0-15).
|
||||||
|
*
|
||||||
* @return double - The interpolated noise at the coordinates.
|
* @return double - The interpolated noise at the coordinates.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public double getNoise(double x, double y, double z) {
|
public double getNoise(double x, double y, double z) {
|
||||||
return interpGrid[reRange(((int) x) / 4, 3)][(FastMath.max(FastMath.min(((int) y), max), min) - min) / 4][reRange(((int) z) / 4, 3)].trilerp((x % 4) / 4, (y % 4) / 4, (z % 4) / 4);
|
return interpGrid[reRange(((int) x) / 4, 3)][(FastMath.max(FastMath.min(((int) y), max), min) - min) / 4][reRange(((int) z) / 4,
|
||||||
|
3)].trilerp(
|
||||||
|
(x % 4) / 4, (y % 4) / 4, (z % 4) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getNoise(int x, int y, int z) {
|
public double getNoise(int x, int y, int z) {
|
||||||
return interpGrid[x / 4][(y - min) / 4][z / 4].trilerp((double) (x % 4) / 4, (double) (y % 4) / 4, (double) (z % 4) / 4);
|
return interpGrid[x / 4][(y - min) / 4][z / 4].trilerp((double) (x % 4) / 4, (double) (y % 4) / 4, (double) (z % 4) / 4);
|
||||||
}
|
}
|
||||||
|
@ -4,24 +4,25 @@ import com.dfsek.terra.api.world.World;
|
|||||||
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
public class ElevationInterpolator {
|
public class ElevationInterpolator {
|
||||||
private final double[][] values = new double[18][18];
|
private final double[][] values = new double[18][18];
|
||||||
|
|
||||||
public ElevationInterpolator(World world, int chunkX, int chunkZ, BiomeProvider provider, int smooth) {
|
public ElevationInterpolator(World world, int chunkX, int chunkZ, BiomeProvider provider, int smooth) {
|
||||||
int xOrigin = chunkX << 4;
|
int xOrigin = chunkX << 4;
|
||||||
int zOrigin = chunkZ << 4;
|
int zOrigin = chunkZ << 4;
|
||||||
|
|
||||||
long seed = world.getSeed();
|
long seed = world.getSeed();
|
||||||
|
|
||||||
GenerationSettings[][] gens = new GenerationSettings[18 + 2 * smooth][18 + 2 * smooth];
|
GenerationSettings[][] gens = new GenerationSettings[18 + 2 * smooth][18 + 2 * smooth];
|
||||||
|
|
||||||
// Precompute generators.
|
// Precompute generators.
|
||||||
for(int x = -1 - smooth; x <= 16 + smooth; x++) {
|
for(int x = -1 - smooth; x <= 16 + smooth; x++) {
|
||||||
for(int z = -1 - smooth; z <= 16 + smooth; z++) {
|
for(int z = -1 - smooth; z <= 16 + smooth; z++) {
|
||||||
gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z, seed).getGenerator();
|
gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z, seed).getGenerator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int x = -1; x <= 16; x++) {
|
for(int x = -1; x <= 16; x++) {
|
||||||
for(int z = -1; z <= 16; z++) {
|
for(int z = -1; z <= 16; z++) {
|
||||||
double noise = 0;
|
double noise = 0;
|
||||||
@ -37,7 +38,7 @@ public class ElevationInterpolator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getElevation(int x, int z) {
|
public double getElevation(int x, int z) {
|
||||||
return values[x + 1][z + 1];
|
return values[x + 1][z + 1];
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
|||||||
*/
|
*/
|
||||||
public class Interpolator {
|
public class Interpolator {
|
||||||
private final double v0, v1, v2, v3;
|
private final double v0, v1, v2, v3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an interpolator with given values as vertices of a unit square.
|
* Constructs an interpolator with given values as vertices of a unit square.
|
||||||
*
|
*
|
||||||
@ -20,24 +20,26 @@ public class Interpolator {
|
|||||||
this.v2 = v2;
|
this.v2 = v2;
|
||||||
this.v3 = v3;
|
this.v3 = v3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1D Linear interpolation between 2 points 1 unit apart.
|
* 1D Linear interpolation between 2 points 1 unit apart.
|
||||||
*
|
*
|
||||||
* @param t - Distance from v0. Total distance between v0 and v1 is 1 unit.
|
* @param t - Distance from v0. Total distance between v0 and v1 is 1 unit.
|
||||||
* @param v0 - Value at v0.
|
* @param v0 - Value at v0.
|
||||||
* @param v1 - Value at v1.
|
* @param v1 - Value at v1.
|
||||||
|
*
|
||||||
* @return double - The interpolated value.
|
* @return double - The interpolated value.
|
||||||
*/
|
*/
|
||||||
public static double lerp(double t, double v0, double v1) {
|
public static double lerp(double t, double v0, double v1) {
|
||||||
return v0 + t * (v1 - v0);
|
return v0 + t * (v1 - v0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2D Bilinear interpolation between 4 points on a unit square.
|
* 2D Bilinear interpolation between 4 points on a unit square.
|
||||||
*
|
*
|
||||||
* @param s - X value
|
* @param s - X value
|
||||||
* @param t - Z value
|
* @param t - Z value
|
||||||
|
*
|
||||||
* @return double - The interpolated value.
|
* @return double - The interpolated value.
|
||||||
*/
|
*/
|
||||||
public double bilerp(double s, double t) {
|
public double bilerp(double s, double t) {
|
||||||
|
@ -6,7 +6,7 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
|||||||
public class Interpolator3 {
|
public class Interpolator3 {
|
||||||
private final Interpolator bottom;
|
private final Interpolator bottom;
|
||||||
private final Interpolator top;
|
private final Interpolator top;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an interpolator with given values as vertices of a unit cube.
|
* Constructs an interpolator with given values as vertices of a unit cube.
|
||||||
* * @param _000 The value at <code>(t, u, v) = (0, 0, 0)</code>.
|
* * @param _000 The value at <code>(t, u, v) = (0, 0, 0)</code>.
|
||||||
@ -25,7 +25,7 @@ public class Interpolator3 {
|
|||||||
this.top = new Interpolator(_000, _010, _001, _011);
|
this.top = new Interpolator(_000, _010, _001, _011);
|
||||||
this.bottom = new Interpolator(_100, _110, _101, _111);
|
this.bottom = new Interpolator(_100, _110, _101, _111);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double trilerp(double x, double y, double z) {
|
public double trilerp(double x, double y, double z) {
|
||||||
return Interpolator.lerp(x, top.bilerp(y, z), bottom.bilerp(y, z));
|
return Interpolator.lerp(x, top.bilerp(y, z), bottom.bilerp(y, z));
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,30 @@
|
|||||||
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
|
||||||
|
|
||||||
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator3D;
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator3D;
|
||||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ElevationInterpolator;
|
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ElevationInterpolator;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import com.dfsek.terra.api.world.generator.Sampler;
|
import com.dfsek.terra.api.world.generator.Sampler;
|
||||||
import net.jafama.FastMath;
|
|
||||||
|
|
||||||
public class Sampler3D implements Sampler {
|
public class Sampler3D implements Sampler {
|
||||||
private final ChunkInterpolator3D interpolator;
|
private final ChunkInterpolator3D interpolator;
|
||||||
private final ElevationInterpolator elevationInterpolator;
|
private final ElevationInterpolator elevationInterpolator;
|
||||||
|
|
||||||
public Sampler3D(int x, int z, BiomeProvider provider, World world, int elevationSmooth) {
|
public Sampler3D(int x, int z, BiomeProvider provider, World world, int elevationSmooth) {
|
||||||
this.interpolator = new ChunkInterpolator3D(world, x, z, provider, (generator, coord) -> generator.getBaseSampler().getNoiseSeeded(coord, world.getSeed()));
|
this.interpolator = new ChunkInterpolator3D(world, x, z, provider, (generator, coord) -> generator.getBaseSampler()
|
||||||
|
.getNoiseSeeded(coord,
|
||||||
|
world.getSeed()));
|
||||||
this.elevationInterpolator = new ElevationInterpolator(world, x, z, provider, elevationSmooth);
|
this.elevationInterpolator = new ElevationInterpolator(world, x, z, provider, elevationSmooth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double sample(double x, double y, double z) {
|
public double sample(double x, double y, double z) {
|
||||||
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
|
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double sample(int x, int y, int z) {
|
public double sample(int x, int y, int z) {
|
||||||
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
|
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
|
||||||
|
@ -2,21 +2,22 @@ package com.dfsek.terra.addons.chunkgenerator.palette;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteHolder {
|
public class PaletteHolder {
|
||||||
private final Palette[] palettes;
|
private final Palette[] palettes;
|
||||||
private final int offset;
|
private final int offset;
|
||||||
|
|
||||||
protected PaletteHolder(Palette[] palettes, int offset) {
|
protected PaletteHolder(Palette[] palettes, int offset) {
|
||||||
this.palettes = palettes;
|
this.palettes = palettes;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Palette getPalette(int y) {
|
public Palette getPalette(int y) {
|
||||||
int index = y + offset;
|
int index = y + offset;
|
||||||
return index >= 0
|
return index >= 0
|
||||||
? index < palettes.length
|
? index < palettes.length
|
||||||
? palettes[index]
|
? palettes[index]
|
||||||
: palettes[palettes.length - 1]
|
: palettes[palettes.length - 1]
|
||||||
: palettes[0];
|
: palettes[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
package com.dfsek.terra.addons.chunkgenerator.palette;
|
package com.dfsek.terra.addons.chunkgenerator.palette;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteHolderBuilder {
|
public class PaletteHolderBuilder {
|
||||||
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
||||||
|
|
||||||
public PaletteHolderBuilder add(int y, Palette palette) {
|
public PaletteHolderBuilder add(int y, Palette palette) {
|
||||||
paletteMap.put(y, palette);
|
paletteMap.put(y, palette);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaletteHolder build() {
|
public PaletteHolder build() {
|
||||||
|
|
||||||
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
||||||
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
||||||
|
|
||||||
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
|
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
|
||||||
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
|
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
|
||||||
Palette d = null;
|
Palette d = null;
|
||||||
|
@ -3,12 +3,14 @@ package com.dfsek.terra.addons.chunkgenerator.palette;
|
|||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
|
||||||
|
|
||||||
import java.lang.reflect.AnnotatedType;
|
import java.lang.reflect.AnnotatedType;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
|
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,32 +3,33 @@ package com.dfsek.terra.addons.chunkgenerator.palette;
|
|||||||
import com.dfsek.terra.api.properties.Properties;
|
import com.dfsek.terra.api.properties.Properties;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteInfo implements Properties {
|
public class PaletteInfo implements Properties {
|
||||||
private final PaletteHolder paletteHolder;
|
private final PaletteHolder paletteHolder;
|
||||||
private final SlantHolder slantHolder;
|
private final SlantHolder slantHolder;
|
||||||
private final Palette ocean;
|
private final Palette ocean;
|
||||||
|
|
||||||
private final int seaLevel;
|
private final int seaLevel;
|
||||||
|
|
||||||
public PaletteInfo(PaletteHolder paletteHolder, SlantHolder slantHolder, Palette ocean, int seaLevel) {
|
public PaletteInfo(PaletteHolder paletteHolder, SlantHolder slantHolder, Palette ocean, int seaLevel) {
|
||||||
this.paletteHolder = paletteHolder;
|
this.paletteHolder = paletteHolder;
|
||||||
this.slantHolder = slantHolder;
|
this.slantHolder = slantHolder;
|
||||||
this.ocean = ocean;
|
this.ocean = ocean;
|
||||||
this.seaLevel = seaLevel;
|
this.seaLevel = seaLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Palette getOcean() {
|
public Palette getOcean() {
|
||||||
return ocean;
|
return ocean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaletteHolder getPaletteHolder() {
|
public PaletteHolder getPaletteHolder() {
|
||||||
return paletteHolder;
|
return paletteHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SlantHolder getSlantHolder() {
|
public SlantHolder getSlantHolder() {
|
||||||
return slantHolder;
|
return slantHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSeaLevel() {
|
public int getSeaLevel() {
|
||||||
return seaLevel;
|
return seaLevel;
|
||||||
}
|
}
|
||||||
|
@ -3,19 +3,20 @@ package com.dfsek.terra.addons.chunkgenerator.palette;
|
|||||||
|
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
|
||||||
public class SlantHolder {
|
public class SlantHolder {
|
||||||
private final TreeMap<Double, PaletteHolder> layers;
|
private final TreeMap<Double, PaletteHolder> layers;
|
||||||
private final double minSlope;
|
private final double minSlope;
|
||||||
|
|
||||||
public SlantHolder(TreeMap<Double, PaletteHolder> layers, double minSlope) {
|
public SlantHolder(TreeMap<Double, PaletteHolder> layers, double minSlope) {
|
||||||
this.layers = layers;
|
this.layers = layers;
|
||||||
this.minSlope = minSlope;
|
this.minSlope = minSlope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaletteHolder getPalette(double slope) {
|
public PaletteHolder getPalette(double slope) {
|
||||||
return layers.floorEntry(slope).getValue();
|
return layers.floorEntry(slope).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getMinSlope() {
|
public double getMinSlope() {
|
||||||
return minSlope;
|
return minSlope;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class SlantHolderLoader implements TypeLoader<SlantHolder> {
|
public class SlantHolderLoader implements TypeLoader<SlantHolder> {
|
||||||
@Override
|
@Override
|
||||||
@ -16,13 +17,13 @@ public class SlantHolderLoader implements TypeLoader<SlantHolder> {
|
|||||||
List<Map<Object, Object>> layers = (List<Map<Object, Object>>) o;
|
List<Map<Object, Object>> layers = (List<Map<Object, Object>>) o;
|
||||||
TreeMap<Double, PaletteHolder> slantLayers = new TreeMap<>();
|
TreeMap<Double, PaletteHolder> slantLayers = new TreeMap<>();
|
||||||
double minThreshold = Double.MAX_VALUE;
|
double minThreshold = Double.MAX_VALUE;
|
||||||
|
|
||||||
for(Map<Object, Object> layer : layers) {
|
for(Map<Object, Object> layer : layers) {
|
||||||
double threshold = ((Number) layer.get("threshold")).doubleValue();
|
double threshold = ((Number) layer.get("threshold")).doubleValue();
|
||||||
if(threshold < minThreshold) minThreshold = threshold;
|
if(threshold < minThreshold) minThreshold = threshold;
|
||||||
slantLayers.put(threshold, configLoader.loadType(PaletteHolder.class, layer.get("palette")));
|
slantLayers.put(threshold, configLoader.loadType(PaletteHolder.class, layer.get("palette")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SlantHolder(slantLayers, minThreshold);
|
return new SlantHolder(slantLayers, minThreshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,22 +11,23 @@ import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
|||||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
|
|
||||||
|
|
||||||
@Addon("config-biome")
|
@Addon("config-biome")
|
||||||
@Author("Terra")
|
@Author("Terra")
|
||||||
@Version("1.0.0")
|
@Version("1.0.0")
|
||||||
public class BiomeAddon extends TerraAddon {
|
public class BiomeAddon extends TerraAddon {
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
main.getEventManager()
|
main.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigPackPreLoadEvent.class)
|
.register(this, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
event.getPack().registerConfigType(new BiomeConfigType(event.getPack()), "BIOME", 5);
|
event.getPack().registerConfigType(new BiomeConfigType(event.getPack()), "BIOME", 5);
|
||||||
event.getPack().applyLoader(PaletteHolder.class, new PaletteHolderLoader());
|
event.getPack().applyLoader(PaletteHolder.class, new PaletteHolderLoader());
|
||||||
})
|
})
|
||||||
.failThrough();
|
.failThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@ package com.dfsek.terra.addons.biome;
|
|||||||
|
|
||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.config.ConfigFactory;
|
import com.dfsek.terra.api.config.ConfigFactory;
|
||||||
import com.dfsek.terra.api.config.ConfigPack;
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
@ -10,32 +13,16 @@ import com.dfsek.terra.api.registry.OpenRegistry;
|
|||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class BiomeConfigType implements ConfigType<BiomeTemplate, TerraBiome> {
|
public class BiomeConfigType implements ConfigType<BiomeTemplate, TerraBiome> {
|
||||||
|
public static final TypeKey<TerraBiome> BIOME_TYPE_TOKEN = new TypeKey<>() {
|
||||||
|
};
|
||||||
private final BiomeFactory factory;
|
private final BiomeFactory factory;
|
||||||
|
|
||||||
public static final TypeKey<TerraBiome> BIOME_TYPE_TOKEN = new TypeKey<>() {};
|
|
||||||
|
|
||||||
public BiomeConfigType(ConfigPack pack) {
|
public BiomeConfigType(ConfigPack pack) {
|
||||||
this.factory = new BiomeFactory(pack);
|
this.factory = new BiomeFactory(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiomeTemplate getTemplate(ConfigPack pack, TerraPlugin main) {
|
|
||||||
return new BiomeTemplate(pack, main);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfigFactory<BiomeTemplate, TerraBiome> getFactory() {
|
|
||||||
return factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeKey<TerraBiome> getTypeKey() {
|
|
||||||
return BIOME_TYPE_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Supplier<OpenRegistry<TerraBiome>> registrySupplier(ConfigPack pack) {
|
public Supplier<OpenRegistry<TerraBiome>> registrySupplier(ConfigPack pack) {
|
||||||
return () -> pack.getRegistryFactory().create(registry -> (TypeLoader<TerraBiome>) (t, c, loader) -> {
|
return () -> pack.getRegistryFactory().create(registry -> (TypeLoader<TerraBiome>) (t, c, loader) -> {
|
||||||
@ -46,4 +33,19 @@ public class BiomeConfigType implements ConfigType<BiomeTemplate, TerraBiome> {
|
|||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeTemplate getTemplate(ConfigPack pack, TerraPlugin main) {
|
||||||
|
return new BiomeTemplate(pack, main);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigFactory<BiomeTemplate, TerraBiome> getFactory() {
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeKey<TerraBiome> getTypeKey() {
|
||||||
|
return BIOME_TYPE_TOKEN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,22 @@ import com.dfsek.terra.api.config.ConfigFactory;
|
|||||||
import com.dfsek.terra.api.config.ConfigPack;
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public class BiomeFactory implements ConfigFactory<BiomeTemplate, TerraBiome> {
|
public class BiomeFactory implements ConfigFactory<BiomeTemplate, TerraBiome> {
|
||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
|
|
||||||
public BiomeFactory(ConfigPack pack) {
|
public BiomeFactory(ConfigPack pack) {
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome build(BiomeTemplate template, TerraPlugin main) {
|
public TerraBiome build(BiomeTemplate template, TerraPlugin main) {
|
||||||
UserDefinedGenerationSettings generator = new UserDefinedGenerationSettings(template.getNoiseEquation(), template.getElevationEquation(), template.getCarvingEquation(), template.getBiomeNoise(), template.getElevationWeight(),
|
UserDefinedGenerationSettings generator = new UserDefinedGenerationSettings(template.getNoiseEquation(),
|
||||||
template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight());
|
template.getElevationEquation(),
|
||||||
|
template.getCarvingEquation(), template.getBiomeNoise(),
|
||||||
|
template.getElevationWeight(),
|
||||||
|
template.getBlendDistance(), template.getBlendStep(),
|
||||||
|
template.getBlendWeight());
|
||||||
return new UserDefinedBiome(template.getVanilla(), generator, template);
|
return new UserDefinedBiome(template.getVanilla(), generator, template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,14 @@ import com.dfsek.tectonic.annotations.Final;
|
|||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||||
import com.dfsek.tectonic.exception.ValidationException;
|
import com.dfsek.tectonic.exception.ValidationException;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||||
@ -15,196 +23,191 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
|||||||
import com.dfsek.terra.api.world.biome.Biome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@SuppressWarnings({"FieldMayBeFinal", "unused"})
|
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
|
||||||
public class BiomeTemplate implements AbstractableTemplate, ValidatedConfigTemplate {
|
public class BiomeTemplate implements AbstractableTemplate, ValidatedConfigTemplate {
|
||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
|
|
||||||
@Value("id")
|
@Value("id")
|
||||||
@Final
|
@Final
|
||||||
private @Meta String id;
|
private @Meta String id;
|
||||||
|
|
||||||
@Value("extends")
|
@Value("extends")
|
||||||
@Final
|
@Final
|
||||||
@Default
|
@Default
|
||||||
private List<String> extended = Collections.emptyList();
|
private List<String> extended = Collections.emptyList();
|
||||||
|
|
||||||
@Value("variables")
|
@Value("variables")
|
||||||
@Default
|
@Default
|
||||||
private @Meta Map<String, @Meta Double> variables = new HashMap<>();
|
private @Meta Map<String, @Meta Double> variables = new HashMap<>();
|
||||||
|
|
||||||
@Value("beta.carving.equation")
|
@Value("beta.carving.equation")
|
||||||
@Default
|
@Default
|
||||||
private @Meta NoiseSampler carvingEquation = NoiseSampler.zero();
|
private @Meta NoiseSampler carvingEquation = NoiseSampler.zero();
|
||||||
|
|
||||||
@Value("vanilla")
|
@Value("vanilla")
|
||||||
private @Meta ProbabilityCollection<Biome> vanilla;
|
private @Meta ProbabilityCollection<Biome> vanilla;
|
||||||
|
|
||||||
@Value("biome-noise")
|
@Value("biome-noise")
|
||||||
@Default
|
@Default
|
||||||
private @Meta NoiseSampler biomeNoise = NoiseSampler.zero();
|
private @Meta NoiseSampler biomeNoise = NoiseSampler.zero();
|
||||||
|
|
||||||
@Value("blend.distance")
|
@Value("blend.distance")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int blendDistance = 3;
|
private @Meta int blendDistance = 3;
|
||||||
|
|
||||||
@Value("blend.weight")
|
@Value("blend.weight")
|
||||||
@Default
|
@Default
|
||||||
private @Meta double blendWeight = 1;
|
private @Meta double blendWeight = 1;
|
||||||
|
|
||||||
@Value("blend.step")
|
@Value("blend.step")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int blendStep = 4;
|
private @Meta int blendStep = 4;
|
||||||
|
|
||||||
@Value("noise")
|
@Value("noise")
|
||||||
private @Meta NoiseSampler noiseEquation;
|
private @Meta NoiseSampler noiseEquation;
|
||||||
|
|
||||||
@Value("ocean.level")
|
@Value("ocean.level")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int seaLevel = 62;
|
private @Meta int seaLevel = 62;
|
||||||
|
|
||||||
@Value("elevation.equation")
|
@Value("elevation.equation")
|
||||||
@Default
|
@Default
|
||||||
private @Meta NoiseSampler elevationEquation = NoiseSampler.zero();
|
private @Meta NoiseSampler elevationEquation = NoiseSampler.zero();
|
||||||
|
|
||||||
@Value("elevation.weight")
|
@Value("elevation.weight")
|
||||||
@Default
|
@Default
|
||||||
private @Meta double elevationWeight = 1;
|
private @Meta double elevationWeight = 1;
|
||||||
|
|
||||||
@Value("slabs.enable")
|
@Value("slabs.enable")
|
||||||
@Default
|
@Default
|
||||||
private @Meta boolean doSlabs = false;
|
private @Meta boolean doSlabs = false;
|
||||||
|
|
||||||
@Value("slabs.threshold")
|
@Value("slabs.threshold")
|
||||||
@Default
|
@Default
|
||||||
private @Meta double slabThreshold = 0.0075D;
|
private @Meta double slabThreshold = 0.0075D;
|
||||||
|
|
||||||
@Value("slabs.palettes")
|
@Value("slabs.palettes")
|
||||||
@Default
|
@Default
|
||||||
private @Meta Map<@Meta BlockType, @Meta Palette> slabPalettes;
|
private @Meta Map<@Meta BlockType, @Meta Palette> slabPalettes;
|
||||||
|
|
||||||
@Value("slabs.stair-palettes")
|
@Value("slabs.stair-palettes")
|
||||||
@Default
|
@Default
|
||||||
private @Meta Map<@Meta BlockType, @Meta Palette> stairPalettes;
|
private @Meta Map<@Meta BlockType, @Meta Palette> stairPalettes;
|
||||||
|
|
||||||
@Value("interpolate-elevation")
|
@Value("interpolate-elevation")
|
||||||
@Default
|
@Default
|
||||||
private @Meta boolean interpolateElevation = true;
|
private @Meta boolean interpolateElevation = true;
|
||||||
|
|
||||||
@Value("color")
|
@Value("color")
|
||||||
@Final
|
@Final
|
||||||
@Default
|
@Default
|
||||||
private @Meta int color = 0;
|
private @Meta int color = 0;
|
||||||
|
|
||||||
@Value("tags")
|
@Value("tags")
|
||||||
@Default
|
@Default
|
||||||
private @Meta Set<@Meta String> tags = new HashSet<>();
|
private @Meta Set<@Meta String> tags = new HashSet<>();
|
||||||
|
|
||||||
@Value("colors")
|
@Value("colors")
|
||||||
@Default
|
@Default
|
||||||
private @Meta Map<String, @Meta Integer> colors = new HashMap<>(); // Plain ol' map, so platforms can decide what to do with colors (if anything).
|
private @Meta Map<String, @Meta Integer> colors = new HashMap<>();
|
||||||
|
// Plain ol' map, so platforms can decide what to do with colors (if anything).
|
||||||
|
|
||||||
public BiomeTemplate(ConfigPack pack, TerraPlugin main) {
|
public BiomeTemplate(ConfigPack pack, TerraPlugin main) {
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getExtended() {
|
|
||||||
return extended;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getTags() {
|
|
||||||
return tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Integer> getColors() {
|
|
||||||
return colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getBlendWeight() {
|
|
||||||
return blendWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColor() {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBlendDistance() {
|
|
||||||
return blendDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean interpolateElevation() {
|
public boolean interpolateElevation() {
|
||||||
return interpolateElevation;
|
return interpolateElevation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getSlabThreshold() {
|
|
||||||
return slabThreshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean doSlabs() {
|
public boolean doSlabs() {
|
||||||
return doSlabs;
|
return doSlabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<BlockType, Palette> getSlabPalettes() {
|
|
||||||
return slabPalettes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<BlockType, Palette> getStairPalettes() {
|
|
||||||
return stairPalettes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoiseSampler getBiomeNoise() {
|
|
||||||
return biomeNoise;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoiseSampler getElevationEquation() {
|
|
||||||
return elevationEquation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoiseSampler getCarvingEquation() {
|
|
||||||
return carvingEquation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigPack getPack() {
|
|
||||||
return pack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSeaLevel() {
|
|
||||||
return seaLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getID() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProbabilityCollection<Biome> getVanilla() {
|
|
||||||
return vanilla;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoiseSampler getNoiseEquation() {
|
|
||||||
return noiseEquation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getElevationWeight() {
|
|
||||||
return elevationWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBlendStep() {
|
|
||||||
return blendStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Double> getVariables() {
|
|
||||||
return variables;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validate() throws ValidationException {
|
public boolean validate() throws ValidationException {
|
||||||
color |= 0xff000000; // Alpha adjustment
|
color |= 0xff000000; // Alpha adjustment
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getExtended() {
|
||||||
|
return extended;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getColors() {
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBlendWeight() {
|
||||||
|
return blendWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlendDistance() {
|
||||||
|
return blendDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSlabThreshold() {
|
||||||
|
return slabThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<BlockType, Palette> getSlabPalettes() {
|
||||||
|
return slabPalettes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<BlockType, Palette> getStairPalettes() {
|
||||||
|
return stairPalettes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSampler getBiomeNoise() {
|
||||||
|
return biomeNoise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSampler getElevationEquation() {
|
||||||
|
return elevationEquation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSampler getCarvingEquation() {
|
||||||
|
return carvingEquation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigPack getPack() {
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSeaLevel() {
|
||||||
|
return seaLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProbabilityCollection<Biome> getVanilla() {
|
||||||
|
return vanilla;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoiseSampler getNoiseEquation() {
|
||||||
|
return noiseEquation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getElevationWeight() {
|
||||||
|
return elevationWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlendStep() {
|
||||||
|
return blendStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Double> getVariables() {
|
||||||
|
return variables;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,23 +3,24 @@ package com.dfsek.terra.addons.biome;
|
|||||||
|
|
||||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||||
|
|
||||||
|
|
||||||
public class BlankFunction implements DynamicFunction {
|
public class BlankFunction implements DynamicFunction {
|
||||||
private final int args;
|
private final int args;
|
||||||
|
|
||||||
public BlankFunction(int args) {
|
public BlankFunction(int args) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getArgNumber() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double eval(double... d) {
|
public double eval(double... d) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getArgNumber() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStateless() {
|
public boolean isStateless() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -4,13 +4,14 @@ import com.dfsek.terra.addons.biome.holder.PaletteHolder;
|
|||||||
import com.dfsek.terra.api.world.biome.PaletteSettings;
|
import com.dfsek.terra.api.world.biome.PaletteSettings;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteSettingsImpl implements PaletteSettings {
|
public class PaletteSettingsImpl implements PaletteSettings {
|
||||||
private final PaletteHolder palette;
|
private final PaletteHolder palette;
|
||||||
|
|
||||||
public PaletteSettingsImpl(PaletteHolder palette) {
|
public PaletteSettingsImpl(PaletteHolder palette) {
|
||||||
this.palette = palette;
|
this.palette = palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Palette getPalette(int y) {
|
public Palette getPalette(int y) {
|
||||||
return palette.getPalette(y);
|
return palette.getPalette(y);
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package com.dfsek.terra.addons.biome;
|
package com.dfsek.terra.addons.biome;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.dfsek.terra.api.properties.Context;
|
import com.dfsek.terra.api.properties.Context;
|
||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.world.biome.Biome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing a config-defined biome
|
* Class representing a config-defined biome
|
||||||
@ -18,9 +19,9 @@ public class UserDefinedBiome implements TerraBiome {
|
|||||||
private final BiomeTemplate config;
|
private final BiomeTemplate config;
|
||||||
private final int color;
|
private final int color;
|
||||||
private final Set<String> tags;
|
private final Set<String> tags;
|
||||||
|
|
||||||
private final Context context = new Context();
|
private final Context context = new Context();
|
||||||
|
|
||||||
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, UserDefinedGenerationSettings gen, BiomeTemplate config) {
|
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, UserDefinedGenerationSettings gen, BiomeTemplate config) {
|
||||||
this.vanilla = vanilla;
|
this.vanilla = vanilla;
|
||||||
this.gen = gen;
|
this.gen = gen;
|
||||||
@ -30,7 +31,12 @@ public class UserDefinedBiome implements TerraBiome {
|
|||||||
this.tags = config.getTags();
|
this.tags = config.getTags();
|
||||||
tags.add("BIOME:" + id);
|
tags.add("BIOME:" + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{BIOME:" + getID() + "}";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Vanilla biomes to represent the custom biome.
|
* Gets the Vanilla biomes to represent the custom biome.
|
||||||
*
|
*
|
||||||
@ -40,36 +46,31 @@ public class UserDefinedBiome implements TerraBiome {
|
|||||||
public ProbabilityCollection<Biome> getVanillaBiomes() {
|
public ProbabilityCollection<Biome> getVanillaBiomes() {
|
||||||
return vanilla;
|
return vanilla;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getID() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BiomeTemplate getConfig() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenerationSettings getGenerator() {
|
public GenerationSettings getGenerator() {
|
||||||
return gen;
|
return gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColor() {
|
public int getColor() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getTags() {
|
public Set<String> getTags() {
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String getID() {
|
||||||
return "{BIOME:" + getID() + "}";
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BiomeTemplate getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
return context;
|
return context;
|
||||||
|
@ -3,65 +3,67 @@ package com.dfsek.terra.addons.biome;
|
|||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
import com.dfsek.terra.api.world.biome.GenerationSettings;
|
||||||
|
|
||||||
public class UserDefinedGenerationSettings implements GenerationSettings {
|
|
||||||
|
|
||||||
|
public class UserDefinedGenerationSettings implements GenerationSettings {
|
||||||
|
|
||||||
private final NoiseSampler noise;
|
private final NoiseSampler noise;
|
||||||
private final NoiseSampler elevation;
|
private final NoiseSampler elevation;
|
||||||
private final NoiseSampler carving;
|
private final NoiseSampler carving;
|
||||||
|
|
||||||
private final NoiseSampler biomeNoise;
|
private final NoiseSampler biomeNoise;
|
||||||
private final double elevationWeight;
|
private final double elevationWeight;
|
||||||
private final int blendDistance;
|
private final int blendDistance;
|
||||||
private final int blendStep;
|
private final int blendStep;
|
||||||
private final double blendWeight;
|
private final double blendWeight;
|
||||||
|
|
||||||
public UserDefinedGenerationSettings(NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise, double elevationWeight, int blendDistance, int blendStep, double blendWeight) {
|
public UserDefinedGenerationSettings(NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise,
|
||||||
|
double elevationWeight, int blendDistance, int blendStep, double blendWeight) {
|
||||||
this.noise = noise;
|
this.noise = noise;
|
||||||
this.elevation = elevation;
|
this.elevation = elevation;
|
||||||
this.carving = carving;
|
this.carving = carving;
|
||||||
|
|
||||||
this.biomeNoise = biomeNoise;
|
this.biomeNoise = biomeNoise;
|
||||||
this.elevationWeight = elevationWeight;
|
this.elevationWeight = elevationWeight;
|
||||||
this.blendDistance = blendDistance;
|
this.blendDistance = blendDistance;
|
||||||
this.blendStep = blendStep;
|
this.blendStep = blendStep;
|
||||||
this.blendWeight = blendWeight;
|
this.blendWeight = blendWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler getBaseSampler() {
|
public NoiseSampler getBaseSampler() {
|
||||||
return noise;
|
return noise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler getElevationSampler() {
|
public NoiseSampler getElevationSampler() {
|
||||||
return elevation;
|
return elevation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler getCarver() {
|
public NoiseSampler getCarver() {
|
||||||
return carving;
|
return carving;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlendDistance() {
|
public int getBlendDistance() {
|
||||||
return blendDistance;
|
return blendDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getWeight() {
|
public double getWeight() {
|
||||||
return blendWeight;
|
return blendWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler getBiomeNoise() {
|
public NoiseSampler getBiomeNoise() {
|
||||||
return biomeNoise;
|
return biomeNoise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getElevationWeight() {
|
public double getElevationWeight() {
|
||||||
return elevationWeight;
|
return elevationWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlendStep() {
|
public int getBlendStep() {
|
||||||
return blendStep;
|
return blendStep;
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
package com.dfsek.terra.addons.biome.command.biome;
|
package com.dfsek.terra.addons.biome.command.biome;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runnable that locates a biome asynchronously
|
* Runnable that locates a biome asynchronously
|
||||||
*/
|
*/
|
||||||
public class AsyncBiomeFinder implements Runnable {
|
public class AsyncBiomeFinder implements Runnable {
|
||||||
|
|
||||||
protected final BiomeProvider provider;
|
protected final BiomeProvider provider;
|
||||||
protected final TerraBiome target;
|
protected final TerraBiome target;
|
||||||
protected final int startRadius;
|
protected final int startRadius;
|
||||||
@ -24,8 +26,9 @@ public class AsyncBiomeFinder implements Runnable {
|
|||||||
protected final TerraPlugin main;
|
protected final TerraPlugin main;
|
||||||
private final Consumer<Vector3> callback;
|
private final Consumer<Vector3> callback;
|
||||||
protected int searchSize = 1;
|
protected int searchSize = 1;
|
||||||
|
|
||||||
public AsyncBiomeFinder(BiomeProvider provider, TerraBiome target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
public AsyncBiomeFinder(BiomeProvider provider, TerraBiome target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius,
|
||||||
|
Consumer<Vector3> callback, TerraPlugin main) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.main = main;
|
this.main = main;
|
||||||
@ -36,35 +39,23 @@ public class AsyncBiomeFinder implements Runnable {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to get biome at location
|
|
||||||
*
|
|
||||||
* @param x X coordinate
|
|
||||||
* @param z Z coordinate
|
|
||||||
* @return TerraBiome at coordinates
|
|
||||||
*/
|
|
||||||
public boolean isValid(int x, int z, TerraBiome target) {
|
|
||||||
int res = main.getTerraConfig().getBiomeSearchResolution();
|
|
||||||
return getProvider().getBiome(x * res, z * res, world.getSeed()).equals(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3 finalizeVector(Vector3 orig) {
|
public Vector3 finalizeVector(Vector3 orig) {
|
||||||
return orig.multiply(main.getTerraConfig().getBiomeSearchResolution());
|
return orig.multiply(main.getTerraConfig().getBiomeSearchResolution());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int x = centerX;
|
int x = centerX;
|
||||||
int z = centerZ;
|
int z = centerZ;
|
||||||
|
|
||||||
x /= searchSize;
|
x /= searchSize;
|
||||||
z /= searchSize;
|
z /= searchSize;
|
||||||
|
|
||||||
int run = 1;
|
int run = 1;
|
||||||
boolean toggle = true;
|
boolean toggle = true;
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
||||||
main:
|
main:
|
||||||
for(int i = startRadius; i < maxRadius; i++) {
|
for(int i = startRadius; i < maxRadius; i++) {
|
||||||
for(int j = 0; j < run; j++) {
|
for(int j = 0; j < run; j++) {
|
||||||
@ -89,23 +80,36 @@ public class AsyncBiomeFinder implements Runnable {
|
|||||||
Vector3 finalSpawn = found ? finalizeVector(new Vector3(x, 0, z)) : null;
|
Vector3 finalSpawn = found ? finalizeVector(new Vector3(x, 0, z)) : null;
|
||||||
callback.accept(finalSpawn);
|
callback.accept(finalSpawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get biome at location
|
||||||
|
*
|
||||||
|
* @param x X coordinate
|
||||||
|
* @param z Z coordinate
|
||||||
|
*
|
||||||
|
* @return TerraBiome at coordinates
|
||||||
|
*/
|
||||||
|
public boolean isValid(int x, int z, TerraBiome target) {
|
||||||
|
int res = main.getTerraConfig().getBiomeSearchResolution();
|
||||||
|
return getProvider().getBiome(x * res, z * res, world.getSeed()).equals(target);
|
||||||
|
}
|
||||||
|
|
||||||
public TerraBiome getTarget() {
|
public TerraBiome getTarget() {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BiomeProvider getProvider() {
|
public BiomeProvider getProvider() {
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSearchSize() {
|
public int getSearchSize() {
|
||||||
return searchSize;
|
return searchSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSearchSize(int searchSize) {
|
public void setSearchSize(int searchSize) {
|
||||||
this.searchSize = searchSize;
|
this.searchSize = searchSize;
|
||||||
}
|
}
|
||||||
|
@ -12,18 +12,11 @@ import com.dfsek.terra.api.entity.Player;
|
|||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
subcommands = {
|
subcommands = {
|
||||||
@Subcommand(
|
@Subcommand(value = "info", aliases = "i", clazz = BiomeInfoCommand.class),
|
||||||
value = "info",
|
@Subcommand(value = "locate", aliases = "l", clazz = BiomeLocateCommand.class)
|
||||||
aliases = {"i"},
|
|
||||||
clazz = BiomeInfoCommand.class
|
|
||||||
),
|
|
||||||
@Subcommand(
|
|
||||||
value = "locate",
|
|
||||||
aliases = {"l"},
|
|
||||||
clazz = BiomeLocateCommand.class
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
usage = "/terra biome"
|
usage = "/terra biome"
|
||||||
)
|
)
|
||||||
@ -32,11 +25,11 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
|||||||
public class BiomeCommand implements CommandTemplate {
|
public class BiomeCommand implements CommandTemplate {
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender) {
|
public void execute(CommandSender sender) {
|
||||||
Player player = (Player) sender;
|
Player player = (Player) sender;
|
||||||
|
|
||||||
BiomeProvider provider = player.world().getBiomeProvider();
|
BiomeProvider provider = player.world().getBiomeProvider();
|
||||||
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position(), player.world().getSeed());
|
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position(), player.world().getSeed());
|
||||||
sender.sendMessage("You are standing in " + biome.getID());
|
sender.sendMessage("You are standing in " + biome.getID());
|
||||||
|
@ -11,27 +11,24 @@ import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
|
|||||||
import com.dfsek.terra.api.entity.CommandSender;
|
import com.dfsek.terra.api.entity.CommandSender;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
@Command(
|
|
||||||
arguments = {
|
@Command(arguments = @Argument(
|
||||||
@Argument(
|
value = "biome",
|
||||||
value = "biome",
|
tabCompleter = BiomeTabCompleter.class,
|
||||||
tabCompleter = BiomeTabCompleter.class,
|
argumentParser = BiomeArgumentParser.class
|
||||||
argumentParser = BiomeArgumentParser.class
|
))
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class BiomeInfoCommand implements CommandTemplate {
|
public class BiomeInfoCommand implements CommandTemplate {
|
||||||
@ArgumentTarget("biome")
|
@ArgumentTarget("biome")
|
||||||
private TerraBiome biome;
|
private TerraBiome biome;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender) {
|
public void execute(CommandSender sender) {
|
||||||
sender.sendMessage("Biome info for \"" + biome.getID() + "\".");
|
sender.sendMessage("Biome info for \"" + biome.getID() + "\".");
|
||||||
sender.sendMessage("Vanilla biome: " + biome.getVanillaBiomes());
|
sender.sendMessage("Vanilla biome: " + biome.getVanillaBiomes());
|
||||||
|
|
||||||
if(biome instanceof UserDefinedBiome) {
|
if(biome instanceof UserDefinedBiome) {
|
||||||
BiomeTemplate bio = ((UserDefinedBiome) biome).getConfig();
|
BiomeTemplate bio = ((UserDefinedBiome) biome).getConfig();
|
||||||
|
|
||||||
if(bio.getExtended().size() == 0) {
|
if(bio.getExtended().size() == 0) {
|
||||||
sender.sendMessage("No Parent Biomes");
|
sender.sendMessage("No Parent Biomes");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.dfsek.terra.addons.biome.command.biome;
|
package com.dfsek.terra.addons.biome.command.biome;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.biome.command.biome.arg.BiomeArgumentParser;
|
import com.dfsek.terra.addons.biome.command.biome.arg.BiomeArgumentParser;
|
||||||
import com.dfsek.terra.addons.biome.command.biome.tab.BiomeTabCompleter;
|
import com.dfsek.terra.addons.biome.command.biome.tab.BiomeTabCompleter;
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
@ -18,58 +20,58 @@ import com.dfsek.terra.api.injection.annotations.Inject;
|
|||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
@PlayerCommand
|
@PlayerCommand
|
||||||
@WorldCommand
|
@WorldCommand
|
||||||
@Command(
|
@Command(arguments = {
|
||||||
arguments = {
|
@Argument(
|
||||||
@Argument(
|
value = "biome",
|
||||||
value = "biome",
|
tabCompleter = BiomeTabCompleter.class,
|
||||||
tabCompleter = BiomeTabCompleter.class,
|
argumentParser = BiomeArgumentParser.class
|
||||||
argumentParser = BiomeArgumentParser.class
|
),
|
||||||
),
|
@Argument(
|
||||||
@Argument(
|
value = "radius",
|
||||||
value = "radius",
|
required = false,
|
||||||
required = false,
|
defaultValue = "1000",
|
||||||
defaultValue = "1000",
|
argumentParser = IntegerArgumentParser.class
|
||||||
argumentParser = IntegerArgumentParser.class
|
)
|
||||||
)
|
}, switches = @Switch(
|
||||||
},
|
value = "teleport",
|
||||||
switches = {
|
aliases = { "t", "tp" }
|
||||||
@Switch(
|
))
|
||||||
value = "teleport",
|
|
||||||
aliases = {"t", "tp"}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public class BiomeLocateCommand implements CommandTemplate {
|
public class BiomeLocateCommand implements CommandTemplate {
|
||||||
|
|
||||||
@ArgumentTarget("radius")
|
@ArgumentTarget("radius")
|
||||||
private Integer radius;
|
private Integer radius;
|
||||||
|
|
||||||
@ArgumentTarget("biome")
|
@ArgumentTarget("biome")
|
||||||
private TerraBiome biome;
|
private TerraBiome biome;
|
||||||
|
|
||||||
@SwitchTarget("teleport")
|
@SwitchTarget("teleport")
|
||||||
private boolean teleport;
|
private boolean teleport;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender) {
|
public void execute(CommandSender sender) {
|
||||||
|
|
||||||
Player player = (Player) sender;
|
Player player = (Player) sender;
|
||||||
|
|
||||||
new Thread(new AsyncBiomeFinder(player.world().getBiomeProvider(), biome, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> {
|
new Thread(new AsyncBiomeFinder(player.world().getBiomeProvider(), biome,
|
||||||
|
player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())),
|
||||||
|
player.world(), 0, radius, location -> {
|
||||||
if(location != null) {
|
if(location != null) {
|
||||||
sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position())));
|
sender.sendMessage(
|
||||||
|
String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT),
|
||||||
|
location.getBlockX(), location.getBlockZ(),
|
||||||
|
location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position())));
|
||||||
if(teleport) {
|
if(teleport) {
|
||||||
main.runPossiblyUnsafeTask(() -> player.position(new Vector3(location.getX(), player.position().getY(), location.getZ())));
|
main.runPossiblyUnsafeTask(
|
||||||
|
() -> player.position(new Vector3(location.getX(), player.position().getY(), location.getZ())));
|
||||||
}
|
}
|
||||||
} else sender.sendMessage("Unable to locate biome \"" + biome.getID() + "\"");
|
} else sender.sendMessage("Unable to locate biome \"" + biome.getID() + "\"");
|
||||||
}, main), "Biome Location Thread").start();
|
}, main), "Biome Location Thread").start();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,11 @@ import com.dfsek.terra.api.entity.Player;
|
|||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
|
|
||||||
public class BiomeArgumentParser implements ArgumentParser<TerraBiome> {
|
public class BiomeArgumentParser implements ArgumentParser<TerraBiome> {
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TerraBiome parse(CommandSender sender, String arg) {
|
public TerraBiome parse(CommandSender sender, String arg) {
|
||||||
Player player = (Player) sender;
|
Player player = (Player) sender;
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.dfsek.terra.addons.biome.command.biome.tab;
|
package com.dfsek.terra.addons.biome.command.biome.tab;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.command.tab.TabCompleter;
|
import com.dfsek.terra.api.command.tab.TabCompleter;
|
||||||
import com.dfsek.terra.api.entity.CommandSender;
|
import com.dfsek.terra.api.entity.CommandSender;
|
||||||
@ -7,16 +10,15 @@ import com.dfsek.terra.api.entity.Player;
|
|||||||
import com.dfsek.terra.api.injection.annotations.Inject;
|
import com.dfsek.terra.api.injection.annotations.Inject;
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class BiomeTabCompleter implements TabCompleter {
|
public class BiomeTabCompleter implements TabCompleter {
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> complete(CommandSender sender) {
|
public List<String> complete(CommandSender sender) {
|
||||||
Player player = (Player) sender;
|
Player player = (Player) sender;
|
||||||
return player.world().getConfig().getRegistry(TerraBiome.class).entries().stream().map(TerraBiome::getID).collect(Collectors.toList());
|
return player.world().getConfig().getRegistry(TerraBiome.class).entries().stream().map(TerraBiome::getID).collect(
|
||||||
|
Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,22 @@ package com.dfsek.terra.addons.biome.holder;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteHolder {
|
public class PaletteHolder {
|
||||||
private final Palette[] palettes;
|
private final Palette[] palettes;
|
||||||
private final int offset;
|
private final int offset;
|
||||||
|
|
||||||
protected PaletteHolder(Palette[] palettes, int offset) {
|
protected PaletteHolder(Palette[] palettes, int offset) {
|
||||||
this.palettes = palettes;
|
this.palettes = palettes;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Palette getPalette(int y) {
|
public Palette getPalette(int y) {
|
||||||
int index = y + offset;
|
int index = y + offset;
|
||||||
return index >= 0
|
return index >= 0
|
||||||
? index < palettes.length
|
? index < palettes.length
|
||||||
? palettes[index]
|
? palettes[index]
|
||||||
: palettes[palettes.length - 1]
|
: palettes[palettes.length - 1]
|
||||||
: palettes[0];
|
: palettes[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
package com.dfsek.terra.addons.biome.holder;
|
package com.dfsek.terra.addons.biome.holder;
|
||||||
|
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteHolderBuilder {
|
public class PaletteHolderBuilder {
|
||||||
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
||||||
|
|
||||||
public PaletteHolderBuilder add(int y, Palette palette) {
|
public PaletteHolderBuilder add(int y, Palette palette) {
|
||||||
paletteMap.put(y, palette);
|
paletteMap.put(y, palette);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaletteHolder build() {
|
public PaletteHolder build() {
|
||||||
|
|
||||||
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
||||||
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
||||||
|
|
||||||
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
|
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
|
||||||
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
|
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
|
||||||
Palette d = null;
|
Palette d = null;
|
||||||
|
@ -3,13 +3,14 @@ package com.dfsek.terra.addons.biome.holder;
|
|||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
import com.dfsek.terra.api.world.generator.Palette;
|
|
||||||
|
|
||||||
import java.lang.reflect.AnnotatedType;
|
import java.lang.reflect.AnnotatedType;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.generator.Palette;
|
||||||
|
|
||||||
|
|
||||||
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
|
public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
package com.dfsek.terra.addons.carver;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.carver.carving.Worm;
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
|
||||||
import com.dfsek.terra.api.util.PopulationUtil;
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
|
||||||
import com.dfsek.terra.api.world.World;
|
|
||||||
import com.dfsek.terra.api.world.biome.TerraBiome;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
@ -18,43 +10,60 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class CarverCache {
|
import com.dfsek.terra.addons.carver.carving.Worm;
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
import com.dfsek.terra.api.util.PopulationUtil;
|
||||||
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
|
import com.dfsek.terra.api.world.World;
|
||||||
|
import com.dfsek.terra.api.world.biome.TerraBiome;
|
||||||
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public class CarverCache {
|
||||||
|
|
||||||
private final LoadingCache<Long, List<Worm.WormPoint>> cache;
|
private final LoadingCache<Long, List<Worm.WormPoint>> cache;
|
||||||
private final UserDefinedCarver carver;
|
private final UserDefinedCarver carver;
|
||||||
|
|
||||||
public CarverCache(World w, TerraPlugin main, UserDefinedCarver carver) {
|
public CarverCache(World w, TerraPlugin main, UserDefinedCarver carver) {
|
||||||
this.carver = carver;
|
this.carver = carver;
|
||||||
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getCarverCacheSize())
|
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getCarverCacheSize())
|
||||||
.build(new CacheLoader<>() {
|
.build(new CacheLoader<>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Worm.WormPoint> load(@NotNull Long key) {
|
public List<Worm.WormPoint> load(@NotNull Long key) {
|
||||||
int chunkX = (int) (key >> 32);
|
int chunkX = (int) (key >> 32);
|
||||||
int chunkZ = (int) key.longValue();
|
int chunkZ = (int) key.longValue();
|
||||||
BiomeProvider provider = w.getBiomeProvider();
|
BiomeProvider provider = w.getBiomeProvider();
|
||||||
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new Random(PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) {
|
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new Random(
|
||||||
long seed = PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
PopulationUtil.getCarverChunkSeed(chunkX, chunkZ,
|
||||||
Random r = new Random(seed);
|
w.getSeed() + CarverCache.this.carver.hashCode())))) {
|
||||||
Worm carving = CarverCache.this.carver.getWorm(seed, new Vector3((chunkX << 4) + r.nextInt(16), CarverCache.this.carver.getConfig().getHeight().get(r), (chunkZ << 4) + r.nextInt(16)));
|
long seed = PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
|
||||||
List<Worm.WormPoint> points = new ArrayList<>();
|
Random r = new Random(seed);
|
||||||
for(int i = 0; i < carving.getLength(); i++) {
|
Worm carving = CarverCache.this.carver.getWorm(seed, new Vector3((chunkX << 4) + r.nextInt(16),
|
||||||
carving.step();
|
CarverCache.this.carver.getConfig()
|
||||||
TerraBiome biome = provider.getBiome(carving.getRunning(), w.getSeed());
|
.getHeight()
|
||||||
|
.get(r),
|
||||||
|
(chunkZ << 4) + r.nextInt(16)));
|
||||||
|
List<Worm.WormPoint> points = new ArrayList<>();
|
||||||
|
for(int i = 0; i < carving.getLength(); i++) {
|
||||||
|
carving.step();
|
||||||
|
TerraBiome biome = provider.getBiome(carving.getRunning(), w.getSeed());
|
||||||
/*
|
/*
|
||||||
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop if we enter a biome this carver is not present in
|
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop
|
||||||
|
if we enter a biome this carver is not present in
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
points.add(carving.getPoint());
|
points.add(carving.getPoint());
|
||||||
}
|
}
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Worm.WormPoint> getPoints(int chunkX, int chunkZ) {
|
public List<Worm.WormPoint> getPoints(int chunkX, int chunkZ) {
|
||||||
return cache.getUnchecked(MathUtil.squash(chunkX, chunkZ));
|
return cache.getUnchecked(MathUtil.squash(chunkX, chunkZ));
|
||||||
}
|
}
|
||||||
|
@ -3,30 +3,33 @@ package com.dfsek.terra.addons.carver;
|
|||||||
import com.dfsek.paralithic.eval.parser.Scope;
|
import com.dfsek.paralithic.eval.parser.Scope;
|
||||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
import com.dfsek.tectonic.exception.LoadException;
|
import com.dfsek.tectonic.exception.LoadException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.config.ConfigFactory;
|
import com.dfsek.terra.api.config.ConfigFactory;
|
||||||
import com.dfsek.terra.api.config.ConfigPack;
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CarverFactory implements ConfigFactory<CarverTemplate, UserDefinedCarver> {
|
public class CarverFactory implements ConfigFactory<CarverTemplate, UserDefinedCarver> {
|
||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
|
|
||||||
public CarverFactory(ConfigPack pack) {
|
public CarverFactory(ConfigPack pack) {
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDefinedCarver build(CarverTemplate config, TerraPlugin main) throws LoadException {
|
public UserDefinedCarver build(CarverTemplate config, TerraPlugin main) throws LoadException {
|
||||||
double[] start = new double[] {config.getStartX(), config.getStartY(), config.getStartZ()};
|
double[] start = { config.getStartX(), config.getStartY(), config.getStartZ() };
|
||||||
double[] mutate = new double[] {config.getMutateX(), config.getMutateY(), config.getMutateZ()};
|
double[] mutate = { config.getMutateX(), config.getMutateY(), config.getMutateZ() };
|
||||||
List<String> radius = Arrays.asList(config.getRadMX(), config.getRadMY(), config.getRadMZ());
|
List<String> radius = Arrays.asList(config.getRadMX(), config.getRadMY(), config.getRadMZ());
|
||||||
long hash = MathUtil.hashToLong(config.getID());
|
long hash = MathUtil.hashToLong(config.getID());
|
||||||
UserDefinedCarver carver;
|
UserDefinedCarver carver;
|
||||||
try {
|
try {
|
||||||
carver = new UserDefinedCarver(config.getHeight(), config.getLength(), start, mutate, radius, new Scope(), hash, config.getCutTop(), config.getCutBottom(), config, main);
|
carver = new UserDefinedCarver(config.getHeight(), config.getLength(), start, mutate, radius, new Scope(), hash,
|
||||||
|
config.getCutTop(), config.getCutBottom(), config, main);
|
||||||
} catch(ParseException e) {
|
} catch(ParseException e) {
|
||||||
throw new LoadException("Unable to parse radius equations", e);
|
throw new LoadException("Unable to parse radius equations", e);
|
||||||
}
|
}
|
||||||
|
@ -1,52 +1,54 @@
|
|||||||
package com.dfsek.terra.addons.carver;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
|
||||||
import com.dfsek.terra.api.block.state.BlockState;
|
|
||||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
|
||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
|
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||||
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes", "RedundantSuppression" })
|
||||||
public class CarverPalette {
|
public class CarverPalette {
|
||||||
private final boolean blacklist;
|
private final boolean blacklist;
|
||||||
private final MaterialSet replace;
|
private final MaterialSet replace;
|
||||||
private final TreeMap<Integer, ProbabilityCollection<BlockState>> map = new TreeMap<>();
|
private final TreeMap<Integer, ProbabilityCollection<BlockState>> map = new TreeMap<>();
|
||||||
private ProbabilityCollection<BlockState>[] layers;
|
private ProbabilityCollection<BlockState>[] layers;
|
||||||
private int offset = 0;
|
private int offset = 0;
|
||||||
|
|
||||||
public CarverPalette(MaterialSet replaceable, boolean blacklist) {
|
public CarverPalette(MaterialSet replaceable, boolean blacklist) {
|
||||||
this.blacklist = blacklist;
|
this.blacklist = blacklist;
|
||||||
this.replace = replaceable;
|
this.replace = replaceable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarverPalette add(ProbabilityCollection<BlockState> collection, int y) {
|
public CarverPalette add(ProbabilityCollection<BlockState> collection, int y) {
|
||||||
map.put(y, collection);
|
map.put(y, collection);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProbabilityCollection<BlockState> get(int y) {
|
public ProbabilityCollection<BlockState> get(int y) {
|
||||||
int index = y + offset;
|
int index = y + offset;
|
||||||
return index >= 0
|
return index >= 0
|
||||||
? index < layers.length
|
? index < layers.length
|
||||||
? layers[index]
|
? layers[index]
|
||||||
: layers[layers.length - 1]
|
: layers[layers.length - 1]
|
||||||
: layers[0];
|
: layers[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canReplace(BlockType material) {
|
public boolean canReplace(BlockType material) {
|
||||||
return blacklist != replace.contains(material);
|
return blacklist != replace.contains(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the palette to an array.
|
* Build the palette to an array.
|
||||||
*/
|
*/
|
||||||
public void build() {
|
public void build() {
|
||||||
int min = FastMath.min(map.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
int min = FastMath.min(map.keySet().stream().min(Integer::compareTo).orElse(0), 0);
|
||||||
int max = FastMath.max(map.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
int max = FastMath.max(map.keySet().stream().max(Integer::compareTo).orElse(255), 255);
|
||||||
|
|
||||||
layers = new ProbabilityCollection[map.lastKey() + 1 - min];
|
layers = new ProbabilityCollection[map.lastKey() + 1 - min];
|
||||||
for(int y = min; y <= FastMath.max(map.lastKey(), max); y++) {
|
for(int y = min; y <= FastMath.max(map.lastKey(), max); y++) {
|
||||||
ProbabilityCollection<BlockState> d = null;
|
ProbabilityCollection<BlockState> d = null;
|
||||||
|
@ -4,6 +4,10 @@ package com.dfsek.terra.addons.carver;
|
|||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Final;
|
import com.dfsek.tectonic.annotations.Final;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
import com.dfsek.terra.api.config.AbstractableTemplate;
|
import com.dfsek.terra.api.config.AbstractableTemplate;
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
@ -11,176 +15,174 @@ import com.dfsek.terra.api.util.ConstantRange;
|
|||||||
import com.dfsek.terra.api.util.Range;
|
import com.dfsek.terra.api.util.Range;
|
||||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "FieldMayBeFinal"})
|
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
|
||||||
public class CarverTemplate implements AbstractableTemplate {
|
public class CarverTemplate implements AbstractableTemplate {
|
||||||
@Value("id")
|
@Value("id")
|
||||||
@Final
|
@Final
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@Value("step")
|
@Value("step")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int step = 2;
|
private @Meta int step = 2;
|
||||||
|
|
||||||
@Value("recalculate-magnitude")
|
@Value("recalculate-magnitude")
|
||||||
@Default
|
@Default
|
||||||
private @Meta double recaclulateMagnitude = 4;
|
private @Meta double recaclulateMagnitude = 4;
|
||||||
|
|
||||||
@Value("recalculate-direction")
|
@Value("recalculate-direction")
|
||||||
@Default
|
@Default
|
||||||
private @Meta Range recalc = new ConstantRange(8, 10);
|
private @Meta Range recalc = new ConstantRange(8, 10);
|
||||||
|
|
||||||
@Value("length")
|
@Value("length")
|
||||||
private @Meta Range length;
|
private @Meta Range length;
|
||||||
|
|
||||||
@Value("start.x")
|
@Value("start.x")
|
||||||
private @Meta double startX;
|
private @Meta double startX;
|
||||||
|
|
||||||
@Value("start.y")
|
@Value("start.y")
|
||||||
private @Meta double startY;
|
private @Meta double startY;
|
||||||
|
|
||||||
@Value("start.z")
|
@Value("start.z")
|
||||||
private @Meta double startZ;
|
private @Meta double startZ;
|
||||||
|
|
||||||
@Value("start.radius.x")
|
@Value("start.radius.x")
|
||||||
private @Meta String radMX;
|
private @Meta String radMX;
|
||||||
|
|
||||||
@Value("start.radius.y")
|
@Value("start.radius.y")
|
||||||
private @Meta String radMY;
|
private @Meta String radMY;
|
||||||
|
|
||||||
@Value("start.radius.z")
|
@Value("start.radius.z")
|
||||||
private @Meta String radMZ;
|
private @Meta String radMZ;
|
||||||
|
|
||||||
@Value("start.height")
|
@Value("start.height")
|
||||||
private @Meta Range height;
|
private @Meta Range height;
|
||||||
|
|
||||||
@Value("cut.bottom")
|
@Value("cut.bottom")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int cutBottom = 0;
|
private @Meta int cutBottom = 0;
|
||||||
|
|
||||||
@Value("cut.top")
|
@Value("cut.top")
|
||||||
@Default
|
@Default
|
||||||
private @Meta int cutTop = 0;
|
private @Meta int cutTop = 0;
|
||||||
|
|
||||||
@Value("mutate.x")
|
@Value("mutate.x")
|
||||||
private @Meta double mutateX;
|
private @Meta double mutateX;
|
||||||
|
|
||||||
@Value("mutate.y")
|
@Value("mutate.y")
|
||||||
private @Meta double mutateY;
|
private @Meta double mutateY;
|
||||||
|
|
||||||
@Value("mutate.z")
|
@Value("mutate.z")
|
||||||
private @Meta double mutateZ;
|
private @Meta double mutateZ;
|
||||||
|
|
||||||
@Value("palette.top")
|
@Value("palette.top")
|
||||||
private @Meta CarverPalette top;
|
private @Meta CarverPalette top;
|
||||||
|
|
||||||
@Value("palette.bottom")
|
@Value("palette.bottom")
|
||||||
private @Meta CarverPalette bottom;
|
private @Meta CarverPalette bottom;
|
||||||
|
|
||||||
@Value("palette.outer")
|
@Value("palette.outer")
|
||||||
private @Meta CarverPalette outer;
|
private @Meta CarverPalette outer;
|
||||||
|
|
||||||
@Value("palette.inner")
|
@Value("palette.inner")
|
||||||
private @Meta CarverPalette inner;
|
private @Meta CarverPalette inner;
|
||||||
|
|
||||||
@Value("shift")
|
@Value("shift")
|
||||||
@Default
|
@Default
|
||||||
private @Meta Map<@Meta BlockType, @Meta MaterialSet> shift = new HashMap<>();
|
private @Meta Map<@Meta BlockType, @Meta MaterialSet> shift = new HashMap<>();
|
||||||
|
|
||||||
@Value("update")
|
@Value("update")
|
||||||
@Default
|
@Default
|
||||||
private @Meta MaterialSet update = new MaterialSet();
|
private @Meta MaterialSet update = new MaterialSet();
|
||||||
|
|
||||||
public String getID() {
|
public String getID() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStep() {
|
public int getStep() {
|
||||||
return step;
|
return step;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Range getLength() {
|
public Range getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getStartX() {
|
public double getStartX() {
|
||||||
return startX;
|
return startX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getStartY() {
|
public double getStartY() {
|
||||||
return startY;
|
return startY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getStartZ() {
|
public double getStartZ() {
|
||||||
return startZ;
|
return startZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRadMX() {
|
public String getRadMX() {
|
||||||
return radMX;
|
return radMX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRadMY() {
|
public String getRadMY() {
|
||||||
return radMY;
|
return radMY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRadMZ() {
|
public String getRadMZ() {
|
||||||
return radMZ;
|
return radMZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Range getHeight() {
|
public Range getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCutBottom() {
|
public int getCutBottom() {
|
||||||
return cutBottom;
|
return cutBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCutTop() {
|
public int getCutTop() {
|
||||||
return cutTop;
|
return cutTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getMutateX() {
|
public double getMutateX() {
|
||||||
return mutateX;
|
return mutateX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getMutateY() {
|
public double getMutateY() {
|
||||||
return mutateY;
|
return mutateY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getMutateZ() {
|
public double getMutateZ() {
|
||||||
return mutateZ;
|
return mutateZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarverPalette getTop() {
|
public CarverPalette getTop() {
|
||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarverPalette getBottom() {
|
public CarverPalette getBottom() {
|
||||||
return bottom;
|
return bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarverPalette getOuter() {
|
public CarverPalette getOuter() {
|
||||||
return outer;
|
return outer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarverPalette getInner() {
|
public CarverPalette getInner() {
|
||||||
return inner;
|
return inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<BlockType, MaterialSet> getShift() {
|
public Map<BlockType, MaterialSet> getShift() {
|
||||||
return shift;
|
return shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialSet getUpdate() {
|
public MaterialSet getUpdate() {
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Range getRecalc() {
|
public Range getRecalc() {
|
||||||
return recalc;
|
return recalc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getRecaclulateMagnitude() {
|
public double getRecaclulateMagnitude() {
|
||||||
return recaclulateMagnitude;
|
return recaclulateMagnitude;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
package com.dfsek.terra.addons.carver;
|
package com.dfsek.terra.addons.carver;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
import com.dfsek.terra.api.block.state.BlockState;
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
@ -11,20 +17,17 @@ import com.dfsek.terra.api.world.Chunk;
|
|||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.generator.Chunkified;
|
import com.dfsek.terra.api.world.generator.Chunkified;
|
||||||
import com.dfsek.terra.api.world.generator.GenerationStage;
|
import com.dfsek.terra.api.world.generator.GenerationStage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class CavePopulator implements GenerationStage, Chunkified {
|
public class CavePopulator implements GenerationStage, Chunkified {
|
||||||
private static final Map<BlockType, BlockState> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
|
private static final Map<BlockType, BlockState> shiftStorage = new HashMap<>();
|
||||||
|
// Persist BlockData created for shifts, to avoid re-calculating each time.
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
|
|
||||||
public CavePopulator(TerraPlugin main) {
|
public CavePopulator(TerraPlugin main) {
|
||||||
this.main = main;
|
this.main = main;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
@Override
|
@Override
|
||||||
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
public void populate(@NotNull World world, @NotNull Chunk chunk) {
|
||||||
@ -32,7 +35,7 @@ public class CavePopulator implements GenerationStage, Chunkified {
|
|||||||
Random random = PopulationUtil.getRandom(chunk);
|
Random random = PopulationUtil.getRandom(chunk);
|
||||||
WorldConfig config = world.getConfig();
|
WorldConfig config = world.getConfig();
|
||||||
if(config.disableCarving()) return;
|
if(config.disableCarving()) return;
|
||||||
|
|
||||||
for(UserDefinedCarver c : config.getRegistry(UserDefinedCarver.class).entries()) {
|
for(UserDefinedCarver c : config.getRegistry(UserDefinedCarver.class).entries()) {
|
||||||
CarverTemplate template = c.getConfig();
|
CarverTemplate template = c.getConfig();
|
||||||
Map<Vector3, BlockState> shiftCandidate = new HashMap<>();
|
Map<Vector3, BlockState> shiftCandidate = new HashMap<>();
|
||||||
@ -43,25 +46,29 @@ public class CavePopulator implements GenerationStage, Chunkified {
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case CENTER:
|
case CENTER:
|
||||||
if(template.getInner().canReplace(re)) {
|
if(template.getInner().canReplace(re)) {
|
||||||
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(), template.getInner().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(),
|
||||||
|
template.getInner().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
||||||
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WALL:
|
case WALL:
|
||||||
if(template.getOuter().canReplace(re)) {
|
if(template.getOuter().canReplace(re)) {
|
||||||
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(), template.getOuter().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(),
|
||||||
|
template.getOuter().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
||||||
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOP:
|
case TOP:
|
||||||
if(template.getTop().canReplace(re)) {
|
if(template.getTop().canReplace(re)) {
|
||||||
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(), template.getTop().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(),
|
||||||
|
template.getTop().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
||||||
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOTTOM:
|
case BOTTOM:
|
||||||
if(template.getBottom().canReplace(re)) {
|
if(template.getBottom().canReplace(re)) {
|
||||||
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(), template.getBottom().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(),
|
||||||
|
template.getBottom().get(v.getBlockY()).get(random), template.getUpdate().contains(re));
|
||||||
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
if(template.getShift().containsKey(re)) shiftCandidate.put(v, m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -73,16 +80,19 @@ public class CavePopulator implements GenerationStage, Chunkified {
|
|||||||
Vector3 mut = l.clone();
|
Vector3 mut = l.clone();
|
||||||
BlockState orig = chunk.getBlock(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
BlockState orig = chunk.getBlock(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
||||||
do mut.subtract(0, 1, 0);
|
do mut.subtract(0, 1, 0);
|
||||||
while(mut.getY() > world.getMinHeight() && chunk.getBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ()).matches(orig));
|
while(mut.getY() > world.getMinHeight() && chunk.getBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ()).matches(
|
||||||
|
orig));
|
||||||
try {
|
try {
|
||||||
if(template.getShift().get(entry.getValue().getBlockType()).contains(chunk.getBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ()).getBlockType())) {
|
if(template.getShift().get(entry.getValue().getBlockType()).contains(
|
||||||
chunk.setBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ(), shiftStorage.computeIfAbsent(entry.getValue().getBlockType(), BlockType::getDefaultData), false);
|
chunk.getBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ()).getBlockType())) {
|
||||||
|
chunk.setBlock(mut.getBlockX(), mut.getBlockY(), mut.getBlockZ(),
|
||||||
|
shiftStorage.computeIfAbsent(entry.getValue().getBlockType(), BlockType::getDefaultData), false);
|
||||||
}
|
}
|
||||||
} catch(NullPointerException ignored) {
|
} catch(NullPointerException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,6 @@ import com.dfsek.paralithic.Expression;
|
|||||||
import com.dfsek.paralithic.eval.parser.Parser;
|
import com.dfsek.paralithic.eval.parser.Parser;
|
||||||
import com.dfsek.paralithic.eval.parser.Scope;
|
import com.dfsek.paralithic.eval.parser.Scope;
|
||||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
import com.dfsek.terra.addons.carver.carving.Carver;
|
|
||||||
import com.dfsek.terra.addons.carver.carving.Worm;
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
|
||||||
import com.dfsek.terra.api.util.ConstantRange;
|
|
||||||
import com.dfsek.terra.api.util.Range;
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
|
||||||
import com.dfsek.terra.api.world.World;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -19,6 +12,15 @@ import java.util.Random;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.carver.carving.Carver;
|
||||||
|
import com.dfsek.terra.addons.carver.carving.Worm;
|
||||||
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
|
import com.dfsek.terra.api.util.ConstantRange;
|
||||||
|
import com.dfsek.terra.api.util.Range;
|
||||||
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
|
import com.dfsek.terra.api.world.World;
|
||||||
|
|
||||||
|
|
||||||
public class UserDefinedCarver extends Carver {
|
public class UserDefinedCarver extends Carver {
|
||||||
private final double[] start; // 0, 1, 2 = x, y, z.
|
private final double[] start; // 0, 1, 2 = x, y, z.
|
||||||
private final double[] mutate; // 0, 1, 2 = x, y, z. 3 = radius.
|
private final double[] mutate; // 0, 1, 2 = x, y, z. 3 = radius.
|
||||||
@ -30,14 +32,15 @@ public class UserDefinedCarver extends Carver {
|
|||||||
private final Expression xRad;
|
private final Expression xRad;
|
||||||
private final Expression yRad;
|
private final Expression yRad;
|
||||||
private final Expression zRad;
|
private final Expression zRad;
|
||||||
|
|
||||||
private final Map<Long, CarverCache> cacheMap = new ConcurrentHashMap<>();
|
private final Map<Long, CarverCache> cacheMap = new ConcurrentHashMap<>();
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
private double step = 2;
|
private double step = 2;
|
||||||
private Range recalc = new ConstantRange(8, 10);
|
private Range recalc = new ConstantRange(8, 10);
|
||||||
private double recalcMagnitude = 3;
|
private double recalcMagnitude = 3;
|
||||||
|
|
||||||
public UserDefinedCarver(Range height, Range length, double[] start, double[] mutate, List<String> radii, Scope parent, long hash, int topCut, int bottomCut, CarverTemplate config, TerraPlugin main) throws ParseException {
|
public UserDefinedCarver(Range height, Range length, double[] start, double[] mutate, List<String> radii, Scope parent, long hash,
|
||||||
|
int topCut, int bottomCut, CarverTemplate config, TerraPlugin main) throws ParseException {
|
||||||
super(height.getMin(), height.getMax());
|
super(height.getMin(), height.getMax());
|
||||||
this.length = length;
|
this.length = length;
|
||||||
this.start = start;
|
this.start = start;
|
||||||
@ -47,41 +50,27 @@ public class UserDefinedCarver extends Carver {
|
|||||||
this.bottomCut = bottomCut;
|
this.bottomCut = bottomCut;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.main = main;
|
this.main = main;
|
||||||
|
|
||||||
Parser p = new Parser();
|
Parser p = new Parser();
|
||||||
|
|
||||||
Scope s = new Scope().withParent(parent);
|
Scope s = new Scope().withParent(parent);
|
||||||
|
|
||||||
|
|
||||||
s.addInvocationVariable("x");
|
s.addInvocationVariable("x");
|
||||||
s.addInvocationVariable("y");
|
s.addInvocationVariable("y");
|
||||||
s.addInvocationVariable("z");
|
s.addInvocationVariable("z");
|
||||||
|
|
||||||
s.addInvocationVariable("length");
|
s.addInvocationVariable("length");
|
||||||
s.addInvocationVariable("position");
|
s.addInvocationVariable("position");
|
||||||
s.addInvocationVariable("seed");
|
s.addInvocationVariable("seed");
|
||||||
|
|
||||||
|
|
||||||
xRad = p.parse(radii.get(0), s);
|
xRad = p.parse(radii.get(0), s);
|
||||||
yRad = p.parse(radii.get(1), s);
|
yRad = p.parse(radii.get(1), s);
|
||||||
zRad = p.parse(radii.get(2), s);
|
zRad = p.parse(radii.get(2), s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Worm getWorm(long l, Vector3 vector) {
|
|
||||||
Random r = new Random(l + hash);
|
|
||||||
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStep(double step) {
|
|
||||||
this.step = step;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRecalc(Range recalc) {
|
|
||||||
this.recalc = recalc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector3, CarvingType> consumer) {
|
public void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector3, CarvingType> consumer) {
|
||||||
synchronized(cacheMap) {
|
synchronized(cacheMap) {
|
||||||
@ -91,7 +80,8 @@ public class UserDefinedCarver extends Carver {
|
|||||||
for(int z = chunkZ - carvingRadius; z <= chunkZ + carvingRadius; z++) {
|
for(int z = chunkZ - carvingRadius; z <= chunkZ + carvingRadius; z++) {
|
||||||
cache.getPoints(x, z).forEach(point -> {
|
cache.getPoints(x, z).forEach(point -> {
|
||||||
Vector3 origin = point.getOrigin();
|
Vector3 origin = point.getOrigin();
|
||||||
if(FastMath.floorDiv(origin.getBlockX(), 16) != chunkX && FastMath.floorDiv(origin.getBlockZ(), 16) != chunkZ) // We only want to carve this chunk.
|
if(FastMath.floorDiv(origin.getBlockX(), 16) != chunkX && FastMath.floorDiv(origin.getBlockZ(), 16) !=
|
||||||
|
chunkZ) // We only want to carve this chunk.
|
||||||
return;
|
return;
|
||||||
point.carve(chunkX, chunkZ, consumer, w);
|
point.carve(chunkX, chunkZ, consumer, w);
|
||||||
});
|
});
|
||||||
@ -99,24 +89,39 @@ public class UserDefinedCarver extends Carver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRecalcMagnitude(double recalcMagnitude) {
|
@Override
|
||||||
this.recalcMagnitude = recalcMagnitude;
|
public Worm getWorm(long l, Vector3 vector) {
|
||||||
|
Random r = new Random(l + hash);
|
||||||
|
return new UserDefinedWorm(length.get(r) / 2, r, vector, topCut, bottomCut, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
|
public boolean isChunkCarved(World w, int chunkX, int chunkZ, Random random) {
|
||||||
/*BiomeTemplate conf = ((UserDefinedBiome) main.getWorld(w).getBiomeProvider().getBiome((chunkX << 4) + 8, (chunkZ << 4) + 8)).getConfig();
|
/*BiomeTemplate conf = ((UserDefinedBiome) main.getWorld(w).getBiomeProvider().getBiome((chunkX << 4) + 8, (chunkZ << 4) + 8))
|
||||||
|
.getConfig();
|
||||||
if(conf.getCarvers().get(this) != null) {
|
if(conf.getCarvers().get(this) != null) {
|
||||||
return new Random(random.nextLong() + hash).nextInt(100) < conf.getCarvers().get(this);
|
return new Random(random.nextLong() + hash).nextInt(100) < conf.getCarvers().get(this);
|
||||||
}*/
|
}*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRecalc(Range recalc) {
|
||||||
|
this.recalc = recalc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecalcMagnitude(double recalcMagnitude) {
|
||||||
|
this.recalcMagnitude = recalcMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStep(double step) {
|
||||||
|
this.step = step;
|
||||||
|
}
|
||||||
|
|
||||||
public CarverTemplate getConfig() {
|
public CarverTemplate getConfig() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UserDefinedWorm extends Worm {
|
private class UserDefinedWorm extends Worm {
|
||||||
private final Vector3 direction;
|
private final Vector3 direction;
|
||||||
private final Vector3 origin;
|
private final Vector3 origin;
|
||||||
@ -124,41 +129,44 @@ public class UserDefinedCarver extends Carver {
|
|||||||
private int steps;
|
private int steps;
|
||||||
private int nextDirection = 0;
|
private int nextDirection = 0;
|
||||||
private double[] currentRotation = new double[3];
|
private double[] currentRotation = new double[3];
|
||||||
|
|
||||||
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut, long seed) {
|
public UserDefinedWorm(int length, Random r, Vector3 origin, int topCut, int bottomCut, long seed) {
|
||||||
super(length, r, origin);
|
super(length, r, origin);
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
super.setTopCut(topCut);
|
super.setTopCut(topCut);
|
||||||
super.setBottomCut(bottomCut);
|
super.setBottomCut(bottomCut);
|
||||||
direction = new Vector3((r.nextDouble() - 0.5D) * start[0], (r.nextDouble() - 0.5D) * start[1], (r.nextDouble() - 0.5D) * start[2]).normalize().multiply(step);
|
direction = new Vector3((r.nextDouble() - 0.5D) * start[0], (r.nextDouble() - 0.5D) * start[1],
|
||||||
double[] args = {origin.getX(), origin.getY(), origin.getZ(), length, 0, seed};
|
(r.nextDouble() - 0.5D) * start[2]).normalize().multiply(step);
|
||||||
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
double[] args = { origin.getX(), origin.getY(), origin.getZ(), length, 0, seed };
|
||||||
|
setRadius(new int[]{ (int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args)) });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public WormPoint getPoint() {
|
|
||||||
return new WormPoint(getRunning().clone(), getRadius(), config.getCutTop(), config.getCutBottom());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void step() {
|
public void step() {
|
||||||
if(steps == nextDirection) {
|
if(steps == nextDirection) {
|
||||||
direction.rotateAroundX(FastMath.toRadians((getRandom().nextGaussian()) * mutate[0] * recalcMagnitude));
|
direction.rotateAroundX(FastMath.toRadians((getRandom().nextGaussian()) * mutate[0] * recalcMagnitude));
|
||||||
direction.rotateAroundY(FastMath.toRadians((getRandom().nextGaussian()) * mutate[1] * recalcMagnitude));
|
direction.rotateAroundY(FastMath.toRadians((getRandom().nextGaussian()) * mutate[1] * recalcMagnitude));
|
||||||
direction.rotateAroundZ(FastMath.toRadians((getRandom().nextGaussian()) * mutate[2] * recalcMagnitude));
|
direction.rotateAroundZ(FastMath.toRadians((getRandom().nextGaussian()) * mutate[2] * recalcMagnitude));
|
||||||
currentRotation = new double[] {(getRandom().nextGaussian()) * mutate[0],
|
currentRotation = new double[]{
|
||||||
|
(getRandom().nextGaussian()) * mutate[0],
|
||||||
(getRandom().nextGaussian()) * mutate[1],
|
(getRandom().nextGaussian()) * mutate[1],
|
||||||
(getRandom().nextGaussian()) * mutate[2]};
|
(getRandom().nextGaussian()) * mutate[2]
|
||||||
|
};
|
||||||
nextDirection += recalc.get(getRandom());
|
nextDirection += recalc.get(getRandom());
|
||||||
}
|
}
|
||||||
steps++;
|
steps++;
|
||||||
double[] args = {origin.getX(), origin.getY(), origin.getZ(), getLength(), steps, seed};
|
double[] args = { origin.getX(), origin.getY(), origin.getZ(), getLength(), steps, seed };
|
||||||
setRadius(new int[] {(int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args))});
|
setRadius(new int[]{ (int) (xRad.evaluate(args)), (int) (yRad.evaluate(args)), (int) (zRad.evaluate(args)) });
|
||||||
direction.rotateAroundX(FastMath.toRadians(currentRotation[0] * mutate[0]));
|
direction.rotateAroundX(FastMath.toRadians(currentRotation[0] * mutate[0]));
|
||||||
direction.rotateAroundY(FastMath.toRadians(currentRotation[1] * mutate[1]));
|
direction.rotateAroundY(FastMath.toRadians(currentRotation[1] * mutate[1]));
|
||||||
direction.rotateAroundZ(FastMath.toRadians(currentRotation[2] * mutate[2]));
|
direction.rotateAroundZ(FastMath.toRadians(currentRotation[2] * mutate[2]));
|
||||||
getRunning().add(direction);
|
getRunning().add(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WormPoint getPoint() {
|
||||||
|
return new WormPoint(getRunning().clone(), getRadius(), config.getCutTop(), config.getCutBottom());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,38 +1,43 @@
|
|||||||
package com.dfsek.terra.addons.carver.carving;
|
package com.dfsek.terra.addons.carver.carving;
|
||||||
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
|
||||||
import com.dfsek.terra.api.world.World;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
|
import com.dfsek.terra.api.world.World;
|
||||||
|
|
||||||
|
|
||||||
public abstract class Carver {
|
public abstract class Carver {
|
||||||
private final int minY;
|
private final int minY;
|
||||||
private final int maxY;
|
private final int maxY;
|
||||||
private final double sixtyFourSq = FastMath.pow(64, 2);
|
private final double sixtyFourSq = FastMath.pow(64, 2);
|
||||||
private int carvingRadius = 4;
|
private int carvingRadius = 4;
|
||||||
|
|
||||||
public Carver(int minY, int maxY) {
|
public Carver(int minY, int maxY) {
|
||||||
this.minY = minY;
|
this.minY = minY;
|
||||||
this.maxY = maxY;
|
this.maxY = maxY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector3, CarvingType> consumer);
|
public abstract void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector3, CarvingType> consumer);
|
||||||
|
|
||||||
public int getCarvingRadius() {
|
public int getCarvingRadius() {
|
||||||
return carvingRadius;
|
return carvingRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCarvingRadius(int carvingRadius) {
|
public void setCarvingRadius(int carvingRadius) {
|
||||||
this.carvingRadius = carvingRadius;
|
this.carvingRadius = carvingRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Worm getWorm(long seed, Vector3 l);
|
public abstract Worm getWorm(long seed, Vector3 l);
|
||||||
|
|
||||||
public abstract boolean isChunkCarved(World w, int chunkX, int chunkZ, Random r);
|
public abstract boolean isChunkCarved(World w, int chunkX, int chunkZ, Random r);
|
||||||
|
|
||||||
public enum CarvingType {
|
public enum CarvingType {
|
||||||
CENTER, WALL, TOP, BOTTOM
|
CENTER,
|
||||||
|
WALL,
|
||||||
|
TOP,
|
||||||
|
BOTTOM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package com.dfsek.terra.addons.carver.carving;
|
package com.dfsek.terra.addons.carver.carving;
|
||||||
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
|
||||||
import com.dfsek.terra.api.world.World;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
|
import com.dfsek.terra.api.world.World;
|
||||||
|
|
||||||
|
|
||||||
public abstract class Worm {
|
public abstract class Worm {
|
||||||
private final Random r;
|
private final Random r;
|
||||||
private final Vector3 origin;
|
private final Vector3 origin;
|
||||||
@ -14,78 +16,73 @@ public abstract class Worm {
|
|||||||
private final int length;
|
private final int length;
|
||||||
private int topCut = 0;
|
private int topCut = 0;
|
||||||
private int bottomCut = 0;
|
private int bottomCut = 0;
|
||||||
private int[] radius = new int[] {0, 0, 0};
|
private int[] radius = { 0, 0, 0 };
|
||||||
|
|
||||||
public Worm(int length, Random r, Vector3 origin) {
|
public Worm(int length, Random r, Vector3 origin) {
|
||||||
this.r = r;
|
this.r = r;
|
||||||
this.length = length;
|
this.length = length;
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.running = origin;
|
this.running = origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void step();
|
||||||
|
|
||||||
public void setBottomCut(int bottomCut) {
|
public void setBottomCut(int bottomCut) {
|
||||||
this.bottomCut = bottomCut;
|
this.bottomCut = bottomCut;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTopCut(int topCut) {
|
public void setTopCut(int topCut) {
|
||||||
this.topCut = topCut;
|
this.topCut = topCut;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 getOrigin() {
|
public Vector3 getOrigin() {
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLength() {
|
public int getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 getRunning() {
|
public Vector3 getRunning() {
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WormPoint getPoint() {
|
public WormPoint getPoint() {
|
||||||
return new WormPoint(running, radius, topCut, bottomCut);
|
return new WormPoint(running, radius, topCut, bottomCut);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getRadius() {
|
public int[] getRadius() {
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRadius(int[] radius) {
|
public void setRadius(int[] radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Random getRandom() {
|
public Random getRandom() {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void step();
|
|
||||||
|
|
||||||
public static class WormPoint {
|
public static class WormPoint {
|
||||||
private final Vector3 origin;
|
private final Vector3 origin;
|
||||||
private final int topCut;
|
private final int topCut;
|
||||||
private final int bottomCut;
|
private final int bottomCut;
|
||||||
private final int[] rad;
|
private final int[] rad;
|
||||||
|
|
||||||
public WormPoint(Vector3 origin, int[] rad, int topCut, int bottomCut) {
|
public WormPoint(Vector3 origin, int[] rad, int topCut, int bottomCut) {
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.rad = rad;
|
this.rad = rad;
|
||||||
this.topCut = topCut;
|
this.topCut = topCut;
|
||||||
this.bottomCut = bottomCut;
|
this.bottomCut = bottomCut;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double ellipseEquation(int x, int y, int z, double xr, double yr, double zr) {
|
private static double ellipseEquation(int x, int y, int z, double xr, double yr, double zr) {
|
||||||
return (FastMath.pow2(x) / FastMath.pow2(xr + 0.5D)) + (FastMath.pow2(y) / FastMath.pow2(yr + 0.5D)) + (FastMath.pow2(z) / FastMath.pow2(zr + 0.5D));
|
return (FastMath.pow2(x) / FastMath.pow2(xr + 0.5D)) + (FastMath.pow2(y) / FastMath.pow2(yr + 0.5D)) + (FastMath.pow2(z) /
|
||||||
|
FastMath.pow2(
|
||||||
|
zr + 0.5D));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 getOrigin() {
|
|
||||||
return origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRadius(int index) {
|
|
||||||
return rad[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void carve(int chunkX, int chunkZ, BiConsumer<Vector3, Carver.CarvingType> consumer, World world) {
|
public void carve(int chunkX, int chunkZ, BiConsumer<Vector3, Carver.CarvingType> consumer, World world) {
|
||||||
int xRad = getRadius(0);
|
int xRad = getRadius(0);
|
||||||
int yRad = getRadius(1);
|
int yRad = getRadius(1);
|
||||||
@ -101,8 +98,10 @@ public abstract class Worm {
|
|||||||
if(position.getY() < world.getMinHeight() || position.getY() > world.getMaxHeight()) continue;
|
if(position.getY() < world.getMinHeight() || position.getY() > world.getMaxHeight()) continue;
|
||||||
double eq = ellipseEquation(x, y, z, xRad, yRad, zRad);
|
double eq = ellipseEquation(x, y, z, xRad, yRad, zRad);
|
||||||
if(eq <= 1 &&
|
if(eq <= 1 &&
|
||||||
y >= -yRad - 1 + bottomCut && y <= yRad + 1 - topCut) {
|
y >= -yRad - 1 + bottomCut && y <= yRad + 1 - topCut) {
|
||||||
consumer.accept(new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), Carver.CarvingType.CENTER);
|
consumer.accept(
|
||||||
|
new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ),
|
||||||
|
Carver.CarvingType.CENTER);
|
||||||
} else if(eq <= 1.5) {
|
} else if(eq <= 1.5) {
|
||||||
Carver.CarvingType type = Carver.CarvingType.WALL;
|
Carver.CarvingType type = Carver.CarvingType.WALL;
|
||||||
if(y <= -yRad - 1 + bottomCut) {
|
if(y <= -yRad - 1 + bottomCut) {
|
||||||
@ -110,11 +109,21 @@ public abstract class Worm {
|
|||||||
} else if(y >= yRad + 1 - topCut) {
|
} else if(y >= yRad + 1 - topCut) {
|
||||||
type = Carver.CarvingType.TOP;
|
type = Carver.CarvingType.TOP;
|
||||||
}
|
}
|
||||||
consumer.accept(new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ), type);
|
consumer.accept(
|
||||||
|
new Vector3(position.getBlockX() - originX, position.getBlockY(), position.getBlockZ() - originZ),
|
||||||
|
type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3 getOrigin() {
|
||||||
|
return origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRadius(int index) {
|
||||||
|
return rad[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.dfsek.terra.addons.feature.distributor;
|
package com.dfsek.terra.addons.feature.distributor;
|
||||||
|
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.feature.distributor.config.AndDistributorTemplate;
|
import com.dfsek.terra.addons.feature.distributor.config.AndDistributorTemplate;
|
||||||
import com.dfsek.terra.addons.feature.distributor.config.NoiseDistributorTemplate;
|
import com.dfsek.terra.addons.feature.distributor.config.NoiseDistributorTemplate;
|
||||||
import com.dfsek.terra.addons.feature.distributor.config.OrDistributorTemplate;
|
import com.dfsek.terra.addons.feature.distributor.config.OrDistributorTemplate;
|
||||||
@ -19,31 +22,32 @@ import com.dfsek.terra.api.registry.CheckedRegistry;
|
|||||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Addon("config-distributors")
|
@Addon("config-distributors")
|
||||||
@Version("1.0.0")
|
@Version("1.0.0")
|
||||||
@Author("Terra")
|
@Author("Terra")
|
||||||
public class DistributorAddon extends TerraAddon {
|
public class DistributorAddon extends TerraAddon {
|
||||||
public static final TypeKey<Supplier<ObjectTemplate<Distributor>>> DISTRIBUTOR_TOKEN = new TypeKey<>() {};
|
public static final TypeKey<Supplier<ObjectTemplate<Distributor>>> DISTRIBUTOR_TOKEN = new TypeKey<>() {
|
||||||
|
};
|
||||||
@Inject
|
@Inject
|
||||||
private TerraPlugin main;
|
private TerraPlugin main;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
main.getEventManager()
|
main.getEventManager()
|
||||||
.getHandler(FunctionalEventHandler.class)
|
.getHandler(FunctionalEventHandler.class)
|
||||||
.register(this, ConfigPackPreLoadEvent.class)
|
.register(this, ConfigPackPreLoadEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
CheckedRegistry<Supplier<ObjectTemplate<Distributor>>> distributorRegistry = event.getPack().getOrCreateRegistry(DISTRIBUTOR_TOKEN);
|
CheckedRegistry<Supplier<ObjectTemplate<Distributor>>> distributorRegistry = event.getPack().getOrCreateRegistry(
|
||||||
distributorRegistry.register("NOISE", NoiseDistributorTemplate::new);
|
DISTRIBUTOR_TOKEN);
|
||||||
distributorRegistry.register("POINTS", PointSetDistributorTemplate::new);
|
distributorRegistry.register("NOISE", NoiseDistributorTemplate::new);
|
||||||
distributorRegistry.register("AND", AndDistributorTemplate::new);
|
distributorRegistry.register("POINTS", PointSetDistributorTemplate::new);
|
||||||
distributorRegistry.register("OR", OrDistributorTemplate::new);
|
distributorRegistry.register("AND", AndDistributorTemplate::new);
|
||||||
|
distributorRegistry.register("OR", OrDistributorTemplate::new);
|
||||||
event.getPack()
|
|
||||||
.applyLoader(Point.class, PointTemplate::new);
|
event.getPack()
|
||||||
})
|
.applyLoader(Point.class, PointTemplate::new);
|
||||||
.failThrough();
|
})
|
||||||
|
.failThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,18 @@ import com.dfsek.tectonic.annotations.Value;
|
|||||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||||
import com.dfsek.tectonic.exception.ValidationException;
|
import com.dfsek.tectonic.exception.ValidationException;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AndDistributorTemplate implements ObjectTemplate<Distributor>, ValidatedConfigTemplate {
|
public class AndDistributorTemplate implements ObjectTemplate<Distributor>, ValidatedConfigTemplate {
|
||||||
@Value("distributors")
|
@Value("distributors")
|
||||||
private @Meta List<@Meta Distributor> distributors;
|
private @Meta List<@Meta Distributor> distributors;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Distributor get() {
|
public Distributor get() {
|
||||||
Distributor current = distributors.remove(0);
|
Distributor current = distributors.remove(0);
|
||||||
@ -22,7 +24,7 @@ public class AndDistributorTemplate implements ObjectTemplate<Distributor>, Vali
|
|||||||
}
|
}
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validate() throws ValidationException {
|
public boolean validate() throws ValidationException {
|
||||||
if(distributors.isEmpty()) throw new ValidationException("AND Distributor must specify at least 1 distributor.");
|
if(distributors.isEmpty()) throw new ValidationException("AND Distributor must specify at least 1 distributor.");
|
||||||
|
@ -3,19 +3,20 @@ package com.dfsek.terra.addons.feature.distributor.config;
|
|||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.feature.distributor.distributors.NoiseDistributor;
|
import com.dfsek.terra.addons.feature.distributor.distributors.NoiseDistributor;
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||||
|
|
||||||
public class NoiseDistributorTemplate implements ObjectTemplate<Distributor> {
|
|
||||||
@Value("distribution")
|
|
||||||
private @Meta NoiseSampler noise;
|
|
||||||
|
|
||||||
|
public class NoiseDistributorTemplate implements ObjectTemplate<Distributor> {
|
||||||
@Value("threshold")
|
@Value("threshold")
|
||||||
@Default
|
@Default
|
||||||
private @Meta double threshold = 0;
|
private final @Meta double threshold = 0;
|
||||||
|
@Value("distribution")
|
||||||
|
private @Meta NoiseSampler noise;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Distributor get() {
|
public Distributor get() {
|
||||||
return new NoiseDistributor(noise, threshold);
|
return new NoiseDistributor(noise, threshold);
|
||||||
|
@ -4,16 +4,18 @@ import com.dfsek.tectonic.annotations.Value;
|
|||||||
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
|
||||||
import com.dfsek.tectonic.exception.ValidationException;
|
import com.dfsek.tectonic.exception.ValidationException;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class OrDistributorTemplate implements ObjectTemplate<Distributor>, ValidatedConfigTemplate {
|
public class OrDistributorTemplate implements ObjectTemplate<Distributor>, ValidatedConfigTemplate {
|
||||||
@Value("distributors")
|
@Value("distributors")
|
||||||
private @Meta List<@Meta Distributor> distributors;
|
private @Meta List<@Meta Distributor> distributors;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Distributor get() {
|
public Distributor get() {
|
||||||
Distributor current = distributors.remove(0);
|
Distributor current = distributors.remove(0);
|
||||||
@ -22,7 +24,7 @@ public class OrDistributorTemplate implements ObjectTemplate<Distributor>, Valid
|
|||||||
}
|
}
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validate() throws ValidationException {
|
public boolean validate() throws ValidationException {
|
||||||
if(distributors.isEmpty()) throw new ValidationException("AND Distributor must specify at least 1 distributor.");
|
if(distributors.isEmpty()) throw new ValidationException("AND Distributor must specify at least 1 distributor.");
|
||||||
|
@ -2,17 +2,19 @@ package com.dfsek.terra.addons.feature.distributor.config;
|
|||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.feature.distributor.distributors.PointSetDistributor;
|
import com.dfsek.terra.addons.feature.distributor.distributors.PointSetDistributor;
|
||||||
import com.dfsek.terra.addons.feature.distributor.util.Point;
|
import com.dfsek.terra.addons.feature.distributor.util.Point;
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class PointSetDistributorTemplate implements ObjectTemplate<Distributor> {
|
public class PointSetDistributorTemplate implements ObjectTemplate<Distributor> {
|
||||||
@Value("points")
|
@Value("points")
|
||||||
private @Meta Set<@Meta Point> points;
|
private @Meta Set<@Meta Point> points;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Distributor get() {
|
public Distributor get() {
|
||||||
return new PointSetDistributor(points);
|
return new PointSetDistributor(points);
|
||||||
|
@ -3,15 +3,17 @@ package com.dfsek.terra.addons.feature.distributor.distributors;
|
|||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||||
|
|
||||||
|
|
||||||
public class NoiseDistributor implements Distributor {
|
public class NoiseDistributor implements Distributor {
|
||||||
private final NoiseSampler sampler;
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
private final double threshold;
|
private final double threshold;
|
||||||
|
|
||||||
public NoiseDistributor(NoiseSampler sampler, double threshold) {
|
public NoiseDistributor(NoiseSampler sampler, double threshold) {
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
this.threshold = threshold;
|
this.threshold = threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(int x, int z, long seed) {
|
public boolean matches(int x, int z, long seed) {
|
||||||
return sampler.getNoiseSeeded(seed, x, z) > threshold;
|
return sampler.getNoiseSeeded(seed, x, z) > threshold;
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
package com.dfsek.terra.addons.feature.distributor.distributors;
|
package com.dfsek.terra.addons.feature.distributor.distributors;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.feature.distributor.util.Point;
|
import com.dfsek.terra.addons.feature.distributor.util.Point;
|
||||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class PointSetDistributor implements Distributor {
|
public class PointSetDistributor implements Distributor {
|
||||||
private final Set<Point> points;
|
private final Set<Point> points;
|
||||||
|
|
||||||
public PointSetDistributor(Set<Point> points) {
|
public PointSetDistributor(Set<Point> points) {
|
||||||
this.points = points;
|
this.points = points;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(int x, int z, long seed) {
|
public boolean matches(int x, int z, long seed) {
|
||||||
return points.contains(new Point(x, z));
|
return points.contains(new Point(x, z));
|
||||||
|
@ -3,28 +3,28 @@ package com.dfsek.terra.addons.feature.distributor.util;
|
|||||||
public class Point {
|
public class Point {
|
||||||
private final int x;
|
private final int x;
|
||||||
private final int z;
|
private final int z;
|
||||||
|
|
||||||
private final int hash;
|
private final int hash;
|
||||||
|
|
||||||
public Point(int x, int z) {
|
public Point(int x, int z) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.hash = 31 * x + z;
|
this.hash = 31 * x + z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getZ() {
|
public int getZ() {
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if(!(obj instanceof Point)) return false;
|
if(!(obj instanceof Point)) return false;
|
||||||
|
@ -2,15 +2,17 @@ package com.dfsek.terra.addons.feature.distributor.util;
|
|||||||
|
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
import com.dfsek.tectonic.loading.object.ObjectTemplate;
|
||||||
|
|
||||||
import com.dfsek.terra.api.config.meta.Meta;
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
|
||||||
|
|
||||||
public class PointTemplate implements ObjectTemplate<Point> {
|
public class PointTemplate implements ObjectTemplate<Point> {
|
||||||
@Value("x")
|
@Value("x")
|
||||||
private @Meta int x;
|
private @Meta int x;
|
||||||
|
|
||||||
@Value("z")
|
@Value("z")
|
||||||
private @Meta int z;
|
private @Meta int z;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Point get() {
|
public Point get() {
|
||||||
return new Point(x, z);
|
return new Point(x, z);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user