-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement support for Conditional Biomes #3
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright 2019 MovingBlocks | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.terasology.biomesAPI; | ||
|
||
import org.terasology.math.geom.Vector2f; | ||
import org.terasology.world.generation.facets.base.FieldFacet2D; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
public abstract class BaseConditionalBiome implements ConditionalBiome { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide Javadoc what this base class offers. |
||
protected Map<Class<? extends FieldFacet2D>, Vector2f> limitedFacets = new HashMap<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of using |
||
|
||
@Override | ||
public boolean isValid(Class<? extends FieldFacet2D> facetClass, Float value) { | ||
Vector2f constraints = limitedFacets.get(facetClass); | ||
return constraints == null || (value >= constraints.x && value <= constraints.y); | ||
} | ||
|
||
@Override | ||
public Set<Class<? extends FieldFacet2D>> getLimitedFacets() { | ||
return limitedFacets.keySet(); | ||
} | ||
|
||
@Override | ||
public void setLowerLimit(Class<? extends FieldFacet2D> facetClass, Float minimum) { | ||
limitedFacets.compute(facetClass, (k, v) -> { | ||
if (v == null) v = new Vector2f(minimum, Float.MAX_VALUE); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use braces even for these simple one-line if-statements. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I'd do if (v == null) v = new Vector2f(Float.MIN_VALUE, Float.MAX_VALUE); for the initialization in both cases, and only set the minimum or maximum once afterwards. |
||
v.x = minimum; | ||
return v; | ||
}); | ||
} | ||
|
||
@Override | ||
public void setUpperLimit(Class<? extends FieldFacet2D> facetClass, Float maximum) { | ||
limitedFacets.compute(facetClass, (k, v) -> { | ||
if (v == null) v = new Vector2f(Float.MIN_VALUE, maximum); | ||
v.y = maximum; | ||
return v; | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -16,8 +16,10 @@ | |||||
package org.terasology.biomesAPI; | ||||||
|
||||||
import org.terasology.entitySystem.systems.ComponentSystem; | ||||||
import org.terasology.math.geom.BaseVector2i; | ||||||
import org.terasology.math.geom.Vector3i; | ||||||
import org.terasology.world.chunks.CoreChunk; | ||||||
import org.terasology.world.generation.GeneratingRegion; | ||||||
|
||||||
import java.util.Collection; | ||||||
import java.util.Optional; | ||||||
|
@@ -96,4 +98,21 @@ public interface BiomeRegistry { | |||||
* @return Collection of biomes of given subtype | ||||||
*/ | ||||||
<T extends Biome> Collection<T> getRegisteredBiomes(Class<T> biomeClass); | ||||||
|
||||||
/** | ||||||
* Returns all biomes that do not forbid themselves from the given location. | ||||||
* @param region The world region | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I created the implementation inside the biome instead of inside the registry is that it is a much simpler matter to add abstract conditional logic as an overridden method of the biome than it is to insert such logic directly into a map. Honestly, it leaves me wondering if biomes should not be changed to a form of asset that can be handled by the entity system, like prefabs... but I believe that doing so would likely require an overhaul of the game loading system so that the entity system is initialized before facets are created. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, the facet providers already use components to hold their configuration (not that this is working for actual world gen, though). Turning biomes into assets sounds like a good idea, overall... |
||||||
* @param pos The location in the world | ||||||
* @return Collection of biomes that are valid for that location | ||||||
*/ | ||||||
Collection<Biome> getValidBiomes(GeneratingRegion region, BaseVector2i pos); | ||||||
|
||||||
/** | ||||||
* Returns all biomes that do not forbid themselves from the given location. | ||||||
* @param region The world region | ||||||
* @param pos The location in the world | ||||||
* @param conditionalOnly If true, ignore biomes that have no restrictions | ||||||
* @return Collection of biomes that are valid for that location | ||||||
*/ | ||||||
Collection<Biome> getValidBiomes(GeneratingRegion region, BaseVector2i pos, boolean conditionalOnly); | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright 2019 MovingBlocks | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... |
||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.terasology.biomesAPI; | ||
|
||
import org.terasology.math.geom.BaseVector2i; | ||
import org.terasology.world.generation.GeneratingRegion; | ||
import org.terasology.world.generation.facets.base.FieldFacet2D; | ||
|
||
import java.util.Set; | ||
|
||
/** | ||
* This interface allows biomes to accept various limits on where they may generate. | ||
*/ | ||
public interface ConditionalBiome extends Biome { | ||
|
||
/** | ||
* Returns true if the biome can generate at the given value of the given facet. | ||
* @param facetClass The facet to check, such as humidity or temperature. | ||
* @param value This facet's value. | ||
* @return True if possible. | ||
*/ | ||
default boolean isValid(Class<? extends FieldFacet2D> facetClass, Float value) | ||
{ | ||
return true; | ||
} | ||
|
||
/** | ||
* Checks whether all facets of the given location meet this biome's restrictions. | ||
* @param region The game region being generated. | ||
* @param pos The particular position we are checking. | ||
* @return True if this biome's conditions are met. | ||
*/ | ||
default boolean isValid(GeneratingRegion region, BaseVector2i pos) | ||
{ | ||
for (Class<? extends FieldFacet2D> classy : getLimitedFacets()) | ||
{ | ||
FieldFacet2D facetResult = region.getRegionFacet(classy); | ||
if (!isValid(classy, facetResult.get(pos))) | ||
{ | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* @return A list of all facets that this biome has restrictions towards. | ||
*/ | ||
Set<Class<? extends FieldFacet2D>> getLimitedFacets(); | ||
|
||
void setLowerLimit(Class<? extends FieldFacet2D> facetClass, Float minimum); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is missing Javadoc on the semantics of Likewise, for |
||
|
||
void setUpperLimit(Class<? extends FieldFacet2D> facetClass, Float maximum); | ||
|
||
default void setLimits(Class<? extends FieldFacet2D> facetClass, Float minimum, Float maximum) | ||
{ | ||
setLowerLimit(facetClass, minimum); | ||
setUpperLimit(facetClass, maximum); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...