diff --git a/FeatureManager-fabric b/FeatureManager-fabric new file mode 160000 index 0000000..9ed4410 --- /dev/null +++ b/FeatureManager-fabric @@ -0,0 +1 @@ +Subproject commit 9ed441098a5132d93b3cdb01cea1a2dcecaf2eb9 diff --git a/TerraForgedAPI-fabric/README.md b/TerraForgedAPI-fabric/README.md new file mode 100644 index 0000000..2d5f64e --- /dev/null +++ b/TerraForgedAPI-fabric/README.md @@ -0,0 +1,23 @@ +# TerraForgedAPI + +### Dependency +```groovy +repositories { + maven { + url "https://io.terraforged.com/repository/maven/" + } +} + +dependencies { + implementation "com.terraforged:TerraForgedAPI:1.15.2-0.0.1" +} +``` + +### Usage + +TerraForged fires a number of setup events each time its chunk generator is created. These events expose certain +components of the generator allowing for world-gen content to be configured, modified, or added to. + +See the `com.terraforged.api.TerraEvent` class for the available events. + +All events are fired on the `FORGE` event bus. \ No newline at end of file diff --git a/TerraForgedAPI-fabric/build.gradle b/TerraForgedAPI-fabric/build.gradle new file mode 100644 index 0000000..368f655 --- /dev/null +++ b/TerraForgedAPI-fabric/build.gradle @@ -0,0 +1,59 @@ +buildscript { + repositories { + maven { url "https://maven.fabricmc.net/" } + jcenter() + } + dependencies { + classpath "net.fabricmc:fabric-loom:0.2.7-SNAPSHOT" + } +} + +apply plugin: "fabric-loom" +apply plugin: "maven-publish" +apply plugin: "eclipse" + +version = "${mc_version}-${mod_version}" +archivesBaseName = "TerraForgedAPI-fabric" + +repositories { + jcenter() + mavenCentral() +} + +dependencies { + minecraft "com.mojang:minecraft:${mc_version}" + mappings "net.fabricmc:yarn:${mc_version}+build.${yarn_build}:v2" + modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}" + compile project(":Noise2D") + compile project(":FeatureManager-fabric") + compile project(":TerraForgedCore") +} + +jar { + from("$buildDir/classes/java/main") + from(project(":Noise2D").buildDir.getPath() + "/classes/java/main") + from(project(":FeatureManager-fabric").buildDir.getPath() + "/classes/java/main") + from(project(":TerraForgedCore").buildDir.getPath() + "/classes/java/main") +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifact jar + } + } + + if (System.getenv("MAVEN_USER") != null && System.getenv("MAVEN_PASS") != null) { + repositories { + maven { + credentials { + username System.getenv("MAVEN_USER") + password System.getenv("MAVEN_PASS") + } + name = "nexus" + url = "https://io.terraforged.com/repository/maven/" + } + } + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/BiomeTags.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/BiomeTags.java new file mode 100644 index 0000000..b7d6b05 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/BiomeTags.java @@ -0,0 +1,121 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.biome; + +import com.terraforged.core.world.biome.BiomeType; +import net.minecraft.tag.Tag; +import net.minecraft.tag.TagContainer; +import net.minecraft.util.Identifier; +import net.minecraft.world.biome.Biome; + +import java.util.Collection; +import java.util.EnumMap; +import java.util.Map; +import java.util.Optional; + +public class BiomeTags { + + private static int generation; + private static TagContainer collection = new TagContainer<>( + path -> Optional.empty(), + "", + false, + "" + ); + + private static final Map tags = new EnumMap<>(BiomeType.class); + + public static final Tag ALPINE = tag(BiomeType.ALPINE); + public static final Tag COLD_STEPPE = tag(BiomeType.COLD_STEPPE); + public static final Tag DESERT = tag(BiomeType.DESERT); + public static final Tag GRASSLAND = tag(BiomeType.GRASSLAND); + public static final Tag SAVANNA = tag(BiomeType.SAVANNA); + public static final Tag STEPPE = tag(BiomeType.STEPPE); + public static final Tag TAIGA = tag(BiomeType.TAIGA); + public static final Tag TEMPERATE_FOREST = tag(BiomeType.TEMPERATE_FOREST); + public static final Tag TEMPERATE_RAINFOREST = tag(BiomeType.TEMPERATE_RAINFOREST); + public static final Tag TROPICAL_RAINFOREST = tag(BiomeType.TROPICAL_RAINFOREST); + public static final Tag TUNDRA = tag(BiomeType.TUNDRA); + + public static Tag getTag(BiomeType type) { + return tags.get(type); + } + + public static void setCollection(TagContainer collection) { + BiomeTags.collection = collection; + BiomeTags.generation++; + } + + private static BiomeWrapper tag(BiomeType type) { + BiomeWrapper wrapper = tag(type.name().toLowerCase()); + tags.put(type, wrapper); + return wrapper; + } + + private static BiomeWrapper tag(String name) { + return new BiomeWrapper(new Identifier("terraforged", name)); + } + + private static class BiomeWrapper extends Tag { + + private Tag cachedTag = null; + private int lastKnownGeneration = -1; + + public BiomeWrapper(Identifier name) { + super(name); + } + + @Override + public boolean contains(Biome biome) { + if (this.lastKnownGeneration != BiomeTags.generation) { + this.cachedTag = BiomeTags.collection.getOrCreate(this.getId()); + this.lastKnownGeneration = BiomeTags.generation; + } + + return this.cachedTag.contains(biome); + } + + @Override + public Collection values() { + if (this.lastKnownGeneration != BiomeTags.generation) { + this.cachedTag = BiomeTags.collection.getOrCreate(this.getId()); + this.lastKnownGeneration = BiomeTags.generation; + } + + return this.cachedTag.values(); + } + + @Override + public Collection> entries() { + if (this.lastKnownGeneration != BiomeTags.generation) { + this.cachedTag = BiomeTags.collection.getOrCreate(this.getId()); + this.lastKnownGeneration = BiomeTags.generation; + } + + return this.cachedTag.entries(); + } + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/BiomeVariant.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/BiomeVariant.java new file mode 100644 index 0000000..52317b2 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/BiomeVariant.java @@ -0,0 +1,52 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.biome; + +import net.minecraft.world.biome.Biome; + +public abstract class BiomeVariant extends Biome { + + protected BiomeVariant(Settings biomeBuilder) { + super(biomeBuilder); + } + + @Override + public int getGrassColorAt(double x, double z) { + return getBase().getGrassColorAt(x, z); + } + + @Override + public int getFoliageColor() { + return getBase().getFoliageColor(); + } + + @Override + public int getSkyColor() { + return getBase().getSkyColor(); + } + + public abstract Biome getBase(); +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/AbstractMaxHeightModifier.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/AbstractMaxHeightModifier.java new file mode 100644 index 0000000..773b321 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/AbstractMaxHeightModifier.java @@ -0,0 +1,67 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.world.biome.Biome; + +public abstract class AbstractMaxHeightModifier extends AbstractOffsetModifier { + + private final float minHeight; + private final float maxHeight; + private final float range; + private final Module variance; + + public AbstractMaxHeightModifier(Seed seed, Climate climate, int scale, int octaves, float variance, float minHeight, float maxHeight) { + super(climate); + this.minHeight = minHeight; + this.maxHeight = maxHeight; + this.range = maxHeight - minHeight; + this.variance = Source.perlin(seed.next(), scale, octaves).scale(variance); + } + + @Override + protected final Biome modify(Biome in, Cell cell, int x, int z, float ox, float oz) { + float var = variance.getValue(x, z); + float value = cell.value + var; + if (value < minHeight) { + return in; + } + if (value > maxHeight) { + return getModifiedBiome(in, cell, x, z, ox, oz); + } + float alpha = (value - minHeight) / range; + cell.biomeEdge *= alpha; + return in; + } + + protected abstract Biome getModifiedBiome(Biome in, Cell cell, int x, int z, float ox, float oz); +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/AbstractOffsetModifier.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/AbstractOffsetModifier.java new file mode 100644 index 0000000..d0a6a43 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/AbstractOffsetModifier.java @@ -0,0 +1,49 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.world.biome.Biome; + +public abstract class AbstractOffsetModifier implements BiomeModifier { + + private final Climate climate; + + public AbstractOffsetModifier(Climate climate) { + this.climate = climate; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + float dx = climate.getOffsetX(x, z, 50); + float dz = climate.getOffsetX(x, z, 50); + return modify(in, cell, x, z, x + dx, z + dz); + } + + protected abstract Biome modify(Biome in, Cell cell, int x, int z, float ox, float oz); +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/BiomeModifier.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/BiomeModifier.java new file mode 100644 index 0000000..2d81330 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/BiomeModifier.java @@ -0,0 +1,45 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.world.biome.Biome; + +public interface BiomeModifier extends Comparable { + + int priority(); + + boolean test(Biome biome); + + Biome modify(Biome in, Cell cell, int x, int z); + + @Override + default int compareTo(BiomeModifier other) { + // reverse order + return Integer.compare(other.priority(), priority()); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/ModifierManager.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/ModifierManager.java new file mode 100644 index 0000000..dc9bc07 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/biome/modifier/ModifierManager.java @@ -0,0 +1,31 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.biome.modifier; + +public interface ModifierManager { + + void register(BiomeModifier modifier); +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/ChunkContext.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/ChunkContext.java new file mode 100644 index 0000000..a1817e0 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/ChunkContext.java @@ -0,0 +1,48 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk; + +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.ChunkRandom; + +public class ChunkContext { + + public final int chunkX; + public final int chunkZ; + public final int blockX; + public final int blockZ; + public final Chunk chunk; + public final ChunkRandom random = new ChunkRandom(); + + public ChunkContext(Chunk chunk) { + this.chunk = chunk; + this.chunkX = chunk.getPos().x; + this.chunkZ = chunk.getPos().z; + this.blockX = chunkX << 4; + this.blockZ = chunkZ << 4; + this.random.setSeed(chunkX, chunkZ); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/ChunkDelegate.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/ChunkDelegate.java new file mode 100644 index 0000000..d267764 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/ChunkDelegate.java @@ -0,0 +1,308 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk; + +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.shorts.ShortList; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.Entity; +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.FluidState; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.structure.StructureStart; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.Heightmap; +import net.minecraft.world.RayTraceContext; +import net.minecraft.world.TickScheduler; +import net.minecraft.world.biome.source.BiomeArray; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkSection; +import net.minecraft.world.chunk.ChunkStatus; +import net.minecraft.world.chunk.UpgradeData; +import net.minecraft.world.gen.GenerationStep; + +import java.util.BitSet; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +public interface ChunkDelegate extends Chunk { + + Chunk getDelegate(); + + @Override + //@Nullable + default BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving) { + return getDelegate().setBlockState(pos, state, isMoving); + } + + @Override + default void setBlockEntity(BlockPos pos, BlockEntity tileEntityIn) { + getDelegate().setBlockEntity(pos, tileEntityIn); + } + + @Override + default void addEntity(Entity entityIn) { + getDelegate().addEntity(entityIn); + } + + @Override + //@Nullable + default ChunkSection getHighestNonEmptySection() { + return getDelegate().getHighestNonEmptySection(); + } + + @Override + default int getHighestNonEmptySectionYOffset() { + return getDelegate().getHighestNonEmptySectionYOffset(); + } + + @Override + default Set getBlockEntityPositions() { + return getDelegate().getBlockEntityPositions(); + } + + @Override + default ChunkSection[] getSectionArray() { + return getDelegate().getSectionArray(); + } + + + @Override + default Collection> getHeightmaps() { + return getDelegate().getHeightmaps(); + } + + @Override + default void setHeightmap(Heightmap.Type type, long[] data) { + getDelegate().setHeightmap(type, data); + } + + @Override + default Heightmap getHeightmap(Heightmap.Type type) { + return getDelegate().getHeightmap(type); + } + + @Override + default int sampleHeightmap(Heightmap.Type heightmapType, int x, int z) { + return getDelegate().sampleHeightmap(heightmapType, x, z); + } + + @Override + default ChunkPos getPos() { + return getDelegate().getPos(); + } + + @Override + default void setLastSaveTime(long saveTime) { + getDelegate().setLastSaveTime(saveTime); + } + + @Override + default Map getStructureStarts() { + return getDelegate().getStructureStarts(); + } + + @Override + default void setStructureStarts(Map structureStartsIn) { + getDelegate().setStructureStarts(structureStartsIn); + } + + @Override + default boolean method_12228(int startY, int endY) { + return getDelegate().method_12228(startY, endY); + } + + @Override + //@Nullable + default BiomeArray getBiomeArray() { + return getDelegate().getBiomeArray(); + } + + @Override + default void setLightOn(boolean modified) { + getDelegate().setLightOn(modified); + } + + @Override + default boolean isLightOn() { + return getDelegate().isLightOn(); + } + + @Override + default ChunkStatus getStatus() { + return getDelegate().getStatus(); + } + + @Override + default void removeBlockEntity(BlockPos pos) { + getDelegate().removeBlockEntity(pos); + } + + @Override + default void markBlockForPostProcessing(BlockPos pos) { + getDelegate().markBlockForPostProcessing(pos); + } + + @Override + default ShortList[] getPostProcessingLists() { + return getDelegate().getPostProcessingLists(); + } + + @Override + default void markBlockForPostProcessing(short packedPosition, int index) { + getDelegate().markBlockForPostProcessing(packedPosition, index); + } + + @Override + default void addPendingBlockEntityTag(CompoundTag nbt) { + getDelegate().addPendingBlockEntityTag(nbt); + } + + @Override + //@Nullable + default CompoundTag method_20598(BlockPos pos) { + return getDelegate().method_20598(pos); + } + + @Override + //@Nullable + default CompoundTag getBlockEntityTagAt(BlockPos pos) { + return getDelegate().getBlockEntityTagAt(pos); + } + + @Override + default Stream getLightSourcesStream() { + return getDelegate().getLightSourcesStream(); + } + + @Override + default TickScheduler getBlockTickScheduler() { + return getDelegate().getBlockTickScheduler(); + } + + @Override + default TickScheduler getFluidTickScheduler() { + return getDelegate().getFluidTickScheduler(); + } + + @Override + default BitSet getCarvingMask(GenerationStep.Carver type) { + return getDelegate().getCarvingMask(type); + } + + @Override + default void setShouldSave(boolean shouldSave) { + getDelegate().setShouldSave(shouldSave); + } + + @Override + default boolean needsSaving() { + return getDelegate().needsSaving(); + } + + @Override + default void setStructureStart(String structure, StructureStart start) { + getDelegate().setStructureStart(structure, start); + } + + @Override + default int getLuminance(BlockPos pos) { + return getDelegate().getLuminance(pos); + } + + @Override + default UpgradeData getUpgradeData() { + return getDelegate().getUpgradeData(); + } + + @Override + default void setInhabitedTime(long inhabitedTime) { + getDelegate().setInhabitedTime(inhabitedTime); + } + + @Override + default long getInhabitedTime() { + return getDelegate().getInhabitedTime(); + } + + @Override + default BlockEntity getBlockEntity(BlockPos pos) { + return getDelegate().getBlockEntity(pos); + } + + @Override + default BlockState getBlockState(BlockPos pos) { + return getDelegate().getBlockState(pos); + } + + @Override + default FluidState getFluidState(BlockPos pos) { + return getDelegate().getFluidState(pos); + } + + @Override + default StructureStart getStructureStart(String structure) { + return getDelegate().getStructureStart(structure); + } + + @Override + default LongSet getStructureReferences(String structure) { + return getDelegate().getStructureReferences(structure); + } + + @Override + default void addStructureReference(String structure, long reference) { + getDelegate().addStructureReference(structure, reference); + } + + @Override + default Map getStructureReferences() { + return getDelegate().getStructureReferences(); + } + + @Override + default void setStructureReferences(Map structureReferences) { + getDelegate().setStructureReferences(structureReferences); + } + + @Override + default int getMaxLightLevel() { + return getDelegate().getMaxLightLevel(); + } + + @Override + default int getHeight() { + return getDelegate().getHeight(); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/ColumnDecorator.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/ColumnDecorator.java new file mode 100644 index 0000000..45f3611 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/ColumnDecorator.java @@ -0,0 +1,63 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.column; + +import com.terraforged.api.chunk.surface.ChunkSurfaceBuffer; +import me.dags.noise.Source; +import me.dags.noise.source.FastSource; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.Chunk; + +public interface ColumnDecorator { + + FastSource variance = (FastSource) Source.perlin(0, 100, 1); + + void decorate(Chunk chunk, DecoratorContext context, int x, int y, int z); + + default void decorate(ChunkSurfaceBuffer buffer, DecoratorContext context, int x, int y, int z) { + decorate(buffer.getDelegate(), context, x, y, z); + } + + default void setState(Chunk chunk, int x, int y, int z, BlockState state, boolean moving) { + chunk.setBlockState(new BlockPos(x, y, z), state, moving); + } + + default void fillDown(DecoratorContext context, Chunk chunk, int x, int z, int from, int to, BlockState state) { + for (int dy = from; dy > to; dy--) { + chunk.setBlockState(context.pos.set(x, dy, z), state, false); + } + } + + static float getNoise(float x, float z, int seed, float scale, float bias) { + return (variance.getValue(x, z, seed) * scale) + bias; + } + + static float getNoise(float x, float z, int seed, int scale, int bias) { + return getNoise(x, z, seed, scale / 255F, bias / 255F); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/DecoratorContext.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/DecoratorContext.java new file mode 100644 index 0000000..6ed8be9 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/DecoratorContext.java @@ -0,0 +1,54 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.column; + +import com.terraforged.api.chunk.ChunkContext; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.Chunk; + +public class DecoratorContext extends ChunkContext { + + public final Levels levels; + public final Climate climate; + public final Terrains terrains; + public final BlockPos.Mutable pos = new BlockPos.Mutable(); + + public Biome biome; + public Cell cell; + + public DecoratorContext(Chunk chunk, Levels levels, Terrains terrain, Climate climate) { + super(chunk); + this.levels = levels; + this.climate = climate; + this.terrains = terrain; + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/DecoratorManager.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/DecoratorManager.java new file mode 100644 index 0000000..81671ea --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/column/DecoratorManager.java @@ -0,0 +1,47 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.column; + +import java.util.List; + +public class DecoratorManager { + + private final List baseDecorators; + private final List featureDecorators; + + public DecoratorManager(List baseDecorators, List featureDecorators) { + this.baseDecorators = baseDecorators; + this.featureDecorators = featureDecorators; + } + + public void registerBaseDecorator(ColumnDecorator decorator) { + baseDecorators.add(decorator); + } + + public void registerFeatureDecorator(ColumnDecorator decorator) { + featureDecorators.add(decorator); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/CachedSurface.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/CachedSurface.java new file mode 100644 index 0000000..8bda7b8 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/CachedSurface.java @@ -0,0 +1,34 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.surface; + +import net.minecraft.world.biome.Biome; + +public class CachedSurface { + + public Biome biome; + public Surface surface; +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/ChunkSurfaceBuffer.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/ChunkSurfaceBuffer.java new file mode 100644 index 0000000..b8f5daf --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/ChunkSurfaceBuffer.java @@ -0,0 +1,72 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.surface; + +import com.terraforged.api.chunk.ChunkDelegate; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.Chunk; + +public class ChunkSurfaceBuffer implements ChunkDelegate { + + private int surfaceTop; + private int surfaceBottom; + private final Chunk delegate; + + public ChunkSurfaceBuffer(Chunk chunk) { + this.delegate = chunk; + } + + @Override + public Chunk getDelegate() { + return delegate; + } + + //@Nullable + @Override + public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving) { + if (pos.getY() > surfaceTop) { + surfaceTop = pos.getY(); + } + if (pos.getY() < surfaceBottom) { + surfaceBottom = pos.getY(); + } + return getDelegate().setBlockState(pos, state, isMoving); + } + + public int getSurfaceTop() { + return surfaceTop; + } + + public int getSurfaceBottom() { + return surfaceBottom; + } + + public void setSurfaceLevel(int y) { + surfaceTop = y; + surfaceBottom = y; + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/Surface.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/Surface.java new file mode 100644 index 0000000..3003c2a --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/Surface.java @@ -0,0 +1,52 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.surface; + + +import com.terraforged.api.chunk.surface.builder.Combiner; +import net.minecraft.block.BlockState; +import net.minecraft.world.chunk.Chunk; + +public interface Surface { + + void buildSurface(int x, int z, int height, SurfaceContext ctx); + + default void fill(int x, int z, int start, int end, SurfaceContext ctx, Chunk chunk, BlockState state) { + if (start < end) { + for (int y = start; y < end; y++) { + chunk.setBlockState(ctx.pos.set(x, y, z), state, false); + } + } else if (start > end) { + for (int y = start; y > end; y--) { + chunk.setBlockState(ctx.pos.set(x, y, z), state, false); + } + } + } + + default Surface then(Surface next) { + return new Combiner(this, next); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/SurfaceContext.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/SurfaceContext.java new file mode 100644 index 0000000..bc82a01 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/SurfaceContext.java @@ -0,0 +1,53 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.surface; + +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrains; +import net.minecraft.block.BlockState; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.chunk.ChunkGeneratorConfig; + +public class SurfaceContext extends DecoratorContext { + + public final BlockState solid; + public final BlockState fluid; + public final int seaLevel; + public final long seed; + public final CachedSurface cached = new CachedSurface(); + + public double noise; + + public SurfaceContext(Chunk chunk, Levels levels, Terrains terrain, Climate climate, ChunkGeneratorConfig settings, long seed) { + super(chunk, levels, terrain, climate); + this.solid = settings.getDefaultBlock(); + this.fluid = settings.getDefaultFluid(); + this.seed = seed; + this.seaLevel = levels.waterLevel; + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/SurfaceManager.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/SurfaceManager.java new file mode 100644 index 0000000..e0578de --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/SurfaceManager.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.surface; + +import com.terraforged.api.chunk.surface.builder.Delegate; +import net.minecraft.world.biome.Biome; + +import java.util.HashMap; +import java.util.Map; + +public class SurfaceManager { + + private final Map surfaces = new HashMap<>(); + + public SurfaceManager replace(Biome biome, Surface surface) { + surfaces.put(biome, surface); + return this; + } + + public SurfaceManager extend(Biome biome, Surface surface) { + Surface result = getOrCreateSurface(biome).then(surface); + return replace(biome, result); + } + + public Surface getSurface(SurfaceContext context) { + if (context.biome == context.cached.biome) { + return context.cached.surface; + } + context.cached.biome = context.biome; + context.cached.surface = getOrCreateSurface(context.biome); + return context.cached.surface; + } + + public Surface getOrCreateSurface(Biome biome) { + return surfaces.computeIfAbsent(biome, Delegate.FUNC); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/builder/Combiner.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/builder/Combiner.java new file mode 100644 index 0000000..fdc7015 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/builder/Combiner.java @@ -0,0 +1,46 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.surface.builder; + +import com.terraforged.api.chunk.surface.Surface; +import com.terraforged.api.chunk.surface.SurfaceContext; + +public class Combiner implements Surface { + + private final Surface first; + private final Surface second; + + public Combiner(Surface first, Surface second) { + this.first = first; + this.second = second; + } + + @Override + public void buildSurface(int x, int z, int height, SurfaceContext ctx) { + first.buildSurface(x, z, height, ctx); + second.buildSurface(x, z, height, ctx); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/builder/Delegate.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/builder/Delegate.java new file mode 100644 index 0000000..2f9034d --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/chunk/surface/builder/Delegate.java @@ -0,0 +1,67 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.chunk.surface.builder; + +import com.terraforged.api.chunk.surface.Surface; +import com.terraforged.api.chunk.surface.SurfaceContext; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.surfacebuilders.ConfiguredSurfaceBuilder; + +import java.util.function.Function; + +public class Delegate implements Surface { + + public static final Function FUNC = Delegate::new; + + private final ConfiguredSurfaceBuilder surfaceBuilder; + + private Delegate(Biome biome) { + this(biome.getSurfaceBuilder()); + } + + private Delegate(ConfiguredSurfaceBuilder surfaceBuilder) { + this.surfaceBuilder = surfaceBuilder; + } + + @Override + public void buildSurface(int x, int z, int height, SurfaceContext context) { + surfaceBuilder.setSeed(context.seed); + + surfaceBuilder.buildSurface( + context.random, + context.chunk, + context.biome, + x, + z, + height, + context.noise, + context.solid, + context.fluid, + context.seaLevel, + context.seed + ); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/event/SetupEvent.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/event/SetupEvent.java new file mode 100644 index 0000000..ba3fa16 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/event/SetupEvent.java @@ -0,0 +1,107 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.event; + +import com.terraforged.api.biome.modifier.ModifierManager; +import com.terraforged.api.chunk.column.DecoratorManager; +import com.terraforged.api.chunk.surface.SurfaceManager; +import com.terraforged.api.material.geology.GeologyManager; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.terrain.provider.TerrainProvider; +import com.terraforged.feature.modifier.FeatureModifiers; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +@FunctionalInterface +public interface SetupEvent { + /** + * Can be used to register custom biome Surface decorators + */ + Event> SURFACE = EventFactory.createArrayBacked(SetupEvent.class, handlers -> (manager, context) -> { + for (SetupEvent handler : handlers) { + handler.handle(manager, context); + } + }); + /** + * Register additional layer blocks (such as Snow Layers) + */ + Event> LAYERS = EventFactory.createArrayBacked(SetupEvent.class, handlers -> (manager, context) -> { + for (SetupEvent handler : handlers) { + handler.handle(manager, context); + } + }); + /** + * Register custom Strata and Geologies + */ + Event> GEOLOGY = EventFactory.createArrayBacked(SetupEvent.class, handlers -> (manager, context) -> { + for (SetupEvent handler : handlers) { + handler.handle(manager, context); + } + }); + /** + * Register custom BiomeModifiers + */ + Event> BIOME_MODIFIER = EventFactory.createArrayBacked(SetupEvent.class, handlers -> (manager, context) -> { + for (SetupEvent handler : handlers) { + handler.handle(manager, context); + } + }); + /** + * Register custom FeatureModifiers + */ + Event> FEATURES = EventFactory.createArrayBacked(SetupEvent.class, handlers -> (manager, context) -> { + for (SetupEvent handler : handlers) { + handler.handle(manager, context); + } + }); + /** + * Register custom Terrain Populators + */ + Event> TERRAIN = EventFactory.createArrayBacked(SetupEvent.class, handlers -> (manager, context) -> { + for (SetupEvent handler : handlers) { + handler.handle(manager, context); + } + }); + /** + * Register custom ColumnDecorators + * - base decorators process chunk columns early in the generation process (before biome surfaces etc) + * - feature decorators process chunk columns late in the generation process (after all features have been placed) + */ + Event> DECORATORS = EventFactory.createArrayBacked(SetupEvent.class, handlers -> (manager, context) -> { + for (SetupEvent handler : handlers) { + handler.handle(manager, context); + } + }); + + /** + * Handle the setup event. + * + * @param manager the Manager/Service being setup + * @param context the generator setup context + */ + void handle(T manager, GeneratorContext context); +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/MaterialTags.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/MaterialTags.java new file mode 100644 index 0000000..adacf73 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/MaterialTags.java @@ -0,0 +1,50 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material; + +import net.fabricmc.fabric.api.tag.TagRegistry; +import net.minecraft.block.Block; +import net.minecraft.tag.BlockTags; +import net.minecraft.tag.Tag; +import net.minecraft.util.Identifier; + +public class MaterialTags { + + public static final Tag WG_ROCK = tag("rock"); + public static final Tag WG_EARTH = tag("earth"); + public static final Tag WG_CLAY = tag("clay"); + public static final Tag WG_SEDIMENT = tag("sediment"); + public static final Tag WG_ORE = tag("ore"); + public static final Tag WG_ERODIBLE = tag("erodible"); + + public static void init() { + + } + + private static Tag tag(String name) { + return TagRegistry.create(new Identifier("terraforged", name), BlockTags::getContainer); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/GeologyManager.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/GeologyManager.java new file mode 100644 index 0000000..dd46b94 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/GeologyManager.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.geology; + +import com.terraforged.core.world.geology.Geology; +import com.terraforged.core.world.geology.Strata; +import net.minecraft.block.BlockState; +import net.minecraft.world.biome.Biome; + +public interface GeologyManager { + + StrataGenerator getStrataGenerator(); + + /** + * Register a global strata group (applies to any biome that does not have specific geology defined. + */ + void register(Strata strata); + + /** + * Register a biome specific strata group. + */ + default void register(Biome biome, Strata strata) { + register(biome, strata, false); + } + + /** + * Register a biome specific strata group. + */ + void register(Biome biome, Strata strata, boolean inheritGlobal); + + /** + * Register/replace a biome-specific geology group + */ + void register(Biome biome, Geology geology); +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/StrataConfig.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/StrataConfig.java new file mode 100644 index 0000000..58ee8b2 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/StrataConfig.java @@ -0,0 +1,64 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.geology; + +import me.dags.noise.util.NoiseUtil; + +public class StrataConfig { + + public Config soil = new Config(0, 1, 0.1F, 0.25F); + public Config sediment = new Config(0, 2, 0.05F, 0.15F); + public Config clay = new Config(0, 2, 0.05F, 0.1F); + public Config rock = new Config(10, 30, 0.1F, 1.5F); + + public static class Config { + + public int minLayers; + public int maxLayers; + public float minDepth; + public float maxDepth; + + public Config() { + } + + public Config(int minLayers, int maxLayers, float minDepth, float maxDepth) { + this.minLayers = minLayers; + this.maxLayers = maxLayers; + this.minDepth = minDepth; + this.maxDepth = maxDepth; + } + + public int getLayers(float value) { + int range = maxLayers - minLayers; + return minLayers + NoiseUtil.round(value * range); + } + + public float getDepth(float value) { + float range = maxDepth - minDepth; + return minDepth + value * range; + } + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/StrataGenerator.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/StrataGenerator.java new file mode 100644 index 0000000..ae712f4 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/geology/StrataGenerator.java @@ -0,0 +1,34 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.geology; + +import com.terraforged.core.world.geology.Strata; +import net.minecraft.block.BlockState; + +public interface StrataGenerator { + + Strata generate(int seed, int scale, StrataConfig config); +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/layer/LayerManager.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/layer/LayerManager.java new file mode 100644 index 0000000..954687b --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/layer/LayerManager.java @@ -0,0 +1,53 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.layer; + +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; + +import java.util.HashMap; +import java.util.Map; + +public class LayerManager { + + private final Map layers = new HashMap<>(); + + public LayerManager() { + register(LayerMaterial.of(Blocks.SNOW_BLOCK, Blocks.SNOW)); + } + + public void register(LayerMaterial material) { + register(material.getLayerType(), material); + } + + public void register(Block block, LayerMaterial material) { + layers.put(block, material); + } + + public LayerMaterial getMaterial(Block block) { + return layers.get(block); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/layer/LayerMaterial.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/layer/LayerMaterial.java new file mode 100644 index 0000000..3df5a90 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/layer/LayerMaterial.java @@ -0,0 +1,135 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.layer; + +import me.dags.noise.util.NoiseUtil; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.state.property.Property; +import net.minecraft.state.property.Properties; + +public class LayerMaterial { + + private static final BlockState AIR = Blocks.AIR.getDefaultState(); + + private final int min; + private final int max; + private final BlockState fullState; + private final BlockState layerState; + private final Property layerProperty; + + private LayerMaterial(BlockState fullState, BlockState layerState, Property layerProperty) { + this.layerProperty = layerProperty; + this.min = min(layerProperty); + this.max = max(layerProperty); + this.layerState = layerState; + this.fullState = fullState; + } + + public Block getLayerType() { + return layerState.getBlock(); + } + + public BlockState getFull() { + return fullState; + } + + public BlockState getState(float value) { + return getState(getLevel(value)); + } + + public BlockState getState(int level) { + if (level < min) { + return LayerMaterial.AIR; + } + if (level >= max) { + return fullState; + } + return layerState.with(layerProperty, level); + } + + public int getMin() { + return min; + } + + public int getMax() { + return max; + } + + public int getLevel(float depth) { + if (depth > 1) { + depth = getDepth(depth); + } else if (depth < 0) { + depth = 0; + } + return NoiseUtil.round(depth * max); + } + + public float getDepth(float height) { + return height - (int) height; + } + + private static int min(Property property) { + return property.getValues().stream().min(Integer::compareTo).orElse(0); + } + + private static int max(Property property) { + return property.getValues().stream().max(Integer::compareTo).orElse(0); + } + + public static LayerMaterial of(Block block) { + return of(block, Properties.LAYERS); + } + + public static LayerMaterial of(Block block, Property property) { + return of(block.getDefaultState(), block.getDefaultState(), property); + } + + public static LayerMaterial of(Block full, Block layer) { + return of(full.getDefaultState(), layer.getDefaultState()); + } + + public static LayerMaterial of(Block full, Block layer, Property property) { + return of(full.getDefaultState(), layer.getDefaultState(), property); + } + + public static LayerMaterial of(BlockState layer) { + return of(layer, Properties.LAYERS); + } + + public static LayerMaterial of(BlockState layer, Property property) { + return of(layer.with(property, max(property)), layer); + } + + public static LayerMaterial of(BlockState full, BlockState layer) { + return of(full, layer, Properties.LAYERS); + } + + public static LayerMaterial of(BlockState full, BlockState layer, Property property) { + return new LayerMaterial(full, layer, property); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/CachedState.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/CachedState.java new file mode 100644 index 0000000..f970121 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/CachedState.java @@ -0,0 +1,65 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.state; + +import net.minecraft.block.BlockState; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class CachedState extends StateSupplier { + + private static final List all = new ArrayList<>(); + + private final Supplier supplier; + + private volatile BlockState reference = null; + + public CachedState(Supplier supplier) { + this.supplier = supplier; + all.add(this); + } + + @Override + public BlockState get() { + BlockState state = reference; + if (state == null) { + state = supplier.get(); + reference = state; + } + return state; + } + + public CachedState clear() { + reference = null; + return this; + } + + public static void clearAll() { + all.forEach(CachedState::clear); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/DefaultState.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/DefaultState.java new file mode 100644 index 0000000..e40bd2d --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/DefaultState.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.state; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +public class DefaultState extends StateSupplier { + + private final Identifier name; + + private DefaultState(Identifier name) { + this.name = name; + } + + public CachedState cache() { + return new CachedState(this); + } + + @Override + public BlockState get() { + Block block = Registry.BLOCK.get(name); + return block.getDefaultState(); + } + + public static DefaultState of(String name) { + return of(new Identifier(name)); + } + + public static DefaultState of(Identifier name) { + return new DefaultState(name); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/StateSupplier.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/StateSupplier.java new file mode 100644 index 0000000..8277b9c --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/StateSupplier.java @@ -0,0 +1,42 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.state; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; + +import java.util.function.Supplier; + +public abstract class StateSupplier implements Supplier { + + public Block getBlock() { + return get().getBlock(); + } + + public BlockState getDefaultState() { + return getBlock().getDefaultState(); + } +} diff --git a/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/States.java b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/States.java new file mode 100644 index 0000000..c3e2e85 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/java/com/terraforged/api/material/state/States.java @@ -0,0 +1,48 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.api.material.state; + +public class States { + + public static final StateSupplier BEDROCK = DefaultState.of("minecraft:bedrock").cache(); + public static final StateSupplier COARSE_DIRT = DefaultState.of("minecraft:coarse_dirt").cache(); + public static final StateSupplier DIRT = DefaultState.of("minecraft:dirt").cache(); + public static final StateSupplier GRASS_BLOCK = DefaultState.of("minecraft:grass_block").cache(); + public static final StateSupplier CLAY = DefaultState.of("minecraft:clay").cache(); + public static final StateSupplier GRAVEL = DefaultState.of("minecraft:gravel").cache(); + public static final StateSupplier LAVA = DefaultState.of("minecraft:lava").cache(); + public static final StateSupplier PACKED_ICE = DefaultState.of("minecraft:packed_ice").cache(); + public static final StateSupplier RED_SANDSTONE = DefaultState.of("minecraft:red_sandstone").cache(); + public static final StateSupplier SAND = DefaultState.of("minecraft:sand").cache(); + public static final StateSupplier SANDSTONE = DefaultState.of("minecraft:sandstone").cache(); + public static final StateSupplier SNOW_BLOCK = DefaultState.of("minecraft:snow_block").cache(); + public static final StateSupplier STONE = DefaultState.of("minecraft:stone").cache(); + public static final StateSupplier WATER = DefaultState.of("minecraft:water").cache(); + + public static void invalidate() { + CachedState.clearAll(); + } +} diff --git a/TerraForgedAPI-fabric/src/main/resources/license.txt b/TerraForgedAPI-fabric/src/main/resources/license.txt new file mode 100644 index 0000000..0b31935 --- /dev/null +++ b/TerraForgedAPI-fabric/src/main/resources/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 TerraForged + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/TerraForgedMod-fabric/README.md b/TerraForgedMod-fabric/README.md new file mode 100644 index 0000000..7f0dcfb --- /dev/null +++ b/TerraForgedMod-fabric/README.md @@ -0,0 +1,56 @@ +![TerraForged Social](https://terraforged.com/curse/header.jpg) + +#### About: +TerraForged is an ambitious new terrain generator mod for Minecraft (Java Edition) attempting to + create more immersive, inspiring worlds to explore and build in. Featuring an overhaul of the + vanilla generation system, custom terrain shapes, simulated erosion, better rivers, custom + decorations, tonnes of configuration options, and more! + +#### Website(s): +[https://terraforged.com](https://terraforged.com) +[https://github.com/TerraForged](https://github.com/TerraForged) +[https://curseforge.com/../TerraForged](https://www.curseforge.com/minecraft/mc-mods/terraforged) + +#### Installation: +1. Install forge for the target version of Minecraft (ie 1.15.2) +2. Add the TerraForged mod jar to your profile's mods folder +3. Select the '`TerraForged`' world-type when creating a new world + +#### Features: +- Varied and immersive terrain +- Erosion and improved rivers +- Custom features and decoration +- Extensive configuration options & in-game GUI + +![TerraForged Gallery](https://terraforged.com/curse/gallery.jpg) + +#### FAQ: +1) "Is this compatible with mod xyz?" +_Probably! (to some degree) - TerraForged is designed to work with many of the same world-gen systems +that the majority of block & biome providing mods use. Certain biomes' terrain may not always look +exactly as their author designed but should otherwise be compatible. Feel free to report any other +compatibility issues on the issue tracker._ + +2) "How can I use this on my server?" +_When Forge supports it, you can simply set level-type=terraforged in your server.properties file. In +the meantime, you will need to create the world in single player and then copy that to your server +directory. (In both cases, TerraForged must be installed on the client and the server)._ + +3) "Will I need a super-computer to run this?!" +_No, not really - while this world generator will be a bit slower than vanilla's (on account of it +doing more work to make things look nice), it would only be apparent when first generating a chunk - +they might load in slower when moving to new parts of the world, but game performance should +otherwise be normal. A 4-core CPU should be able to handle this just fine._ + +4) "Can this be ported Fabric/Bukkit/Spigot/Sponge?" +_If someone would like to take this task on, yes - a large part of the TerraForged codebase is already +platform independent. There are certain client-side features in the forge-mod that would not translate +onto server-only APIs, but the core experience could certainly be ported. I don't intend to work on +this directly but others are very welcome._ + +5) "Will this be back-ported to older Forge versions?" +_Not by myself, no - My aim is to keep current with Forge. I'm simply not prolific enough a modder to +write and maintain for multiple versions (hats off to those who do!). Again though, others are welcome +to back-port it, if inclined to do so._ + +[View more questions on Github](https://github.com/TerraForged/TerraForged/issues?q=label:question) \ No newline at end of file diff --git a/TerraForgedMod-fabric/build.gradle b/TerraForgedMod-fabric/build.gradle new file mode 100644 index 0000000..9f8720b --- /dev/null +++ b/TerraForgedMod-fabric/build.gradle @@ -0,0 +1,84 @@ +buildscript { + repositories { + maven { url "https://maven.fabricmc.net/" } + jcenter() + } + dependencies { + classpath "net.fabricmc:fabric-loom:0.2.7-SNAPSHOT" + } +} + +apply plugin: "fabric-loom" +apply plugin: "maven-publish" +apply plugin: "eclipse" + +version = "${mc_version}-${mod_version}${getClassifier()}" +archivesBaseName = "TerraForged" + +repositories { + jcenter() + mavenCentral() +} + +dependencies { + minecraft "com.mojang:minecraft:${mc_version}" + mappings "net.fabricmc:yarn:${mc_version}+build.${yarn_build}:v2" + modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api_version}" + compile project(":Noise2D") + compile (project(":TerraForgedCore")) { + transitive false + } + compile (project(":FeatureManager-fabric")) { + transitive false + } + compile (project(":TerraForgedAPI-fabric")) { + transitive false + } +} + +task collectClasses(type: Copy) { + configurations.collectMany { it.allDependencies }.findAll{ it instanceof ProjectDependency }.each { + ProjectDependency project = (ProjectDependency) it + from("$project.dependencyProject.buildDir/classes/java/main") + } + into("build/classes/java/main") +} + +task collectResources(type: Copy) { + configurations.collectMany { it.allDependencies }.findAll{ it instanceof ProjectDependency }.each { + ProjectDependency project = (ProjectDependency) it + from("$project.dependencyProject.buildDir/resources/main") + } + into("build/resources/main") +} + +processResources { + dependsOn(collectResources) + + filesMatching("**/fabric.mod.json") { + expand( + "version": "${mod_version}${getClassifier()}", + "mc_version": mc_version + ) + } +} + +classes { + dependsOn(collectClasses) +} + +publish { + dependsOn remapJar +} + +static def getClassifier() { + if (System.getenv("GIT_TAG_NAME") != null) { + return "" + } + def buildNumber = System.getenv("BUILD_NUMBER") + if (buildNumber != null) { + return "-${buildNumber}" + } + return "" +} diff --git a/TerraForgedMod-fabric/gradlew b/TerraForgedMod-fabric/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/TerraForgedMod-fabric/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/TerraForgedMod-fabric/gradlew.bat b/TerraForgedMod-fabric/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/TerraForgedMod-fabric/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/TerraForgedMod-fabric/psd/biomes.psd b/TerraForgedMod-fabric/psd/biomes.psd new file mode 100644 index 0000000..eedc297 Binary files /dev/null and b/TerraForgedMod-fabric/psd/biomes.psd differ diff --git a/TerraForgedMod-fabric/psd/icon.png b/TerraForgedMod-fabric/psd/icon.png new file mode 100644 index 0000000..ecedcf8 Binary files /dev/null and b/TerraForgedMod-fabric/psd/icon.png differ diff --git a/TerraForgedMod-fabric/psd/terraforged.png b/TerraForgedMod-fabric/psd/terraforged.png new file mode 100644 index 0000000..0d649c9 Binary files /dev/null and b/TerraForgedMod-fabric/psd/terraforged.png differ diff --git a/TerraForgedMod-fabric/psd/terraforged.psd b/TerraForgedMod-fabric/psd/terraforged.psd new file mode 100644 index 0000000..8034e6d Binary files /dev/null and b/TerraForgedMod-fabric/psd/terraforged.psd differ diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/Log.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/Log.java new file mode 100644 index 0000000..dd5af8d --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/Log.java @@ -0,0 +1,46 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class Log { + + private static final Logger logger = LogManager.getLogger("TerraForged"); + + public static void info(String message, Object... args) { + logger.info(message, args); + } + + public static void debug(String message, Object... args) { + logger.debug(message, args); + } + + public static void err(String message, Object... args) { + logger.error(message, args); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/TerraForgedMod.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/TerraForgedMod.java new file mode 100644 index 0000000..62fa4d2 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/TerraForgedMod.java @@ -0,0 +1,82 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod; + +import com.terraforged.api.material.MaterialTags; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.feature.FeatureManager; +import com.terraforged.mod.biome.tag.BiomeTagManager; +import com.terraforged.mod.command.TerraCommand; +import com.terraforged.mod.data.DataGen; +import com.terraforged.mod.feature.tree.SaplingManager; +import com.terraforged.mod.settings.SettingsHelper; +import com.terraforged.mod.util.Environment; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.server.ServerStartCallback; +import net.fabricmc.fabric.api.event.server.ServerStopCallback; +import net.fabricmc.fabric.api.registry.CommandRegistry; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.minecraft.resource.ResourceType; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.gen.feature.Feature; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; +import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; + +/** + * Author + */ +public class TerraForgedMod implements ModInitializer { + + @Override + public void onInitialize() { + Log.info("Common setup"); + ServerStopCallback.EVENT.register(TerraForgedMod::onShutdown); + MaterialTags.init(); + TerraWorld.init(); + SaplingManager.init(); + if (Environment.isDev()) { + DataGen.dumpData(); + } + FeatureManager.registerTemplates(); + ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new BiomeTagManager()); + CommandRegistry.INSTANCE.register(false, TerraCommand::register); + } + + public static void server() { + Log.info("Setting dedicated server"); + SettingsHelper.setDedicatedServer(); + } + + private static void onShutdown(MinecraftServer server) { + ThreadPool.shutdownCurrent(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/TerraWorld.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/TerraWorld.java new file mode 100644 index 0000000..817225c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/TerraWorld.java @@ -0,0 +1,126 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod; + +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.ChunkGeneratorFactory; +import com.terraforged.mod.chunk.TerraChunkGenerator; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.chunk.TerraGenSettings; +import com.terraforged.mod.chunk.test.TestChunkGenerator; +import com.terraforged.mod.gui.SettingsScreen; +import com.terraforged.mod.settings.SettingsHelper; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.CreateWorldScreen; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; +import net.minecraft.world.WorldType; +import net.minecraft.world.biome.provider.OverworldBiomeProviderSettings; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.OverworldGenSettings; +import net.minecraft.world.level.LevelGeneratorType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import java.util.HashSet; +import java.util.Set; + +public class TerraWorld extends LevelGeneratorType { + public static final int VERSION = 1; + + private static final Set types = new HashSet<>(); + public static final TerraWorld TERRA = new TerraWorld("terraforged", TerraChunkGenerator::new); + public static final TerraWorld TEST = new TerraWorld("terratest", TestChunkGenerator::new); + + private final ChunkGeneratorFactory factory; + + public TerraWorld(String name, ChunkGeneratorFactory factory) { + super(name); + this.factory = factory; + setCustomOptions(true); + TerraWorld.types.add(this); + } + + @Override + public double getHorizon(World world) { + return 0; + } + + @Override + public float getCloudHeight() { + return 260.0F; + } + + @Override + public ChunkGenerator createChunkGenerator(World world) { + if (world.getDimension().getType() != DimensionType.OVERWORLD) { + return world.getDimension().createChunkGenerator(); + } + + Log.debug("Creating {} generator", world.getDimension().getType()); + + int version = SettingsHelper.getVersion(world.getWorldInfo()); + TerraSettings settings = SettingsHelper.getSettings(world); + SettingsHelper.syncSettings(world.getWorldInfo(), settings, version); + + Terrains terrains = Terrains.create(settings); + + OverworldGenSettings genSettings = new TerraGenSettings(settings.structures); + OverworldBiomeProviderSettings biomeSettings = new OverworldBiomeProviderSettings(world.getWorldInfo()); + biomeSettings.setGeneratorSettings(genSettings); + world.getWorldInfo().setGeneratorOptions(NBTHelper.serializeCompact(settings)); + + TerraContext context = new TerraContext(world, terrains, settings); + BiomeProvider biomeProvider = new BiomeProvider(context); + + return getGeneratorFactory().create(context, biomeProvider, genSettings); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void onCustomizeButton(Minecraft mc, CreateWorldScreen gui) { + mc.displayGuiScreen(new SettingsScreen(gui)); + } + + public ChunkGeneratorFactory getGeneratorFactory() { + return factory; + } + + public static void init() { + Log.info("Registered world type(s)"); + } + + public static boolean isTerraWorld(IWorld world) { + if (world instanceof World) { + return types.contains(((World) world).getWorldType()); + } + return false; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ColdSteppe.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ColdSteppe.java new file mode 100644 index 0000000..7645ea9 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ColdSteppe.java @@ -0,0 +1,93 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldView; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; + +public class ColdSteppe extends BiomeVariant { + + public ColdSteppe() { + super((new Settings()).configureSurfaceBuilder(SurfaceBuilder.GIANT_TREE_TAIGA, SurfaceBuilder.GRASS_CONFIG) + .precipitation(Precipitation.SNOW).category(Biome.Category.TAIGA).depth(0.2F).scale(0.25F).temperature(0.2F).downfall(0.1F) + .waterColor(4159204).waterFogColor(329011).parent(null)); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + // DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addDungeons(this); + DefaultBiomeFeatures.addLargeFerns(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultDisks(this); + // DefaultBiomeFeatures.addTaigaConifers(this); + // DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addSavannaGrass(this); + // DefaultBiomeFeatures.addMushrooms(this); + // DefaultBiomeFeatures.addReedsAndPumpkins(this); + // DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addSweetBerryBushes(this); + DefaultBiomeFeatures.addFrozenTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.FOX, 8, 2, 4)); + this.addSpawn(EntityCategory.AMBIENT, new Biome.SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public boolean canSetSnow(WorldView worldIn, BlockPos pos) { + return false; + } + + @Override + public boolean canSetIce(WorldView worldIn, BlockPos pos) { + return false; + } + + @Override + public Biome getBase() { + return Biomes.TAIGA; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/Marshland.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/Marshland.java new file mode 100644 index 0000000..f833842 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/Marshland.java @@ -0,0 +1,109 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.decorator.CountChanceDecoratorConfig; +import net.minecraft.world.gen.decorator.CountDecoratorConfig; +import net.minecraft.world.gen.decorator.Decorator; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; + +public class Marshland extends BiomeVariant { + + public Marshland() { + super((new Settings()).configureSurfaceBuilder(SurfaceBuilder.SWAMP, SurfaceBuilder.GRASS_CONFIG).precipitation(Precipitation.RAIN) + .category(Category.SWAMP).depth(0.2F).scale(0.2F).temperature(0.8F).downfall(0.4F).waterColor(6388580).waterFogColor(2302743) + .parent(null)); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + DefaultBiomeFeatures.addDungeons(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultDisks(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addSavannaTallGrass(this); + DefaultBiomeFeatures.addSavannaTallGrass(this); + DefaultBiomeFeatures.addSavannaTallGrass(this); + DefaultBiomeFeatures.addSavannaTallGrass(this); + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addSavannaGrass(this); + DefaultBiomeFeatures.addDefaultVegetation(this); + Marshland.addSwampVegetation(this); + DefaultBiomeFeatures.addFrozenTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.FOX, 8, 2, 4)); + this.addSpawn(EntityCategory.AMBIENT, new SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.WITCH, 5, 1, 1)); + } + + public int getGrassColor(double p_225528_1_, double p_225528_3_) { + double d0 = FOLIAGE_NOISE.sample(p_225528_1_ * 0.0225D, p_225528_3_ * 0.0225D, false); + return d0 < -0.1D ? 5011004 : 6975545; + } + + public int getFoliageColor() { + return 6975545; + } + + @Override + public Biome getBase() { + return Biomes.SWAMP; + } + + private static void addSwampVegetation(Biome biome) { + biome.addFeature(GenerationStep.Feature.VEGETAL_DECORATION, Feature.RANDOM_PATCH.configure(DefaultBiomeFeatures.LILY_PAD_CONFIG) + .createDecoratedFeature(Decorator.COUNT_HEIGHTMAP_DOUBLE.configure(new CountDecoratorConfig(4)))); + biome.addFeature(GenerationStep.Feature.VEGETAL_DECORATION, Feature.RANDOM_PATCH.configure(DefaultBiomeFeatures.DEAD_BUSH_CONFIG) + .createDecoratedFeature(Decorator.COUNT_HEIGHTMAP_DOUBLE.configure(new CountDecoratorConfig(1)))); + biome.addFeature(GenerationStep.Feature.VEGETAL_DECORATION, Feature.RANDOM_PATCH.configure(DefaultBiomeFeatures.LILY_PAD_CONFIG) + .createDecoratedFeature(Decorator.COUNT_HEIGHTMAP_DOUBLE.configure(new CountDecoratorConfig(4)))); + biome.addFeature(GenerationStep.Feature.VEGETAL_DECORATION, + Feature.RANDOM_PATCH.configure(DefaultBiomeFeatures.BROWN_MUSHROOM_CONFIG) + .createDecoratedFeature(Decorator.COUNT_CHANCE_HEIGHTMAP.configure(new CountChanceDecoratorConfig(8, 0.25F)))); + biome.addFeature(GenerationStep.Feature.VEGETAL_DECORATION, + Feature.RANDOM_PATCH.configure(DefaultBiomeFeatures.RED_MUSHROOM_CONFIG) + .createDecoratedFeature(Decorator.COUNT_CHANCE_HEIGHTMAP_DOUBLE.configure(new CountChanceDecoratorConfig(8, 0.125F)))); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ModBiomes.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ModBiomes.java new file mode 100644 index 0000000..2d3630b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ModBiomes.java @@ -0,0 +1,51 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; + +import java.util.ArrayList; + +public class ModBiomes { + + private static final ArrayList biomes = new ArrayList<>(); + + public static final Biome COLD_STEPPE = register("cold_steppe", new ColdSteppe()); + public static final Biome SAVANNA_SCRUB = register("savanna_scrub", new SavannaScrub()); + public static final Biome SHATTERED_SAVANNA_SCRUB = register("shattered_savanna_scrub", new ShatteredSavannaScrub()); + public static final Biome SNOWY_TAIGA_SCRUB = register("snowy_taiga_scrub", new SnowyTaigaScrub()); + public static final Biome STEPPE = register("steppe", new Steppe()); + public static final Biome TAIGA_SCRUB = register("taiga_scrub", new TaigaScrub()); + public static final Biome WARM_BEACH = register("warm_beach", new WarmBeach()); + public static final Biome MARSHLAND = register("marshland", new Marshland()); + + private static Biome register(String name, BiomeVariant biome) { + return Registry.register(Registry.BIOME, new Identifier("terraforged", name), biome); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/SavannaScrub.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/SavannaScrub.java new file mode 100644 index 0000000..72cb96b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/SavannaScrub.java @@ -0,0 +1,114 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Heightmap; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.surfacebuilder.DefaultSurfaceBuilder; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; +import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig; + +import java.util.Random; + +public class SavannaScrub extends BiomeVariant { + + public SavannaScrub() { + super((new Settings()).configureSurfaceBuilder(new Builder(), SurfaceBuilder.GRASS_CONFIG).precipitation(Precipitation.NONE) + .category(Biome.Category.SAVANNA).depth(0.125F).scale(0.05F).temperature(1.2F).downfall(0.0F).waterColor(4159204) + .waterFogColor(329011).parent(null)); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + // DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addDungeons(this); + DefaultBiomeFeatures.addSavannaTallGrass(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultDisks(this); + // DefaultBiomeFeatures.addSavannaTrees(this); + DefaultBiomeFeatures.addExtraDefaultFlowers(this); + + // func_222339_L - add grasses - add this a few times since there are no trees + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addSavannaGrass(this); + + DefaultBiomeFeatures.addDefaultMushrooms(this); + DefaultBiomeFeatures.addDefaultVegetation(this); + // DefaultBiomeFeatures.addSprings(this); + // DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.HORSE, 1, 2, 6)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.DONKEY, 1, 1, 1)); + this.addSpawn(EntityCategory.AMBIENT, new SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public Biome getBase() { + return Biomes.SAVANNA; + } + + private static class Builder extends DefaultSurfaceBuilder { + + private Builder() { + super(TernarySurfaceConfig::deserialize); + } + + @Override + public void generate(Random random, Chunk chunkIn, Biome biomeIn, int x, int z, int startHeight, double noise, BlockState defaultBlock, + BlockState defaultFluid, int seaLevel, long seed, TernarySurfaceConfig config) { + super.generate(random, chunkIn, biomeIn, x, z, startHeight, noise, defaultBlock, defaultFluid, seaLevel, seed, config); + BlockPos.Mutable pos = new BlockPos.Mutable(); + if (random.nextInt(5) > 0) { + int dx = x & 15; + int dz = z & 15; + int y = chunkIn.sampleHeightmap(Heightmap.Type.MOTION_BLOCKING, dx, dz); + if (y > seaLevel) { + pos.set(dx, y, dz); + //chunkIn.setBlockState(pos, Blocks.SAND.getDefaultState(), false); //todo need tweak + } + } + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ShatteredSavannaScrub.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ShatteredSavannaScrub.java new file mode 100644 index 0000000..915115c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/ShatteredSavannaScrub.java @@ -0,0 +1,118 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.block.BlockState; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Heightmap; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.surfacebuilder.DefaultSurfaceBuilder; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; +import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig; + +import java.util.Random; + +public class ShatteredSavannaScrub extends BiomeVariant { + + public ShatteredSavannaScrub() { + super((new Settings()).configureSurfaceBuilder(new Builder(), SurfaceBuilder.GRASS_CONFIG).precipitation(Precipitation.NONE) + .category(Biome.Category.SAVANNA).depth(0.3625F).scale(1.225F).temperature(1.1F).downfall(0.0F).waterColor(4159204) + .waterFogColor(329011).parent("terraforged:savanna_scrub")); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + // DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addDungeons(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultDisks(this); + // DefaultBiomeFeatures.addShatteredSavannaTrees(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + + // func_222314_K - addGrasses - add this a few times since there are no trees + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addSavannaGrass(this); + + DefaultBiomeFeatures.addDefaultMushrooms(this); + DefaultBiomeFeatures.addDefaultVegetation(this); + // DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addFrozenTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.HORSE, 1, 2, 6)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.DONKEY, 1, 1, 1)); + this.addSpawn(EntityCategory.AMBIENT, new SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public boolean hasParent() { + return true; + } + + @Override + public Biome getBase() { + return Biomes.SHATTERED_SAVANNA; + } + + private static class Builder extends DefaultSurfaceBuilder { + + private Builder() { + super(TernarySurfaceConfig::deserialize); + } + + @Override + public void generate(Random random, Chunk chunkIn, Biome biomeIn, int x, int z, int startHeight, double noise, BlockState defaultBlock, + BlockState defaultFluid, int seaLevel, long seed, TernarySurfaceConfig config) { + SurfaceBuilder.SHATTERED_SAVANNA + .generate(random, chunkIn, biomeIn, x, z, startHeight, noise, defaultBlock, defaultFluid, seaLevel, seed, config); + BlockPos.Mutable pos = new BlockPos.Mutable(); + if (random.nextInt(5) > 0) { + int dx = x & 15; + int dz = z & 15; + int y = chunkIn.sampleHeightmap(Heightmap.Type.MOTION_BLOCKING, dx, dz); + if (y > seaLevel) { + pos.set(dx, y, dz); + // chunkIn.setBlockState(pos, Blocks.SAND.getDefaultState(), false); + } + } + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/SnowyTaigaScrub.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/SnowyTaigaScrub.java new file mode 100644 index 0000000..de57b8b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/SnowyTaigaScrub.java @@ -0,0 +1,81 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; + +public class SnowyTaigaScrub extends BiomeVariant { + + public SnowyTaigaScrub() { + super(new Settings().configureSurfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.GRASS_CONFIG).precipitation(Precipitation.SNOW) + .category(Category.TAIGA).depth(0.2F).scale(0.2F).temperature(-0.5F).downfall(0.4F).waterColor(4020182).waterFogColor(329011) + .parent(null)); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + // DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addDungeons(this); + DefaultBiomeFeatures.addLargeFerns(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultDisks(this); + // DefaultBiomeFeatures.addTaigaConifers(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addTaigaGrass(this); + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addDefaultMushrooms(this); + DefaultBiomeFeatures.addDefaultVegetation(this); + // DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addSweetBerryBushesSnowy(this); + DefaultBiomeFeatures.addFrozenTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.FOX, 8, 2, 4)); + this.addSpawn(EntityCategory.AMBIENT, new SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public Biome getBase() { + return Biomes.SNOWY_TAIGA; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/Steppe.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/Steppe.java new file mode 100644 index 0000000..09fc59c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/Steppe.java @@ -0,0 +1,94 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldView; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; + +public class Steppe extends BiomeVariant { + + protected Steppe() { + super((new Settings()).configureSurfaceBuilder(SurfaceBuilder.GIANT_TREE_TAIGA, SurfaceBuilder.GRASS_CONFIG).precipitation(Precipitation.SNOW) + .category(Category.SAVANNA).depth(0.2F).scale(0.2F).temperature(0.7F).downfall(0.1F).waterColor(4159204).waterFogColor(329011) + .parent(null)); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + // DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addDungeons(this); + // DefaultBiomeFeatures.addTaigaRocks(this); + // DefaultBiomeFeatures.addTaigaLargeFerns(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultDisks(this); + // extra grasses as no trees/ferns + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addSavannaGrass(this); + // DefaultBiomeFeatures.func_222285_H(this); + // DefaultBiomeFeatures.addDefaultFlowers(this); + // DefaultBiomeFeatures.addMushrooms(this); + // DefaultBiomeFeatures.addReedsAndPumpkins(this); + // DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addFrozenTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityCategory.AMBIENT, new SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE_VILLAGER, 25, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.WITCH, 5, 1, 1)); + + } + + @Override + public boolean canSetIce(WorldView world, BlockPos blockPos) { + return false; + } + + @Override + public boolean canSetSnow(WorldView worldView, BlockPos blockPos) { + return false; + } + + @Override + public Biome getBase() { + return Biomes.SAVANNA; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/TaigaScrub.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/TaigaScrub.java new file mode 100644 index 0000000..cbcab24 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/TaigaScrub.java @@ -0,0 +1,85 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; + +public class TaigaScrub extends BiomeVariant { + + public TaigaScrub() { + super((new Settings()).configureSurfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.GRASS_CONFIG).precipitation(Precipitation.RAIN) + .category(Category.TAIGA).depth(0.2F).scale(0.2F).temperature(0.25F).downfall(0.8F).waterColor(4159204).waterFogColor(329011) + .parent(null)); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + // DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addDungeons(this); + DefaultBiomeFeatures.addLargeFerns(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultDisks(this); + // DefaultBiomeFeatures.addTaigaConifers(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addSavannaGrass(this); + + // extra grass since there are no trees + DefaultBiomeFeatures.addForestGrass(this); + DefaultBiomeFeatures.addForestGrass(this); + + DefaultBiomeFeatures.addDefaultVegetation(this); + // DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addSweetBerryBushes(this); + DefaultBiomeFeatures.addFrozenTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityCategory.CREATURE, new SpawnEntry(EntityType.FOX, 8, 2, 4)); + this.addSpawn(EntityCategory.AMBIENT, new SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new SpawnEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public Biome getBase() { + return Biomes.TAIGA; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/WarmBeach.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/WarmBeach.java new file mode 100644 index 0000000..46e5b00 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/WarmBeach.java @@ -0,0 +1,79 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityCategory; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.feature.BuriedTreasureFeatureConfig; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.MineshaftFeature; +import net.minecraft.world.gen.feature.MineshaftFeatureConfig; +import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder; + +public class WarmBeach extends BiomeVariant { + + public WarmBeach() { + super((new Settings()).configureSurfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.SAND_CONFIG).precipitation(Precipitation.RAIN) + .category(Category.BEACH).depth(-0.5F).scale(0.1F).temperature(1.5F).downfall(0.5F).waterColor(4445678).waterFogColor(270131) + .parent(null)); + this.addStructureFeature(Feature.MINESHAFT.configure(new MineshaftFeatureConfig(0.004D, MineshaftFeature.Type.NORMAL))); + this.addStructureFeature(Feature.BURIED_TREASURE.configure(new BuriedTreasureFeatureConfig(0.01F))); + DefaultBiomeFeatures.addLandCarvers(this); + DefaultBiomeFeatures.addDefaultStructures(this); + DefaultBiomeFeatures.addDungeons(this); + DefaultBiomeFeatures.addMineables(this); + DefaultBiomeFeatures.addDefaultOres(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addDefaultGrass(this); + DefaultBiomeFeatures.addDefaultMushrooms(this); + DefaultBiomeFeatures.addDefaultVegetation(this); + DefaultBiomeFeatures.addFrozenTopLayer(this); + this.addSpawn(EntityCategory.CREATURE, new Biome.SpawnEntry(EntityType.TURTLE, 5, 2, 5)); + this.addSpawn(EntityCategory.AMBIENT, new Biome.SpawnEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public Biome.TemperatureGroup getTemperatureGroup() { + return TemperatureGroup.WARM; + } + + @Override + public Biome getBase() { + return Biomes.WARM_OCEAN; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/AbstractBiomeMap.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/AbstractBiomeMap.java new file mode 100644 index 0000000..e41c7ce --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/AbstractBiomeMap.java @@ -0,0 +1,220 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.common.collect.Sets; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.ModBiomes; +import com.terraforged.mod.biome.provider.BiomeHelper; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public abstract class AbstractBiomeMap implements BiomeMap { + + private final Biome[][] beach; + private final Biome[][] river; + private final Biome[][] wetland; + private final Biome[][] ocean; + private final Biome[][] deepOcean; + + protected final DefaultBiome defaultLand = this::defaultBiome; + protected final DefaultBiome defaultBeach = this::defaultBeach; + protected final DefaultBiome defaultRiver = this::defaultRiver; + protected final DefaultBiome defaultWetland = this::defaultWetland; + protected final DefaultBiome defaultOcean = this::defaultOcean; + protected final DefaultBiome defaultDeepOcean = this::defaultDeepOcean; + + protected AbstractBiomeMap(BiomeMapBuilder builder) { + river = builder.rivers(); + beach = builder.beaches(); + ocean = builder.oceans(); + wetland = builder.wetlands(); + deepOcean = builder.deepOceans(); + } + + @Override + public Biome getBeach(float temperature, float moisture, float shape) { + return get(beach, getCategory(temperature), shape, temperature, defaultBeach); + } + + @Override + public Biome getRiver(float temperature, float moisture, float shape) { + return get(river, getCategory(temperature), shape, temperature, defaultRiver); + } + + @Override + public Biome getWetland(float temperature, float moisture, float shape) { + return get(wetland, getCategory(temperature), shape, temperature, defaultWetland); + } + + @Override + public Biome getOcean(float temperature, float moisture, float shape) { + return get(ocean, getCategory(temperature), shape, temperature, defaultOcean); + } + + @Override + public Biome getDeepOcean(float temperature, float moisture, float shape) { + return get(deepOcean, getCategory(temperature), shape, temperature, defaultDeepOcean); + } + + @Override + public Set getOceanBiomes(Biome.TemperatureGroup temp) { + return Sets.newHashSet(ocean[temp.ordinal() - 1]); + } + + @Override + public Set getDeepOceanBiomes(Biome.TemperatureGroup temp) { + return Sets.newHashSet(deepOcean[temp.ordinal() - 1]); + } + + @Override + public Set getRivers(Biome.TemperatureGroup temp) { + return Sets.newHashSet(river[temp.ordinal() - 1]); + } + + @Override + public JsonObject toJson() { + JsonObject root = new JsonObject(); + root.add("rivers", collect(river)); + root.add("wetland", collect(wetland)); + root.add("beaches", collect(beach)); + root.add("oceans", collect(ocean)); + root.add("deepOceans", collect(deepOcean)); + return root; + } + + private JsonObject collect(Biome[][] biomes) { + JsonObject root = new JsonObject(); + for (Biome.TemperatureGroup temp : Biome.TemperatureGroup.values()) { + if (temp == Biome.TemperatureGroup.OCEAN) { + continue; + } + JsonArray array = new JsonArray(); + Biome[] group = biomes[temp.ordinal() - 1]; + if (group != null) { + Set set = new HashSet<>(); + Collections.addAll(set, group); + set.stream().map(BiomeHelper::getId).sorted().forEach(array::add); + } + root.add(temp.name(), array); + } + return root; + } + + + protected Biome.TemperatureGroup getCategory(float value) { + if (value < 0.25) { + return Biome.TemperatureGroup.COLD; + } + if (value > 0.75) { + return Biome.TemperatureGroup.WARM; + } + return Biome.TemperatureGroup.MEDIUM; + } + + protected Biome defaultBeach(float temperature) { + if (temperature < 0.25) { + return Biomes.SNOWY_BEACH; + } + if (temperature > 0.75) { + return ModBiomes.WARM_BEACH; + } + return Biomes.BEACH; + } + + protected Biome defaultRiver(float temperature) { + if (temperature < 0.15) { + return Biomes.FROZEN_RIVER; + } + return Biomes.RIVER; + } + + protected Biome defaultWetland(float temperature) { + if (temperature < 0.15) { + return ModBiomes.TAIGA_SCRUB; + } + return ModBiomes.MARSHLAND; + } + + protected Biome defaultOcean(float temperature) { + if (temperature < 0.3) { + return Biomes.FROZEN_OCEAN; + } + if (temperature > 0.7) { + return Biomes.WARM_OCEAN; + } + return Biomes.OCEAN; + } + + protected Biome defaultDeepOcean(float temperature) { + if (temperature < 0.3) { + return Biomes.DEEP_FROZEN_OCEAN; + } + if (temperature > 0.7) { + return Biomes.DEEP_WARM_OCEAN; + } + return Biomes.DEEP_OCEAN; + } + + protected Biome defaultBiome(float temperature) { + if (temperature < 0.3) { + return ModBiomes.TAIGA_SCRUB; + } + if (temperature > 0.7) { + return ModBiomes.SAVANNA_SCRUB; + } + return Biomes.PLAINS; + } + + protected Biome get(Biome[][] group, Biome.TemperatureGroup category, float shape, float temp, DefaultBiome def) { + return get(group, category.ordinal() - 1, shape, temp, def); + } + + protected Biome get(Biome[][] group, BiomeType type, float shape, float temp, DefaultBiome def) { + return get(group, type.ordinal(), shape, temp, def); + } + + protected Biome get(Biome[][] group, int ordinal, float shape, float temp, DefaultBiome def) { + if (ordinal >= group.length) { + return def.getDefaultBiome(temp); + } + + Biome[] biomes = group[ordinal]; + if (biomes == null || biomes.length == 0) { + return def.getDefaultBiome(temp); + } + + int index = NoiseUtil.round((biomes.length - 1) * shape); + return biomes[index]; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BasicBiomeMap.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BasicBiomeMap.java new file mode 100644 index 0000000..37f62e8 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BasicBiomeMap.java @@ -0,0 +1,82 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.common.collect.Sets; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.provider.BiomeHelper; +import net.minecraft.world.biome.Biome; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class BasicBiomeMap extends AbstractBiomeMap { + + private final Biome[][] biomeTypes; + + public BasicBiomeMap(BiomeMapBuilder builder) { + super(builder); + biomeTypes = builder.biomeList(); + } + + @Override + public List getAllBiomes(BiomeType type) { + if (type.ordinal() >= biomeTypes.length) { + return Collections.emptyList(); + } + return Arrays.asList(biomeTypes[type.ordinal()]); + } + + @Override + public Set getBiomes(BiomeType type) { + if (type.ordinal() >= biomeTypes.length) { + return Collections.emptySet(); + } + return Sets.newHashSet(biomeTypes[type.ordinal()]); + } + + @Override + public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) { + return get(biomeTypes, type, shape, temperature, defaultLand); + } + + @Override + public JsonObject toJson() { + JsonObject groups = new JsonObject(); + for (BiomeType type : BiomeType.values()) { + JsonArray group = new JsonArray(); + getBiomes(type).stream().map(BiomeHelper::getId).sorted().forEach(group::add); + groups.add(type.name(), group); + } + JsonObject root = super.toJson(); + root.add("biomes", groups); + return root; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeGroup.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeGroup.java new file mode 100644 index 0000000..98fd7cc --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeGroup.java @@ -0,0 +1,38 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.terraforged.core.util.grid.FixedGrid; +import net.minecraft.world.biome.Biome; + +public class BiomeGroup { + + public final FixedGrid biomes; + + public BiomeGroup(FixedGrid biomes) { + this.biomes = biomes; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java new file mode 100644 index 0000000..4c0da8d --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java @@ -0,0 +1,81 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.gson.JsonElement; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.world.biome.Biome; + +import java.util.List; +import java.util.Set; + +public interface BiomeMap { + + Biome getBeach(float temperature, float moisture, float shape); + + Biome getRiver(float temperature, float moisture, float shape); + + Biome getWetland(float temperature, float moisture, float shape); + + Biome getOcean(float temperature, float moisture, float shape); + + Biome getDeepOcean(float temperature, float moisture, float shape); + + Biome getBiome(BiomeType type, float temperature, float moisture, float shape); + + default Biome getBiome(Cell cell) { + return getBiome(cell.biomeType, cell.temperature, cell.moisture, cell.biome); + } + + List getAllBiomes(BiomeType type); + + Set getBiomes(BiomeType type); + + Set getRivers(Biome.TemperatureGroup temp); + + Set getOceanBiomes(Biome.TemperatureGroup temp); + + Set getDeepOceanBiomes(Biome.TemperatureGroup temp); + + JsonElement toJson(); + + interface Builder { + + Builder addBeach(Biome biome, int count); + + Builder addRiver(Biome biome, int count); + + Builder addWetland(Biome biome, int count); + + Builder addOcean(Biome biome, int count); + + Builder addBiome(BiomeType type, Biome biome, int count); + + BiomeMap build(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeMapBuilder.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeMapBuilder.java new file mode 100644 index 0000000..265dab9 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomeMapBuilder.java @@ -0,0 +1,188 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.terraforged.core.util.grid.FixedGrid; +import com.terraforged.core.world.biome.BiomeData; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.provider.BiomeHelper; +import com.terraforged.mod.util.ListUtils; +import net.minecraft.world.biome.Biome; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public class BiomeMapBuilder implements BiomeMap.Builder { + + private final Map> rivers = new HashMap<>(); + private final Map> wetlands = new HashMap<>(); + private final Map> beaches = new HashMap<>(); + private final Map> oceans = new HashMap<>(); + private final Map> deepOceans = new HashMap<>(); + private final Map> map = new EnumMap<>(BiomeType.class); + private final Map dataMap = new HashMap<>(); + + private final int gridSize; + private final Function constructor; + + BiomeMapBuilder(Function constructor, int gridSize, List biomes) { + this.constructor = constructor; + this.gridSize = gridSize; + + for (BiomeData data : biomes) { + dataMap.put((Biome) data.reference, data); + } + } + + @Override + public BiomeMapBuilder addOcean(Biome biome, int count) { + Biome.TemperatureGroup category = BiomeHelper.getTemperatureGroup(biome); + if (biome.getDepth() < -1) { + add(deepOceans.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + } else { + add(oceans.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + } + return this; + } + + @Override + public BiomeMap.Builder addBeach(Biome biome, int count) { + Biome.TemperatureGroup category = BiomeHelper.getTemperatureGroup(biome); + add(beaches.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + return this; + } + + @Override + public BiomeMapBuilder addRiver(Biome biome, int count) { + Biome.TemperatureGroup category = BiomeHelper.getTemperatureGroup(biome); + add(rivers.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + return this; + } + + @Override + public BiomeMapBuilder addWetland(Biome biome, int count) { + Biome.TemperatureGroup category = BiomeHelper.getTemperatureGroup(biome); + add(wetlands.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + return this; + } + + @Override + public BiomeMapBuilder addBiome(BiomeType type, Biome biome, int count) { + add(map.computeIfAbsent(type, t -> new ArrayList<>()), biome, count); + return this; + } + + @Override + public BiomeMap build() { + return constructor.apply(this); + } + + Biome[][] rivers() { + return collectTemps(rivers); + } + + Biome[][] wetlands() { + return collectTemps(wetlands); + } + + Biome[][] beaches() { + return collectTemps(beaches); + } + + Biome[][] oceans() { + return collectTemps(oceans); + } + + Biome[][] deepOceans() { + return collectTemps(deepOceans); + } + + Biome[][] biomeList() { + return collectTypes(map); + } + + BiomeGroup[] biomeGroups() { + BiomeGroup[] biomes = new BiomeGroup[BiomeType.values().length]; + + Function moisture = b -> dataMap.get(b).rainfall; + Function temperature = b -> dataMap.get(b).temperature; + for (BiomeType type : BiomeType.values()) { + List list = map.getOrDefault(type, Collections.emptyList()); + if (list.isEmpty()) { + continue; + } + FixedGrid grid = FixedGrid.generate(gridSize, list, moisture, temperature); + biomes[type.ordinal()] = new BiomeGroup(grid); + } + + return biomes; + } + + private void add(List list, Biome biome, int count) { + for (int i = 0; i < count; i++) { + list.add(biome); + } + } + + private Biome[][] collectTemps(Map> map) { + Biome[][] biomes = new Biome[3][]; + for (Biome.TemperatureGroup category : Biome.TemperatureGroup.values()) { + if (category == Biome.TemperatureGroup.OCEAN) { + continue; + } + List list = map.getOrDefault(category, Collections.emptyList()); + list = ListUtils.minimize(list); + list.sort(Comparator.comparing(BiomeHelper::getId)); + biomes[category.ordinal() - 1] = list.toArray(new Biome[0]); + } + return biomes; + } + + private Biome[][] collectTypes(Map> map) { + Biome[][] biomes = new Biome[BiomeType.values().length][]; + for (BiomeType type : BiomeType.values()) { + List list = map.getOrDefault(type, Collections.emptyList()); + list = ListUtils.minimize(list); + list.sort(Comparator.comparing(BiomeHelper::getId)); + biomes[type.ordinal()] = list.toArray(new Biome[0]); + } + return biomes; + } + + public static BiomeMap.Builder basic(List biomes) { + return new BiomeMapBuilder(BasicBiomeMap::new, 0, biomes); + } + + public static BiomeMap.Builder grid(int size, List biomes) { + return new BiomeMapBuilder(GridBiomeMap::new, size, biomes); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomePredicate.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomePredicate.java new file mode 100644 index 0000000..4755a66 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/BiomePredicate.java @@ -0,0 +1,101 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.terraforged.core.world.biome.BiomeData; +import com.terraforged.mod.biome.provider.BiomeHelper; +import net.minecraft.world.biome.Biome; + +import java.util.function.BiPredicate; + +public interface BiomePredicate { + + boolean test(BiomeData data, Biome biome); + + default boolean test(BiomeData data) { + return test(data, (Biome) data.reference); + } + + default BiomePredicate and(BiomePredicate other) { + return (d, b) -> this.test(d, b) && other.test(d, b); + } + + default BiomePredicate not(BiomePredicate other) { + return (d, b) -> this.test(d, b) && !other.test(d, b); + } + + default BiomePredicate or(BiomePredicate other) { + return (d, b) -> this.test(d, b) || other.test(d, b); + } + + static BiomePredicate name(String... name) { + return (d, b) -> anyMatch(BiomeHelper.getId(b), name, String::contains); + } + + static BiomePredicate type(Biome.Category... categories) { + return (d, b) -> anyMatch(b.getCategory(), categories, (c1, c2) -> c1 == c2); + } + + static BiomePredicate rain(double min, double max) { + return (d, b) -> d.rainfall >= min && d.rainfall <= max; + } + + static BiomePredicate rainType(Biome.Precipitation ... rainTypes) { + return (d, b) -> anyMatch(b.getPrecipitation(), rainTypes, (c1, c2) -> c1 == c2); + } + + static BiomePredicate temp(double min, double max) { + return (d, b) -> d.temperature >= min && d.temperature <= max; + } + + static BiomePredicate depth(double min, double max) { + return (d, b) -> b.getDepth() >= min && b.getDepth() <= max; + } + + static boolean anyMatch(T value, T[] test, BiPredicate tester) { + for (T t : test) { + if (tester.test(value, t)) { + return true; + } + } + return false; + } + + BiomePredicate COAST = type(Biome.Category.BEACH); + BiomePredicate WETLAND = type(Biome.Category.SWAMP); + BiomePredicate DESERT = type(Biome.Category.DESERT).or(temp(0.9, 2).and(rain(-1, 0.2))); + BiomePredicate SAVANNA = type(Biome.Category.SAVANNA).or(temp(0.8, 2).and(rain(-1, 0.4))); + BiomePredicate MESA = type(Biome.Category.MESA); + BiomePredicate STEPPE = name("steppe").and(temp(0.3, 1)); + BiomePredicate COLD_STEPPE = name("steppe").and(temp(-1, 0.3)); + BiomePredicate GRASSLAND = type(Biome.Category.PLAINS); + BiomePredicate TEMPERATE_FOREST = type(Biome.Category.FOREST).and(rain(-1, 0.81)); + BiomePredicate TEMPERATE_RAINFOREST = type(Biome.Category.FOREST).and(rain(0.8, 2)); + BiomePredicate TROPICAL_RAINFOREST = type(Biome.Category.JUNGLE); + BiomePredicate TAIGA = type(Biome.Category.TAIGA).or(temp(0.19, 0.35)).not(rainType(Biome.Precipitation.SNOW)); + BiomePredicate TUNDRA = type(Biome.Category.ICY).or(temp(-1, 0.21).and(rainType(Biome.Precipitation.SNOW))); + BiomePredicate MOUNTAIN = type(Biome.Category.EXTREME_HILLS).or(name("mountain")); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/DefaultBiome.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/DefaultBiome.java new file mode 100644 index 0000000..857ffb4 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/DefaultBiome.java @@ -0,0 +1,12 @@ +package com.terraforged.mod.biome.map; + +import net.minecraft.world.biome.Biome; + +public interface DefaultBiome { + + Biome getBiome(float temperature); + + default Biome getDefaultBiome(float temperature) { + return getBiome(temperature).delegate.get(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/GridBiomeMap.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/GridBiomeMap.java new file mode 100644 index 0000000..7b245f2 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/map/GridBiomeMap.java @@ -0,0 +1,128 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.util.grid.FixedList; +import com.terraforged.core.util.grid.MappedList; +import com.terraforged.core.world.biome.BiomeType; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class GridBiomeMap extends AbstractBiomeMap { + + private final BiomeGroup[] biomeTypes; + + GridBiomeMap(BiomeMapBuilder builder) { + super(builder); + biomeTypes = builder.biomeGroups(); + } + + @Override + public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) { + BiomeGroup group = biomeTypes[type.ordinal()]; + if (group == null) { + return Biomes.NETHER; + } + return group.biomes.get(moisture, temperature, shape); + } + + @Override + public List getAllBiomes(BiomeType type) { + BiomeGroup group = biomeTypes[type.ordinal()]; + if (group == null) { + return Collections.emptyList(); + } + List biomes = new LinkedList<>(); + for (MappedList> row : group.biomes) { + for (FixedList cell : row) { + for (Biome biome : cell) { + biomes.add(biome); + } + } + } + return biomes; + } + + @Override + public Set getBiomes(BiomeType type) { + BiomeGroup group = biomeTypes[type.ordinal()]; + if (group == null) { + return Collections.emptySet(); + } + Set biomes = new HashSet<>(); + for (MappedList> row : group.biomes) { + for (FixedList cell : row) { + for (Biome biome : cell) { + biomes.add(biome); + } + } + } + return biomes; + } + + @Override + public JsonObject toJson() { + JsonObject root = new JsonObject(); + for (BiomeType type : BiomeType.values()) { + BiomeGroup group = biomeTypes[type.ordinal()]; + JsonObject grid = new JsonObject(); + if (group != null) { + int rowCount = 0; + float maxRow = group.biomes.size() - 1; + for (MappedList> row : group.biomes) { + int colCount = 0; + float maxCol = row.size() - 1; + + JsonObject rowJson = new JsonObject(); + for (FixedList cell : row) { + JsonArray colJson = new JsonArray(); + for (Biome biome : cell.uniqueValues()) { + colJson.add(String.valueOf(Registry.BIOME.getId(biome))); + } + float colId = colCount / maxCol; + rowJson.add("" + colId, colJson); + colCount++; + } + + float rowId = rowCount / maxRow; + grid.add("" + rowId, rowJson); + rowCount++; + } + } + root.add(type.name(), grid); + } + return root; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/AbstractMaxHeightModifier.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/AbstractMaxHeightModifier.java new file mode 100644 index 0000000..8915c6d --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/AbstractMaxHeightModifier.java @@ -0,0 +1,67 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.world.biome.Biome; + +public abstract class AbstractMaxHeightModifier extends AbstractOffsetModifier { + + private final float minHeight; + private final float maxHeight; + private final float range; + private final Module variance; + + public AbstractMaxHeightModifier(Seed seed, Climate climate, int scale, int octaves, float variance, float minHeight, float maxHeight) { + super(climate); + this.minHeight = minHeight; + this.maxHeight = maxHeight; + this.range = maxHeight - minHeight; + this.variance = Source.perlin(seed.next(), scale, octaves).scale(variance); + } + + @Override + protected final Biome modify(Biome in, Cell cell, int x, int z, float ox, float oz) { + float var = variance.getValue(x, z); + float value = cell.value + var; + if (value < minHeight) { + return in; + } + if (value > maxHeight) { + return getModifiedBiome(in, cell, x, z, ox, oz); + } + float alpha = (value - minHeight) / range; + cell.biomeEdge *= alpha; + return in; + } + + protected abstract Biome getModifiedBiome(Biome in, Cell cell, int x, int z, float ox, float oz); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/AbstractOffsetModifier.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/AbstractOffsetModifier.java new file mode 100644 index 0000000..0f9031a --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/AbstractOffsetModifier.java @@ -0,0 +1,50 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.world.biome.Biome; + +public abstract class AbstractOffsetModifier implements BiomeModifier { + + private final Climate climate; + + public AbstractOffsetModifier(Climate climate) { + this.climate = climate; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + float dx = climate.getOffsetX(x, z, 50); + float dz = climate.getOffsetX(x, z, 50); + return modify(in, cell, x, z, x + dx, z + dz); + } + + protected abstract Biome modify(Biome in, Cell cell, int x, int z, float ox, float oz); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/BeachModifier.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/BeachModifier.java new file mode 100644 index 0000000..31abce2 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/BeachModifier.java @@ -0,0 +1,62 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.map.BiomeMap; +import net.minecraft.world.biome.Biome; + +public class BeachModifier implements BiomeModifier { + + private final Terrains terrain; + private final BiomeMap biomeMap; + + public BeachModifier(BiomeMap biomeMap, Terrains terrain) { + this.terrain = terrain; + this.biomeMap = biomeMap; + } + + @Override + public int priority() { + return 0; + } + + @Override + public boolean test(Biome biome) { + return true; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + if (cell.tag == terrain.beach) { + return biomeMap.getBeach(cell.temperature, cell.moisture, cell.biome); + } + return in; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/BiomeModifierManager.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/BiomeModifierManager.java new file mode 100644 index 0000000..5cbf385 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/BiomeModifierManager.java @@ -0,0 +1,90 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.api.biome.modifier.ModifierManager; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.provider.DesertBiomes; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.biome.Biome; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class BiomeModifierManager implements BiomeModifier, ModifierManager { + + private final DesertBiomes desertBiomes; + private final List biomeModifiers; + + public BiomeModifierManager(TerraContext context, BiomeMap biomes) { + desertBiomes = new DesertBiomes(context.materials, biomes.getAllBiomes(BiomeType.DESERT)); + List modifiers = new ArrayList<>(); + modifiers.add(new BeachModifier(biomes, context.terrain)); + modifiers.add(new DesertColorModifier(desertBiomes)); + modifiers.add(new SandBiomeModifier( + context.seed, + context.factory.getClimate(), + context.levels + )); + Collections.sort(modifiers); + this.biomeModifiers = modifiers; + } + + @Override + public void register(BiomeModifier modifier) { + biomeModifiers.add(modifier); + Collections.sort(biomeModifiers); + } + + public DesertBiomes getDesertBiomes() { + return desertBiomes; + } + + @Override + public int priority() { + return -1; + } + + @Override + public boolean test(Biome biome) { + return true; + } + + @Override + public Biome modify(Biome biome, Cell cell, int x, int z) { + for (BiomeModifier modifier : biomeModifiers) { + if (modifier.test(biome)) { + biome = modifier.modify(biome, cell, x, z); + } + } + return biome; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/DesertColorModifier.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/DesertColorModifier.java new file mode 100644 index 0000000..d941f23 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/DesertColorModifier.java @@ -0,0 +1,63 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.provider.DesertBiomes; +import net.minecraft.world.biome.Biome; + +public class DesertColorModifier implements BiomeModifier { + + private final DesertBiomes biomes; + + public DesertColorModifier(DesertBiomes biomes) { + this.biomes = biomes; + } + + @Override + public int priority() { + return 0; + } + + @Override + public boolean test(Biome biome) { + return biome.getCategory() == Biome.Category.DESERT; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + if (biomes.isRedDesert(in)) { + if (cell.continent <= 0.5F) { + return biomes.getWhiteDesert(cell.biome); + } + } else if (cell.continent > 0.5F) { + return biomes.getRedDesert(cell.biome); + } + return in; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/SandBiomeModifier.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/SandBiomeModifier.java new file mode 100644 index 0000000..66dd39e --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/modifier/SandBiomeModifier.java @@ -0,0 +1,67 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.material.MaterialHelper; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.util.Set; +import java.util.stream.Collectors; + +// prevents deserts forming at high levels +public class SandBiomeModifier extends AbstractMaxHeightModifier { + + private final Set biomes; + + public SandBiomeModifier(Seed seed, Climate climate, Levels levels) { + super(seed, climate, 50, 2, levels.scale(8), levels.ground(5), levels.ground(25)); + this.biomes = Registry.BIOME.stream() + .filter(biome -> MaterialHelper.isSand(biome.getSurfaceConfig().getTopMaterial().getBlock())) + .collect(Collectors.toSet()); + } + + @Override + public int priority() { + return 1; + } + + @Override + public boolean test(Biome biome) { + return biome.getCategory() == Biome.Category.DESERT || biomes.contains(biome); + } + + @Override + protected Biome getModifiedBiome(Biome in, Cell cell, int x, int z, float ox, float oz) { + return Biomes.BADLANDS; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/AbstractBiomeProvider.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/AbstractBiomeProvider.java new file mode 100644 index 0000000..b213a75 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/AbstractBiomeProvider.java @@ -0,0 +1,55 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.google.common.collect.ImmutableSet; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.source.BiomeSource; + +import java.util.Set; + +public abstract class AbstractBiomeProvider extends BiomeSource { + + protected static final Set defaultBiomes = ImmutableSet + .of(Biomes.OCEAN, Biomes.PLAINS, Biomes.DESERT, Biomes.MOUNTAINS, Biomes.FOREST, Biomes.TAIGA, Biomes.SWAMP, Biomes.RIVER, + Biomes.FROZEN_OCEAN, Biomes.FROZEN_RIVER, Biomes.SNOWY_TUNDRA, Biomes.SNOWY_MOUNTAINS, Biomes.MUSHROOM_FIELDS, + Biomes.MUSHROOM_FIELD_SHORE, Biomes.BEACH, Biomes.DESERT_HILLS, Biomes.WOODED_HILLS, Biomes.TAIGA_HILLS, Biomes.MOUNTAIN_EDGE, + Biomes.JUNGLE, Biomes.JUNGLE_HILLS, Biomes.JUNGLE_EDGE, Biomes.DEEP_OCEAN, Biomes.STONE_SHORE, Biomes.SNOWY_BEACH, + Biomes.BIRCH_FOREST, Biomes.BIRCH_FOREST_HILLS, Biomes.DARK_FOREST, Biomes.SNOWY_TAIGA, Biomes.SNOWY_TAIGA_HILLS, + Biomes.GIANT_TREE_TAIGA, Biomes.GIANT_TREE_TAIGA_HILLS, Biomes.WOODED_MOUNTAINS, Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, + Biomes.BADLANDS, Biomes.WOODED_BADLANDS_PLATEAU, Biomes.BADLANDS_PLATEAU, Biomes.WARM_OCEAN, Biomes.LUKEWARM_OCEAN, + Biomes.COLD_OCEAN, Biomes.DEEP_WARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN, Biomes.DEEP_COLD_OCEAN, Biomes.DEEP_FROZEN_OCEAN, + Biomes.SUNFLOWER_PLAINS, Biomes.DESERT_LAKES, Biomes.GRAVELLY_MOUNTAINS, Biomes.FLOWER_FOREST, Biomes.TAIGA_MOUNTAINS, + Biomes.SWAMP_HILLS, Biomes.ICE_SPIKES, Biomes.MODIFIED_JUNGLE, Biomes.MODIFIED_JUNGLE_EDGE, Biomes.TALL_BIRCH_FOREST, + Biomes.TALL_BIRCH_HILLS, Biomes.DARK_FOREST_HILLS, Biomes.SNOWY_TAIGA_MOUNTAINS, Biomes.GIANT_SPRUCE_TAIGA, + Biomes.GIANT_SPRUCE_TAIGA_HILLS, Biomes.MODIFIED_GRAVELLY_MOUNTAINS, Biomes.SHATTERED_SAVANNA, Biomes.SHATTERED_SAVANNA_PLATEAU, + Biomes.ERODED_BADLANDS, Biomes.MODIFIED_WOODED_BADLANDS_PLATEAU, Biomes.MODIFIED_BADLANDS_PLATEAU); + + protected AbstractBiomeProvider() { + super(defaultBiomes); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/BiomeHelper.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/BiomeHelper.java new file mode 100644 index 0000000..646a239 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/BiomeHelper.java @@ -0,0 +1,234 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.terraforged.core.settings.BiomeSettings; +import com.terraforged.core.world.biome.BiomeData; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.ModBiomes; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.map.BiomeMapBuilder; +import com.terraforged.mod.biome.map.BiomePredicate; +import me.dags.noise.util.Vec2f; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.OceanRuinFeature; +import net.minecraft.world.gen.feature.OceanRuinFeatureConfig; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class BiomeHelper { + + private static final Map PREDICATES = new HashMap() {{ + put(BiomeType.TROPICAL_RAINFOREST, BiomePredicate.TROPICAL_RAINFOREST); + put(BiomeType.SAVANNA, + BiomePredicate.SAVANNA.or(BiomePredicate.MESA).not(BiomePredicate.DESERT).not(BiomePredicate.STEPPE).not(BiomePredicate.COAST) + .not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.DESERT, + BiomePredicate.DESERT.or(BiomePredicate.MESA).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.TEMPERATE_RAINFOREST, BiomePredicate.TEMPERATE_RAINFOREST.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TEMPERATE_FOREST, + BiomePredicate.TEMPERATE_FOREST.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.GRASSLAND, BiomePredicate.GRASSLAND.not(BiomePredicate.WETLAND).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.COLD_STEPPE, BiomePredicate.COLD_STEPPE.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.STEPPE, BiomePredicate.STEPPE.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TAIGA, BiomePredicate.TAIGA.not(BiomePredicate.TUNDRA).not(BiomePredicate.COLD_STEPPE).not(BiomePredicate.COAST) + .not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TUNDRA, BiomePredicate.TUNDRA.not(BiomePredicate.TAIGA).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.ALPINE, BiomePredicate.MOUNTAIN); + }}; + + public static BiomeMap.Builder getBuilder(List biomes) { + return BiomeMapBuilder.basic(biomes); + } + + public static BiomeMap getDefaultBiomeMap() { + List biomes = getAllBiomeData(); + BiomeMap.Builder builder = getBuilder(biomes); + for (BiomeData data : biomes) { + int weight = 10; + Biome biome = (Biome) data.reference; + + if (biome.hasParent() && getId(biome).contains("hills")) { + continue; + } + + if (biome.getCategory() == Biome.Category.FOREST) { + weight = 5; + } + + if (biome.getCategory() == Biome.Category.MUSHROOM) { + weight = 1; + } + + // don't use BiomeDictionary with transient biomes todo detect rare +// if (ForgeRegistries.BIOMES.containsKey(biome.getRegistryName())) { +// if (BiomeDictionary.getTypes(biome).contains(BiomeDictionary.Type.RARE)) { +// weight = 1; +// } +// } + + if (biome.getCategory() == Biome.Category.OCEAN) { + builder.addOcean(biome, weight); + } else if (biome.getCategory() == Biome.Category.RIVER) { + builder.addRiver(biome, weight); + } else if (biome.getCategory() == Biome.Category.BEACH || biome == Biomes.STONE_SHORE) { + builder.addBeach(biome, weight); + } else if (biome.getCategory() == Biome.Category.SWAMP) { + builder.addWetland(biome, weight); + } else { + Collection types = getTypes(data, biome); + for (BiomeType type : types) { + builder.addBiome(type, biome, weight); + } + } + } + + builder.addBiome(BiomeType.TEMPERATE_RAINFOREST, Biomes.PLAINS, 10); + builder.addBiome(BiomeType.TEMPERATE_FOREST, Biomes.FLOWER_FOREST, 3); + builder.addBiome(BiomeType.TEMPERATE_FOREST, Biomes.PLAINS, 10); + builder.addBiome(BiomeType.TUNDRA, ModBiomes.SNOWY_TAIGA_SCRUB, 5); + builder.addBiome(BiomeType.TAIGA, ModBiomes.TAIGA_SCRUB, 5); + + return builder.build(); + } + + public static BiomeMap getBiomeMap(BiomeSettings settings) { + List biomes = getAllBiomeData(); + BiomeMap.Builder builder = getBuilder(biomes); + Map biomeMap = biomes.stream().collect(Collectors.toMap(d -> d.name, d -> d)); + Map groupMap = settings.asMap(); + for (Map.Entry e : groupMap.entrySet()) { + for (BiomeSettings.BiomeWeight biomeWeight : e.getValue().biomes) { + BiomeData data = biomeMap.get(biomeWeight.id); + if (data == null) { + continue; + } + builder.addBiome(e.getKey(), (Biome) data.reference, biomeWeight.weight); + } + } + for (BiomeData data : biomes) { + Biome biome = (Biome) data.reference; + if (biome.getCategory() == Biome.Category.OCEAN) { + builder.addOcean(biome, 10); + } else if (biome.getCategory() == Biome.Category.RIVER) { + builder.addRiver(biome, 10); + } + } + return builder.build(); + } + + public static Biome.TemperatureGroup getTemperatureGroup(Biome biome) { + // vanilla ocean biome properties are not at all helpful for determining temperature + if (biome.getCategory() == Biome.Category.OCEAN) { + // warm & luke_warm oceans get OceanRuinStructure.Type.WARM + OceanRuinFeatureConfig config = biome.getStructureFeatureConfig(Feature.OCEAN_RUIN); + if (config != null) { + if (config.biomeType == OceanRuinFeature.BiomeType.WARM) { + return Biome.TemperatureGroup.WARM; + } + } + + // if the id contains the world cold or frozen, assume it's cold + if (getId(biome).contains("cold") || getId(biome).contains("frozen")) { + return Biome.TemperatureGroup.COLD; + } + + // the rest we categorize as medium + return Biome.TemperatureGroup.MEDIUM; + } + // hopefully biomes otherwise have a sensible category + return biome.getTemperatureGroup(); + } + + public static String getId(Biome biome) { + Identifier name = Registry.BIOME.getId(biome); + if (name == null) { + return "unknown"; + } + return name.toString(); + } + + public static Collection getTypes(BiomeData data, Biome biome) { + Set types = new HashSet<>(); + for (Map.Entry entry : PREDICATES.entrySet()) { + if (entry.getValue().test(data, biome)) { + types.add(entry.getKey()); + } + } + return types; + } + + public static List getAllBiomeData() { + Collection biomes = TerraBiomeRegistry.getInstance().getAll(BiomeHelper::filter); + Vec2f tempRange = getRange(biomes, Biome::getTemperature); + Vec2f moistRange = getRange(biomes, Biome::getRainfall); + List list = new LinkedList<>(); + for (Biome biome : biomes) { + String name = getId(biome); + float moisture = (biome.getRainfall() - moistRange.x) / (moistRange.y - moistRange.x); + float temperature = (biome.getTemperature() - tempRange.x) / (tempRange.y - tempRange.x); + int color = biome.getSurfaceConfig().getTopMaterial().getMaterial().getColor().color; + list.add(new BiomeData(name, biome, color, moisture, temperature)); + } + return list; + } + + private static boolean filter(Biome biome) { + if (biome.getCategory() == Biome.Category.NONE) { + return true; + } + if (biome.getCategory() == Biome.Category.THEEND) { + return true; + } + if (biome.getCategory() == Biome.Category.NETHER) { + return true; + } + return false; //!BiomeDictionary.getTypes(biome).contains(BiomeDictionary.Type.OVERWORLD); todo dict + } + + private static Vec2f getRange(Collection biomes, Function getter) { + float min = Float.MAX_VALUE; + float max = Float.MIN_VALUE; + for (Biome biome : biomes) { + float value = getter.apply(biome); + min = Math.min(min, value); + max = Math.max(max, value); + } + return new Vec2f(min, max); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/BiomeProvider.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/BiomeProvider.java new file mode 100644 index 0000000..0888abd --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/BiomeProvider.java @@ -0,0 +1,187 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.google.common.collect.Sets; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.chunk.ChunkReader; +import com.terraforged.core.world.decorator.Decorator; +import com.terraforged.core.world.heightmap.WorldLookup; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.modifier.BiomeModifierManager; +import com.terraforged.mod.chunk.TerraBiomeArray; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.util.setup.SetupHooks; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.feature.StructureFeature; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +public class BiomeProvider extends AbstractBiomeProvider { + + private final BiomeMap biomeMap; + private final TerraContext context; + private final WorldLookup worldLookup; + private final BiomeModifierManager modifierManager; + private final Map> decorators = new HashMap<>(); + + public BiomeProvider(TerraContext context) { + this.context = context; + this.biomeMap = BiomeHelper.getDefaultBiomeMap(); + this.worldLookup = new WorldLookup(context.factory, context); + this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy()); + } + + public Cell lookupPos(int x, int z) { + return worldLookup.getCell(x, z); + } + + @Override + public Biome getBiomeForNoiseGen(int x, int y, int z) { + x = (x << 2); + z = (z << 2); + return getBiome(lookupPos(x, z), x, z); + } + + @Override + public Set getBiomesInArea(int centerX, int centerY, int centerZ, int sideLength) { + int minX = centerX - (sideLength >> 2); + int minZ = centerZ - (sideLength >> 2); + int maxX = centerX + (sideLength >> 2); + int maxZ = centerZ + (sideLength >> 2); + Set biomes = Sets.newHashSet(); + context.heightmap.visit(minX, minZ, maxX, maxZ, (cell, x, z) -> { + Biome biome = getBiome(cell, minX + x, minZ + z); + biomes.add(biome); + }); + return biomes; + } + + @Override + public BlockPos locateBiome(int centerX, int centerY, int centerZ, int range, List biomes, Random random) { + int minX = centerX - (range >> 2); + int minZ = centerZ - (range >> 2); + int maxX = centerX + (range >> 2); + int maxZ = centerZ + (range >> 2); + Set matchBiomes = new HashSet<>(biomes); + SearchContext search = new SearchContext(); + context.heightmap.visit(minX, minZ, maxX, maxZ, (cell, x, z) -> { + Biome biome = getBiome(cell, minX + x, minZ + z); + if (matchBiomes.contains(biome)) { + if (search.first || random.nextInt(search.count + 1) == 0) { + search.first = false; + search.pos.set(minX + x, 0, minZ + z); + } + ++search.count; + } + }); + return search.pos; + } + + @Override + public boolean hasStructureFeature(StructureFeature structureIn) { + return this.structureFeatures.computeIfAbsent(structureIn, (p_205006_1_) -> { + for (Biome biome : defaultBiomes) { + if (biome.hasStructureFeature(p_205006_1_)) { + return true; + } + } + return false; + }); + } + + @Override + public Set getTopMaterials() { + if (this.topMaterials.isEmpty()) { + for (Biome biome : defaultBiomes) { + this.topMaterials.add(biome.getSurfaceConfig().getTopMaterial()); + } + } + return this.topMaterials; + } + + public BiomeModifierManager getModifierManager() { + return modifierManager; + } + + public List getDecorators(Biome biome) { + return decorators.getOrDefault(biome, Collections.emptyList()); + } + + public TerraBiomeArray createBiomeContainer(ChunkReader chunkReader) { + TerraBiomeArray.Builder builder = TerraBiomeArray.builder(); + chunkReader.iterate((cell, dx, dz) -> { + Biome biome = getBiome(cell, chunkReader.getBlockX() + dx, chunkReader.getBlockZ() + dz); + builder.set(dx, dz, biome); + }); + return builder.build(chunkReader); + } + + public Biome getBiome(Cell cell, int x, int z) { + if (cell.tag == context.terrain.wetlands) { + return biomeMap.getWetland(cell.temperature, cell.moisture, cell.biome); + } + + if (cell.value > context.levels.water) { + return getModifierManager().modify(biomeMap.getBiome(cell), cell, x, z); + } + + if (cell.tag == context.terrain.river || cell.tag == context.terrain.riverBanks) { + Biome biome = biomeMap.getBiome(cell); + if (overridesRiver(biome)) { + return biome; + } + + return biomeMap.getRiver(cell.temperature, cell.moisture, cell.biome); + } + + if (cell.tag == context.terrain.ocean) { + return biomeMap.getOcean(cell.temperature, cell.moisture, cell.biome); + } + + return biomeMap.getDeepOcean(cell.temperature, cell.moisture, cell.biome); + } + + private static boolean overridesRiver(Biome biome) { + return biome.getCategory() == Biome.Category.SWAMP || biome.getCategory() == Biome.Category.JUNGLE; + } + + private static class SearchContext { + + private int count = 0; + private boolean first = true; + private final BlockPos.Mutable pos = new BlockPos.Mutable(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/DesertBiomes.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/DesertBiomes.java new file mode 100644 index 0000000..b2b5a74 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/DesertBiomes.java @@ -0,0 +1,117 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.api.material.layer.LayerMaterial; +import com.terraforged.core.util.concurrent.ObjectPool; +import com.terraforged.mod.material.Materials; +import com.terraforged.mod.util.DummyBlockReader; +import com.terraforged.mod.util.ListUtils; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.MaterialColor; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class DesertBiomes { + + private final Set reds; + private final Set whites; + private final List redSand; + private final List whiteSand; + private final LayerManager layerManager; + + private final int maxRedIndex; + private final int maxWhiteIndex; + + public DesertBiomes(Materials materials, List deserts) { + List white = new LinkedList<>(); + List red = new LinkedList<>(); + try (ObjectPool.Item reader = DummyBlockReader.pooled()) { + for (Biome biome : deserts) { + BlockState top = biome.getSurfaceConfig().getTopMaterial(); + MaterialColor color = top.getTopMaterialColor(reader.getValue().set(top), BlockPos.ORIGIN); + int whiteDist2 = distance2(color, MaterialColor.SAND); + int redDist2 = distance2(color, MaterialColor.ORANGE); + if (whiteDist2 < redDist2) { + white.add(biome); + } else { + red.add(biome); + } + } + } + this.layerManager = materials.getLayerManager(); + this.whiteSand = new ArrayList<>(white); + this.redSand = new ArrayList<>(red); + this.whites = new HashSet<>(white); + this.reds = new HashSet<>(red); + this.whiteSand.sort(Comparator.comparing(BiomeHelper::getId)); + this.redSand.sort(Comparator.comparing(BiomeHelper::getId)); + this.maxRedIndex = red.size() - 1; + this.maxWhiteIndex = white.size() - 1; + } + + public boolean isRedDesert(Biome biome) { + return reds.contains(biome); + } + + public boolean isWhiteDesert(Biome biome) { + return whites.contains(biome); + } + + public Biome getRedDesert(float shape) { + return ListUtils.get(redSand, maxRedIndex, shape, Biomes.MODIFIED_BADLANDS_PLATEAU); + } + + public Biome getWhiteDesert(float shape) { + return ListUtils.get(whiteSand, maxWhiteIndex, shape, Biomes.DESERT); + } + + public LayerMaterial getSandLayers(Biome biome) { + Block top = biome.getSurfaceConfig().getTopMaterial().getBlock(); + return layerManager.getMaterial(Blocks.SAND); + } + + private static int distance2(MaterialColor mc1, MaterialColor mc2) { + Color c1 = new Color(mc1.color); + Color c2 = new Color(mc2.color); + int dr = c1.getRed() - c2.getRed(); + int dg = c1.getGreen() - c2.getGreen(); + int db = c1.getBlue() - c2.getBlue(); + return (dr * dr) + (dg * dg) + (db * db); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeRegistry.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeRegistry.java new file mode 100644 index 0000000..1875b99 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeRegistry.java @@ -0,0 +1,52 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; + +import java.util.Collection; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class TerraBiomeRegistry { + + private static final TerraBiomeRegistry instance = new TerraBiomeRegistry(); + + public Optional getBiome(Identifier name) { + return Registry.BIOME.getOrEmpty(name); + } + + public Collection getAll(Predicate filter) { + return Registry.BIOME.stream().filter(filter.negate()).collect(Collectors.toList()); + } + + public static TerraBiomeRegistry getInstance() { + return instance; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/tag/BiomeTagManager.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/tag/BiomeTagManager.java new file mode 100644 index 0000000..91eda81 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/biome/tag/BiomeTagManager.java @@ -0,0 +1,70 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.tag; + +import com.terraforged.api.biome.BiomeTags; +import com.terraforged.mod.Log; +import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; +import net.minecraft.resource.ResourceManager; +import net.minecraft.tag.TagContainer; +import net.minecraft.util.Identifier; +import net.minecraft.util.profiler.Profiler; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +public class BiomeTagManager implements IdentifiableResourceReloadListener { + + private static final boolean RETAIN_ORDER = false; + private static final Identifier ID = new Identifier("terraforged", "biome_tags"); + + private final TagContainer collection = new TagContainer<>( + Registry.BIOME::getOrEmpty, + "tags/biomes", + BiomeTagManager.RETAIN_ORDER, + "biomes" + ); + + @Override + public Identifier getFabricId() { + return ID; + } + + @Override + public CompletableFuture reload(Synchronizer synchronizer, ResourceManager manager, Profiler prepareProfiler, Profiler applyProfiler, + Executor prepareExecutor, Executor applyExecutor) { + Log.debug("Reloading biome tag collection"); + return collection.prepareReload(manager, prepareExecutor) + .thenCompose(synchronizer::whenPrepared) + .thenAcceptAsync(collection::applyReload, applyExecutor) + .thenRun(() -> { + BiomeTags.setCollection(collection); + Log.debug("Biome tag reload complete"); + }); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ChunkGeneratorFactory.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ChunkGeneratorFactory.java new file mode 100644 index 0000000..b994838 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ChunkGeneratorFactory.java @@ -0,0 +1,35 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.mod.biome.provider.BiomeProvider; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.chunk.OverworldChunkGeneratorConfig; + +public interface ChunkGeneratorFactory> { + + T create(TerraContext context, BiomeProvider biomeProvider, OverworldChunkGeneratorConfig settings); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ChunkProcessor.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ChunkProcessor.java new file mode 100644 index 0000000..740c657 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ChunkProcessor.java @@ -0,0 +1,12 @@ +package com.terraforged.mod.chunk; + +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.core.region.chunk.ChunkReader; +import net.minecraft.util.math.ChunkPos; + +public interface ChunkProcessor { + + void preProcess(ChunkPos pos, ChunkReader chunk, TerraBiomeArray container); + + void postProcess(ChunkReader chunk, TerraBiomeArray container, DecoratorContext context); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java new file mode 100644 index 0000000..2e30bcd --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java @@ -0,0 +1,128 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import net.minecraft.entity.EntityCategory; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.noise.NoiseSampler; +import net.minecraft.util.math.noise.OctavePerlinNoiseSampler; +import net.minecraft.village.ZombieSiegeManager; +import net.minecraft.world.ChunkRegion; +import net.minecraft.world.Heightmap; +import net.minecraft.world.IWorld; +import net.minecraft.world.SpawnHelper; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.source.BiomeSource; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.CatSpawner; +import net.minecraft.world.gen.ChunkRandom; +import net.minecraft.world.gen.PhantomSpawner; +import net.minecraft.world.gen.PillagerSpawner; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.chunk.ChunkGeneratorConfig; +import net.minecraft.world.gen.feature.Feature; + +import java.util.List; + +public abstract class ObfHelperChunkGenerator extends ChunkGenerator { + + private final CatSpawner catSpawner = new CatSpawner(); + private final PillagerSpawner patrolSpawner = new PillagerSpawner(); + private final PhantomSpawner phantomSpawner = new PhantomSpawner(); + private final ZombieSiegeManager zombieSiegeManager = new ZombieSiegeManager(); + private final NoiseSampler surfaceNoise; + + public ObfHelperChunkGenerator(IWorld world, BiomeSource biomeSource, T settings) { + super(world, biomeSource, settings); + ChunkRandom random = new ChunkRandom(world.getSeed()); + this.surfaceNoise = new OctavePerlinNoiseSampler(random, 3, 0); + } + + @Override + public List getEntitySpawnList(EntityCategory category, BlockPos pos) { + if (Feature.SWAMP_HUT.method_14029(this.world, pos)) { + if (category == EntityCategory.MONSTER) { + return Feature.SWAMP_HUT.getMonsterSpawns(); + } + + if (category == EntityCategory.CREATURE) { + return Feature.SWAMP_HUT.getCreatureSpawns(); + } + } else if (category == EntityCategory.MONSTER) { + if (Feature.PILLAGER_OUTPOST.isInsideStructure(this.world, pos)) { + return Feature.PILLAGER_OUTPOST.getMonsterSpawns(); + } + + if (Feature.OCEAN_MONUMENT.isInsideStructure(this.world, pos)) { + return Feature.OCEAN_MONUMENT.getMonsterSpawns(); + } + } + return super.getEntitySpawnList(category, pos); + } + + @Override + public void spawnEntities(ServerWorld worldIn, boolean spawnHostileMobs, boolean spawnPeacefulMobs) { + phantomSpawner.spawn(worldIn, spawnHostileMobs, spawnPeacefulMobs); + patrolSpawner.spawn(worldIn, spawnHostileMobs, spawnPeacefulMobs); + catSpawner.spawn(worldIn, spawnHostileMobs, spawnPeacefulMobs); + zombieSiegeManager.spawn(worldIn, spawnHostileMobs, spawnPeacefulMobs); + } + + @Override + public void populateEntities(ChunkRegion region) { + int chunkX = region.getCenterChunkX(); + int chunkZ = region.getCenterChunkZ(); + Biome biome = region.getChunk(chunkX, chunkZ).getBiomeArray().getBiomeForNoiseGen(0, 0, 0); + ChunkRandom random = new ChunkRandom(); + random.setSeed(region.getSeed(), chunkX << 4, chunkZ << 4); + SpawnHelper.populateEntities(region, biome, chunkX, chunkZ, random); + } + + @Override + public final int getHeightInGround(int x, int z, Heightmap.Type type) { + int level = sampleHeight(x, z, type) + 1; + if (type == Heightmap.Type.OCEAN_FLOOR || type == Heightmap.Type.OCEAN_FLOOR_WG) { + return level; + } + return Math.max(getSeaLevel(), level); + } + + public final double getSurfaceNoise(int x, int z) { + double scale = 0.0625D; + double noiseX = x * scale; + double noiseZ = z * scale; + double unusedValue1 = scale; + double unusedValue2 = (x & 15) * scale; + return surfaceNoise.sample(noiseX, noiseZ, unusedValue1, unusedValue2); + } + + public abstract int sampleHeight(int x, int z, Heightmap.Type type); + + public abstract void populateNoise(IWorld world, Chunk chunk); + + public abstract void buildSurface(ChunkRegion world, Chunk chunk); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraBiomeArray.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraBiomeArray.java new file mode 100644 index 0000000..19cc5bc --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraBiomeArray.java @@ -0,0 +1,127 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.chunk.ChunkReader; +import com.terraforged.core.util.PosIterator; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.source.BiomeArray; + +// holds a 1:1 map of biomes in the chunk +// also holds the chunk's view on the heightmap for convenience +public class TerraBiomeArray extends BiomeArray { + + private static final int BITS_WIDTH = (int) Math.round(Math.log(16.0D) / Math.log(2.0D)) - 2; + private static final int ZOOM_VERT = (int) Math.round(Math.log(256.0D) / Math.log(2.0D)) - 2; + public static final int SIZE = 1 << BITS_WIDTH + BITS_WIDTH + ZOOM_VERT; + public static final int MASK_HORIZ = (1 << BITS_WIDTH) - 1; + public static final int MASK_VERT = (1 << ZOOM_VERT) - 1; + + private final Biome[] biomes; + private final Biome[] surface; + private final ChunkReader chunkReader; + + public TerraBiomeArray(Builder builder, ChunkReader chunkReader) { + super(builder.biomes); + this.chunkReader = chunkReader; + this.biomes = builder.biomes; + this.surface = builder.surfaceBiomeCache; + } + + public Biome getBiome(int x, int z) { + return surface[indexOf(x, z)]; + } + + @Override + public Biome getBiomeForNoiseGen(int x, int y, int z) { + return super.getBiomeForNoiseGen(x, y, z); + } + + public Biome getFeatureBiome() { + PosIterator iterator = PosIterator.area(0, 0, 16, 16); + while (iterator.next()) { + Cell cell = chunkReader.getCell(iterator.x(), iterator.z()); + if (cell.biomeType.isExtreme()) { + return getBiome(iterator.x(), iterator.z()); + } + } + return getBiome(8, 8); + } + + public BiomeArray bakeBiomes() { + return new BiomeArray(biomes); + } + + public ChunkReader getChunkReader() { + return chunkReader; + } + + private static int indexOf(int x, int z) { + x &= 15; + z &= 15; + return (z << 4) + x; + } + + private static int indexOf(int x, int y, int z) { + x &= MASK_HORIZ; + y = MathHelper.clamp(y, 0, MASK_VERT); + z &= MASK_HORIZ; + return y << BITS_WIDTH + BITS_WIDTH | z << BITS_WIDTH | x; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final Biome[] biomes = new Biome[SIZE]; + private final Biome[] surfaceBiomeCache = new Biome[256]; + + public void set(int x, int z, Biome biome) { + surfaceBiomeCache[indexOf(x, z)] = biome; + } + + public TerraBiomeArray build(ChunkReader chunkReader) { + // biome storage format is 1 biome pos == 4x4x4 blocks, stored in an 4x64x4 (xyz) array + // sample the 1:1 surfaceBiomeCache every 4 blocks with a 2 block offset (roughly center of the 4x4 area) + for (int dy = 0; dy < 64; dy++) { + for (int dz = 0; dz < 4; dz++) { + for (int dx = 0; dx < 4; dx++) { + int x = dx * 4; + int z = dz * 4; + int index = indexOf(dx, dy, dz); + biomes[index] = surfaceBiomeCache[indexOf(x, z)]; + } + } + } + return new TerraBiomeArray(this, chunkReader); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java new file mode 100644 index 0000000..f1ab0e0 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java @@ -0,0 +1,385 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.chunk.surface.ChunkSurfaceBuffer; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.api.chunk.surface.SurfaceManager; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.RegionCache; +import com.terraforged.core.region.RegionGenerator; +import com.terraforged.core.region.Size; +import com.terraforged.core.region.chunk.ChunkReader; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.core.world.decorator.Decorator; +import com.terraforged.feature.FeatureManager; +import com.terraforged.feature.matcher.dynamic.DynamicMatcher; +import com.terraforged.feature.matcher.feature.FeatureMatcher; +import com.terraforged.feature.modifier.FeatureModifierLoader; +import com.terraforged.feature.modifier.FeatureModifiers; +import com.terraforged.feature.predicate.DeepWater; +import com.terraforged.feature.predicate.FeaturePredicate; +import com.terraforged.feature.predicate.MinHeight; +import com.terraforged.feature.template.type.FeatureTypes; +import com.terraforged.mod.Log; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.fix.ChunkCarverFix; +import com.terraforged.mod.chunk.fix.RegionFix; +import com.terraforged.mod.decorator.ChunkPopulator; +import com.terraforged.mod.decorator.base.BedrockDecorator; +import com.terraforged.mod.decorator.base.CoastDecorator; +import com.terraforged.mod.decorator.base.ErosionDecorator; +import com.terraforged.mod.decorator.base.GeologyDecorator; +import com.terraforged.mod.decorator.feature.LayerDecorator; +import com.terraforged.mod.decorator.feature.SnowEroder; +import com.terraforged.mod.decorator.surface.FrozenOcean; +import com.terraforged.mod.feature.Matchers; +import com.terraforged.mod.feature.TerrainHelper; +import com.terraforged.mod.feature.predicate.TreeLine; +import com.terraforged.mod.material.Materials; +import com.terraforged.mod.material.geology.GeoManager; +import com.terraforged.mod.util.setup.SetupHooks; +import net.minecraft.structure.StructureManager; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.ChunkRegion; +import net.minecraft.world.Heightmap; +import net.minecraft.world.IWorld; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.source.BiomeAccess; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ProtoChunk; +import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.chunk.ChunkGeneratorConfig; +import net.minecraft.world.gen.feature.AbstractTreeFeature; +import net.minecraft.world.gen.feature.Feature; + +import java.util.ArrayList; +import java.util.List; + +public class TerraChunkGenerator extends ObfHelperChunkGenerator implements ChunkProcessor { + + private final TerraContext context; + private final BiomeProvider biomeProvider; + private final TerrainHelper terrainHelper; + + private final GeoManager geologyManager; + private final FeatureManager featureManager; + private final SurfaceManager surfaceManager; + private final List baseDecorators; + private final List postProcessors; + + private final RegionCache regionCache; + + public TerraChunkGenerator(TerraContext context, BiomeProvider biomeProvider, ChunkGeneratorConfig settings) { + super(context.world, biomeProvider, settings); + this.context = context; + this.biomeProvider = biomeProvider; + this.surfaceManager = SetupHooks.setup(createSurfaceManager(), context.copy()); + this.geologyManager = SetupHooks.setup(createGeologyManager(context), context.copy()); + this.baseDecorators = createBaseDecorators(context); + this.postProcessors = createFeatureDecorators(context); + this.terrainHelper = new TerrainHelper((int) world.getSeed(), 0.8F); + this.featureManager = createFeatureManager(context); + this.regionCache = createRegionCache(context); + SetupHooks.setup(getLayerManager(), context.copy()); + SetupHooks.setup(baseDecorators, postProcessors, context.copy()); + } + + @Override + public void setStructureStarts(BiomeAccess biomeAccess, Chunk chunk, ChunkGenerator chunkGenerator, StructureManager structureManager) { + super.setStructureStarts(biomeAccess, chunk, this, structureManager); + } + + @Override + public final void populateBiomes(Chunk chunk) { + ChunkPos pos = chunk.getPos(); + ChunkReader reader = getChunkReader(pos.x, pos.z); + TerraBiomeArray container = getBiomeSource().createBiomeContainer(reader); + ((ProtoChunk) chunk).method_22405(container); + // apply chunk-local heightmap modifications + preProcess(pos, reader, container); + } + + @Override + public final void preProcess(ChunkPos pos, ChunkReader chunk, TerraBiomeArray container) { + chunk.iterate((cell, dx, dz) -> { + Biome biome = container.getBiome(dx, dz); + for (Decorator decorator : getBiomeSource().getDecorators(biome)) { + if (decorator.apply(cell, pos.getStartX() + dx, pos.getStartZ() + dz)) { + return; + } + } + }); + } + + @Override + public final void populateNoise(IWorld world, Chunk chunk) { + DecoratorContext context = new DecoratorContext(chunk, getContext().levels, getContext().terrain, getContext().factory.getClimate()); + TerraBiomeArray container = getBiomeContainer(chunk); + container.getChunkReader().iterate((cell, dx, dz) -> { + int px = context.blockX + dx; + int pz = context.blockZ + dz; + int py = (int) (cell.value * getMaxY()); + context.cell = cell; + context.biome = container.getBiome(dx, dz); + ChunkPopulator.INSTANCE.decorate(chunk, context, px, py, pz); + }); + terrainHelper.flatten(world, chunk, context.blockX, context.blockZ); + } + + @Override + public final void buildSurface(ChunkRegion world, Chunk chunk) { + ChunkSurfaceBuffer buffer = new ChunkSurfaceBuffer(chunk); + SurfaceContext context = getContext().surface(buffer, getConfig()); + TerraBiomeArray container = getBiomeContainer(chunk); + container.getChunkReader().iterate((cell, dx, dz) -> { + int px = context.blockX + dx; + int pz = context.blockZ + dz; + int top = chunk.sampleHeightmap(Heightmap.Type.WORLD_SURFACE_WG, dx, dz) + 1; + + buffer.setSurfaceLevel(top); + + context.cell = cell; + context.biome = container.getBiome(dx, dz); + context.noise = getSurfaceNoise(px, pz) * 15D; + + getSurfaceManager().getSurface(context).buildSurface(px, pz, top, context); + + int py = (int) (cell.value * getMaxY()); + for (ColumnDecorator processor : getBaseDecorators()) { + processor.decorate(buffer, context, px, py, pz); + } + }); + } + + @Override + public void carve(BiomeAccess biomeAccess, Chunk chunk, GenerationStep.Carver carver) { + super.carve(biomeAccess, new ChunkCarverFix(chunk, context.materials), carver); + } + + @Override + public void generateFeatures(ChunkRegion region) { + int chunkX = region.getCenterChunkX(); + int chunkZ = region.getCenterChunkZ(); + Chunk chunk = region.getChunk(chunkX, chunkZ); + TerraBiomeArray container = getBiomeContainer(chunk); + Biome biome = container.getFeatureBiome(); + DecoratorContext context = getContext().decorator(chunk); + + IWorld regionFix = new RegionFix(region, this); + BlockPos pos = new BlockPos(context.blockX, 0, context.blockZ); + + // place biome features + featureManager.decorate(this, regionFix, chunk, biome, pos); + + // run post processes on chunk + postProcess(container.getChunkReader(), container, context); + + // bake biome array & discard gen data + ((ProtoChunk) chunk).method_22405(container.bakeBiomes()); + } + + @Override + public final void postProcess(ChunkReader chunk, TerraBiomeArray container, DecoratorContext context) { + chunk.iterate((cell, dx, dz) -> { + int px = context.blockX + dx; + int pz = context.blockZ + dz; + int py = context.chunk.sampleHeightmap(Heightmap.Type.WORLD_SURFACE_WG, dx, dz); + context.cell = cell; + context.biome = container.getBiome(dx, dz); + for (ColumnDecorator decorator : getPostProcessors()) { + decorator.decorate(context.chunk, context, px, py, pz); + } + }); + } + + @Override + public int getHeightOnGround(int x, int z, Heightmap.Type heightmapType) { + return this.sampleHeight(x, z, heightmapType); // todo may be wrong + } + + @Override + public int sampleHeight(int x, int z, Heightmap.Type type) { + int chunkX = Size.blockToChunk(x); + int chunkZ = Size.blockToChunk(z); + ChunkReader chunk = getChunkReader(chunkX, chunkZ); + Cell cell = chunk.getCell(x, z); + return (int) (cell.value * getMaxY()); + } + + @Override + public BiomeProvider getBiomeSource() { + return biomeProvider; + } + + @Override + public final int getMaxY() { + return getContext().levels.worldHeight; + } + + @Override + public final int getSeaLevel() { + return getContext().levels.waterLevel; + } + + @Override + public int getSpawnHeight() { + return getContext().levels.groundLevel; + } + + public final TerraContext getContext() { + return context; + } + + public final Materials getMaterials() { + return context.materials; + } + + public final GeoManager getGeologyManager() { + return geologyManager; + } + + public final LayerManager getLayerManager() { + return context.materials.getLayerManager(); + } + + public final SurfaceManager getSurfaceManager() { + return surfaceManager; + } + + public final List getBaseDecorators() { + return baseDecorators; + } + + public final List getPostProcessors() { + return postProcessors; + } + + protected TerraBiomeArray getBiomeContainer(Chunk chunk) { + if (chunk.getBiomeArray() instanceof TerraBiomeArray) { + return (TerraBiomeArray) chunk.getBiomeArray(); + } + + ChunkReader view = getChunkReader(chunk.getPos().x, chunk.getPos().z); + TerraBiomeArray container = getBiomeSource().createBiomeContainer(view); + if (chunk instanceof ProtoChunk) { + ((ProtoChunk) chunk).method_22405(container); + } + + return container; + } + + protected FeatureManager createFeatureManager(TerraContext context) { + FeatureModifiers modifiers; + if (context.terraSettings.features.customBiomeFeatures) { + Log.info(" - Custom biome features enabled"); + modifiers = FeatureModifierLoader.load(); + } else { + modifiers = new FeatureModifiers(); + } + + // block ugly features + modifiers.getPredicates().add(Matchers.STONE_BLOBS, FeaturePredicate.DENY); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.DISK), FeaturePredicate.DENY); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.LAKE), FeaturePredicate.DENY); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.SPRING_FEATURE), FeaturePredicate.DENY); + + // limit to deep oceans + modifiers.getPredicates().add(FeatureMatcher.of(Feature.SHIPWRECK), DeepWater.INSTANCE); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.OCEAN_RUIN), DeepWater.INSTANCE); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.OCEAN_MONUMENT), DeepWater.INSTANCE); + + // prevent mineshafts above ground + modifiers.getPredicates().add(FeatureMatcher.of(Feature.MINESHAFT), MinHeight.HEIGHT80); + + // prevent trees/bamboo growing too high up + TreeLine treeLine = new TreeLine(context); + modifiers.getPredicates().add(FeatureTypes.TREE.matcher(), treeLine); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.BAMBOO), treeLine); + modifiers.getDynamic().add(DynamicMatcher.feature(AbstractTreeFeature.class), treeLine); + + return FeatureManager.create(context.world, SetupHooks.setup(modifiers, context.copy())); + } + + protected GeoManager createGeologyManager(TerraContext context) { + return new GeoManager(context); + } + + protected SurfaceManager createSurfaceManager() { + SurfaceManager manager = new SurfaceManager(); + manager.replace(Biomes.FROZEN_OCEAN, new FrozenOcean(context, 20, 15)); + manager.replace(Biomes.DEEP_FROZEN_OCEAN, new FrozenOcean(context, 30, 30)); + return manager; + } + + protected List createBaseDecorators(TerraContext context) { + List processors = new ArrayList<>(); + if (context.terraSettings.features.strataDecorator) { + Log.info(" - Geology decorator enabled"); + processors.add(new GeologyDecorator(geologyManager)); + } + if (context.terraSettings.features.erosionDecorator) { + Log.info(" - Erosion decorator enabled"); + processors.add(new ErosionDecorator(context)); + } + processors.add(new CoastDecorator(context)); + processors.add(new BedrockDecorator()); + return processors; + } + + protected List createFeatureDecorators(TerraContext context) { + List processors = new ArrayList<>(); + if (context.terraSettings.features.naturalSnowDecorator) { + Log.info(" - Natural snow decorator enabled"); + processors.add(new SnowEroder(context)); + } + if (context.terraSettings.features.smoothLayerDecorator) { + Log.info(" - Smooth layer decorator enabled"); + processors.add(new LayerDecorator(context.materials.getLayerManager())); + } + return processors; + } + + protected RegionCache createRegionCache(TerraContext context) { + return RegionGenerator.builder() + .legacy(context.terraSettings.version == 0) + .pool(ThreadPool.getFixed()) + .factory(context.factory) + .size(3, 2) + .build() + .toCache(); + } + + public ChunkReader getChunkReader(int chunkX, int chunkZ) { + return regionCache.getChunk(chunkX, chunkZ); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraContext.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraContext.java new file mode 100644 index 0000000..70e7fa4 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraContext.java @@ -0,0 +1,68 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.WorldGeneratorFactory; +import com.terraforged.core.world.heightmap.Heightmap; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.material.Materials; +import com.terraforged.mod.settings.TerraSettings; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.world.IWorld; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.chunk.ChunkGeneratorConfig; + +public class TerraContext extends GeneratorContext { + + public final IWorld world; + public final Heightmap heightmap; + public final Materials materials; + public final WorldGeneratorFactory factory; + public final TerraSettings terraSettings; + + public TerraContext(IWorld world, Terrains terrain, TerraSettings settings) { + super(terrain, settings, TerraTerrainProvider::new); + this.world = world; + this.materials = new Materials(); + this.terraSettings = settings; + this.factory = new WorldGeneratorFactory(this); + this.heightmap = factory.getHeightmap(); + ItemStack stack = new ItemStack(Items.COBBLESTONE); + stack.getMaxCount(); + } + + public DecoratorContext decorator(Chunk chunk) { + return new DecoratorContext(chunk, levels, terrain, factory.getClimate()); + } + + public SurfaceContext surface(Chunk chunk, ChunkGeneratorConfig settings) { + return new SurfaceContext(chunk, levels, terrain, factory.getClimate(), settings, world.getSeed()); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraGenSettings.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraGenSettings.java new file mode 100644 index 0000000..2ebc5cb --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraGenSettings.java @@ -0,0 +1,41 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.mod.settings.StructureSettings; +import net.minecraft.world.gen.chunk.OverworldChunkGeneratorConfig; + +public class TerraGenSettings extends OverworldChunkGeneratorConfig { + + public TerraGenSettings(StructureSettings settings) { + super.villageDistance *= settings.villageDistance; + super.mansionDistance *= settings.mansionDistance; + super.strongholdDistance *= settings.strongholdDistance; + super.templeDistance *= settings.biomeStructureDistance; + super.oceanMonumentSpacing *= settings.oceanMonumentSpacing; + super.oceanMonumentSeparation *= settings.oceanMonumentSeparation; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraTerrainProvider.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraTerrainProvider.java new file mode 100644 index 0000000..a6365df --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/TerraTerrainProvider.java @@ -0,0 +1,45 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.core.cell.Populator; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.heightmap.RegionConfig; +import com.terraforged.core.world.terrain.provider.StandardTerrainProvider; +import com.terraforged.mod.util.setup.SetupHooks; + +public class TerraTerrainProvider extends StandardTerrainProvider { + + public TerraTerrainProvider(GeneratorContext context, RegionConfig config, Populator defaultPopulator) { + super(context, config, defaultPopulator); + } + + @Override + public void init() { + super.init(); + SetupHooks.setup(this, getContext().copy()); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/ChunkCarverFix.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/ChunkCarverFix.java new file mode 100644 index 0000000..8c6a466 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/ChunkCarverFix.java @@ -0,0 +1,74 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.fix; + +import com.terraforged.api.chunk.ChunkDelegate; +import com.terraforged.api.material.state.States; +import com.terraforged.mod.material.MaterialHelper; +import com.terraforged.mod.material.Materials; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.Chunk; + +public class ChunkCarverFix implements ChunkDelegate { + + private final Chunk delegate; + private final Materials materials; + + public ChunkCarverFix(Chunk chunk, Materials materials) { + this.delegate = chunk; + this.materials = materials; + } + + @Override + public Chunk getDelegate() { + return delegate; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + BlockState state = getDelegate().getBlockState(pos); + if (MaterialHelper.isAir(state.getBlock())) { + return state; + } + if (MaterialHelper.isGrass(state.getBlock())) { + return States.GRASS_BLOCK.get(); + } + if (materials.isStone(state.getBlock())) { + return States.STONE.get(); + } + if (materials.isEarth(state.getBlock())) { + return States.DIRT.get(); + } + if (materials.isClay(state.getBlock())) { + return States.DIRT.get(); + } + if (materials.isSediment(state.getBlock())) { + return States.SAND.get(); + } + return state; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/RegionDelegate.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/RegionDelegate.java new file mode 100644 index 0000000..1085cc4 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/RegionDelegate.java @@ -0,0 +1,589 @@ +package com.terraforged.mod.chunk.fix; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityContext; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.TargetPredicate; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.FluidState; +import net.minecraft.particle.ParticleEffect; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import net.minecraft.world.ChunkRegion; +import net.minecraft.world.Difficulty; +import net.minecraft.world.Heightmap; +import net.minecraft.world.LightType; +import net.minecraft.world.LocalDifficulty; +import net.minecraft.world.RayTraceContext; +import net.minecraft.world.TickScheduler; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.source.BiomeAccess; +import net.minecraft.world.border.WorldBorder; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkManager; +import net.minecraft.world.chunk.ChunkStatus; +import net.minecraft.world.chunk.light.LightingProvider; +import net.minecraft.world.dimension.Dimension; +import net.minecraft.world.level.ColorResolver; +import net.minecraft.world.level.LevelProperties; + +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Stream; + +public class RegionDelegate extends ChunkRegion { + + protected final ChunkRegion region; + + // ChunkRegion init notes: + // - list of chunks passed in must be square (ie (sqrt(size) * sqrt(size) == size) + // - list of chunks must not be empty due to: "list.get(list.size() / 2).getPos()" + public RegionDelegate(ServerWorld world, ChunkRegion region) { + super(world, Collections.singletonList(getMainChunk(region))); + this.region = region; + } + + @Override + public int getCenterChunkX() { + return region.getCenterChunkX(); + } + + @Override + public int getCenterChunkZ() { + return region.getCenterChunkZ(); + } + + @Override + public Chunk getChunk(int chunkX, int chunkZ) { + return region.getChunk(chunkX, chunkZ); + } + + @Override + + public Chunk getChunk(int x, int z, ChunkStatus requiredStatus, boolean nonnull) { + return region.getChunk(x, z, requiredStatus, nonnull); + } + + @Override + public boolean isChunkLoaded(int chunkX, int chunkZ) { + return region.isChunkLoaded(chunkX, chunkZ); + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return region.getBlockState(pos); + } + + @Override + public FluidState getFluidState(BlockPos pos) { + return region.getFluidState(pos); + } + + @Override + + public PlayerEntity getClosestPlayer(double x, double y, double z, double distance, Predicate predicate) { + return region.getClosestPlayer(x, y, z, distance, predicate); + } + + @Override + public int getAmbientDarkness() { + return region.getAmbientDarkness(); + } + + @Override + public BiomeAccess getBiomeAccess() { + return region.getBiomeAccess(); + } + + @Override + public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) { + return region.getBiomeForNoiseGen(biomeX, biomeY, biomeZ); + } + + + @Override + public LightingProvider getLightingProvider() { + return region.getLightingProvider(); + } + + @Override + public boolean breakBlock(BlockPos pos, boolean drop, Entity breakingEntity) { + return region.breakBlock(pos, drop, breakingEntity); + } + + @Override + public BlockEntity getBlockEntity(BlockPos pos) { + return region.getBlockEntity(pos); + } + + @Override + public boolean setBlockState(BlockPos pos, BlockState newState, int flags) { + return region.setBlockState(pos, newState, flags); + } + + @Override + public boolean spawnEntity(Entity entityIn) { + return region.spawnEntity(entityIn); + } + + @Override + public boolean removeBlock(BlockPos pos, boolean isMoving) { + return region.removeBlock(pos, isMoving); + } + + @Override + public WorldBorder getWorldBorder() { + return region.getWorldBorder(); + } + + @Override + public boolean isClient() { + return region.isClient(); + } + + @Override + @Deprecated + public ServerWorld getWorld() { + return region.getWorld(); + } + + + @Override + public LevelProperties getLevelProperties() { + return region.getLevelProperties(); + } + + @Override + public LocalDifficulty getLocalDifficulty(BlockPos pos) { + return region.getLocalDifficulty(pos); + } + + @Override + public ChunkManager getChunkManager() { + return region.getChunkManager(); + } + + @Override + public long getSeed() { + return region.getSeed(); + } + + @Override + public TickScheduler getBlockTickScheduler() { + return region.getBlockTickScheduler(); + } + + @Override + public TickScheduler getFluidTickScheduler() { + return region.getFluidTickScheduler(); + } + + @Override + public int getSeaLevel() { + return region.getSeaLevel(); + } + + @Override + public Random getRandom() { + return region.getRandom(); + } + + @Override + public void updateNeighbors(BlockPos pos, Block blockIn) { + region.updateNeighbors(pos, blockIn); + } + + @Override + public int getTopY(Heightmap.Type heightmapType, int x, int z) { + return region.getTopY(heightmapType, x, z); + } + + @Override + public void playSound(PlayerEntity player, BlockPos pos, SoundEvent soundIn, SoundCategory category, float volume, float pitch) { + region.playSound(player, pos, soundIn, category, volume, pitch); + } + + @Override + public void addParticle(ParticleEffect particleData, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { + region.addParticle(particleData, x, y, z, xSpeed, ySpeed, zSpeed); + } + + @Override + public void playLevelEvent(PlayerEntity player, int type, BlockPos pos, int data) { + region.playLevelEvent(player, type, pos, data); + } + + @Override + @Environment(EnvType.CLIENT) + public BlockPos getSpawnPos() { + return region.getSpawnPos(); + } + + @Override + public Dimension getDimension() { + return region.getDimension(); + } + + @Override + public boolean testBlockState(BlockPos p_217375_1_, Predicate p_217375_2_) { + return region.testBlockState(p_217375_1_, p_217375_2_); + } + + @Override + public List getEntities(Class clazz, Box aabb, Predicate filter) { + return region.getEntities(clazz, aabb, filter); + } + + @Override + public List getEntities(Entity entityIn, Box boundingBox, Predicate predicate) { + return region.getEntities(entityIn, boundingBox, predicate); + } + + @Override + public List getPlayers() { + return region.getPlayers(); + } + + @Override + public float getMoonSize() { + return region.getMoonSize(); + } + + @Override + public float getSkyAngle(float partialTicks) { + return region.getSkyAngle(partialTicks); + } + + @Override + @Environment(EnvType.CLIENT) + public int getMoonPhase() { + return region.getMoonPhase(); + } + + @Override + public Difficulty getDifficulty() { + return region.getDifficulty(); + } + + @Override + public void playLevelEvent(int type, BlockPos pos, int data) { + region.playLevelEvent(type, pos, data); + } + + @Override + public Stream getEntityCollisions(Entity entityIn, Box aabb, Set entitiesToIgnore) { + return region.getEntityCollisions(entityIn, aabb, entitiesToIgnore); + } + + + @Override + public boolean intersectsEntities(Entity entityIn, VoxelShape shape) { + return region.intersectsEntities(entityIn, shape); + } + + @Override + public BlockPos getTopPosition(Heightmap.Type heightmapType, BlockPos pos) { + return region.getTopPosition(heightmapType, pos); + } + + @Override + public List getEntitiesIncludingUngeneratedChunks(Class entityClass, Box box, Predicate predicate) { + return region.getEntitiesIncludingUngeneratedChunks(entityClass, box, predicate); + } + + @Override + public List getEntities(Entity entityIn, Box bb) { + return region.getEntities(entityIn, bb); + } + + @Override + public List getNonSpectatingEntities(Class p_217357_1_, Box p_217357_2_) { + return region.getNonSpectatingEntities(p_217357_1_, p_217357_2_); + } + + @Override + public List getEntitiesIncludingUngeneratedChunks(Class p_225317_1_, Box p_225317_2_) { + return region.getEntitiesIncludingUngeneratedChunks(p_225317_1_, p_225317_2_); + } + + @Override + + public PlayerEntity getClosestPlayer(Entity entityIn, double distance) { + return region.getClosestPlayer(entityIn, distance); + } + + @Override + public PlayerEntity getClosestPlayer(double x, double y, double z, double distance, boolean creativePlayers) { + return region.getClosestPlayer(x, y, z, distance, creativePlayers); + } + + @Override + public PlayerEntity getClosestPlayer(double x, double y, double z) { + return region.getClosestPlayer(x, y, z); + } + + @Override + public boolean isPlayerInRange(double x, double y, double z, double distance) { + return region.isPlayerInRange(x, y, z, distance); + } + + @Override + public PlayerEntity getClosestPlayer(TargetPredicate predicate, LivingEntity target) { + return region.getClosestPlayer(predicate, target); + } + + @Override + public PlayerEntity getClosestPlayer(TargetPredicate predicate, LivingEntity target, double p_217372_3_, double p_217372_5_, double p_217372_7_) { + return region.getClosestPlayer(predicate, target, p_217372_3_, p_217372_5_, p_217372_7_); + } + + @Override + public PlayerEntity getClosestPlayer(TargetPredicate predicate, double x, double y, double z) { + return region.getClosestPlayer(predicate, x, y, z); + } + + @Override + public T getClosestEntity(Class entityClazz, TargetPredicate p_217360_2_, LivingEntity target, + double x, double y, double z, Box boundingBox) { + return region.getClosestEntity(entityClazz, p_217360_2_, target, x, y, z, boundingBox); + } + + @Override + public T getClosestEntityIncludingUngeneratedChunks(Class p_225318_1_, TargetPredicate p_225318_2_, + LivingEntity p_225318_3_, + double p_225318_4_, double p_225318_6_, double p_225318_8_, Box p_225318_10_) { + return region.getClosestEntityIncludingUngeneratedChunks(p_225318_1_, p_225318_2_, p_225318_3_, p_225318_4_, p_225318_6_, p_225318_8_, + p_225318_10_); + } + + @Override + + public T getClosestEntity(List entities, TargetPredicate predicate, LivingEntity target, double x, double y, + double z) { + return region.getClosestEntity(entities, predicate, target, x, y, z); + } + + @Override + public List getPlayers(TargetPredicate predicate, LivingEntity target, Box box) { + return region.getPlayers(predicate, target, box); + } + + @Override + public List getTargets(Class p_217374_1_, TargetPredicate p_217374_2_, + LivingEntity p_217374_3_, Box p_217374_4_) { + return region.getTargets(p_217374_1_, p_217374_2_, p_217374_3_, p_217374_4_); + } + + @Override + + public PlayerEntity getPlayerByUuid(UUID uniqueIdIn) { + return region.getPlayerByUuid(uniqueIdIn); + } + + @Override + public Biome getBiome(BlockPos p_226691_1_) { + return region.getBiome(p_226691_1_); + } + + @Override + @Environment(EnvType.CLIENT) + public int getColor(BlockPos blockPosIn, ColorResolver colorResolverIn) { + return region.getColor(blockPosIn, colorResolverIn); + } + + @Override + public Biome getGeneratorStoredBiome(int biomeX, int biomeY, int biomeZ) { + return region.getGeneratorStoredBiome(biomeX, biomeY, biomeZ); + } + + @Override + public boolean isAir(BlockPos pos) { + return region.isAir(pos); + } + + @Override + public boolean isSkyVisible(BlockPos pos) { + return region.isSkyVisible(pos); + } + + @Override + @Deprecated + public float getBrightness(BlockPos pos) { + return region.getBrightness(pos); + } + + @Override + public int getStrongRedstonePower(BlockPos pos, Direction direction) { + return region.getStrongRedstonePower(pos, direction); + } + + @Override + public Chunk getChunk(BlockPos pos) { + return region.getChunk(pos); + } + + @Override + public Chunk getChunk(int chunkX, int chunkZ, ChunkStatus requiredStatus) { + return region.getChunk(chunkX, chunkZ, requiredStatus); + } + + @Override + public BlockView getExistingChunk(int p_225522_1_, int p_225522_2_) { + return region.getExistingChunk(p_225522_1_, p_225522_2_); + } + + @Override + public boolean isWater(BlockPos pos) { + return region.isWater(pos); + } + + @Override + public boolean containsFluid(Box bb) { + return region.containsFluid(bb); + } + + @Override + public int getLightLevel(BlockPos pos) { + return region.getLightLevel(pos); + } + + @Override + public int getBaseLightLevel(BlockPos pos, int amount) { + return region.getBaseLightLevel(pos, amount); + } + + @Override + @Deprecated + public boolean isChunkLoaded(BlockPos pos) { + return region.isChunkLoaded(pos); + } + + + // @Override todo lol what is this + // public boolean isRegionLoaded(BlockPos center, int range) { + // return region.isRegionLoaded(center, range); + // } + + @Override + @Deprecated + public boolean isRegionLoaded(BlockPos from, BlockPos to) { + return region.isRegionLoaded(from, to); + } + + @Override + @Deprecated + public boolean isRegionLoaded(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + return region.isRegionLoaded(minX, minY, minZ, maxX, maxY, maxZ); + } + + @Override + public int getLightLevel(LightType lightTypeIn, BlockPos blockPosIn) { + return region.getLightLevel(lightTypeIn, blockPosIn); + } + + @Override + public int getLightLevel(BlockPos blockPosIn, int amount) { + return region.getLightLevel(blockPosIn, amount); + } + + @Override + public boolean isSkyVisibleAllowingSea(BlockPos pos) { + return region.isSkyVisibleAllowingSea(pos); + } + + @Override + public int getLuminance(BlockPos pos) { + return region.getLuminance(pos); + } + + @Override + public int getMaxLightLevel() { + return region.getMaxLightLevel(); + } + + @Override + public int getHeight() { + return region.getHeight(); + } + + @Override + public BlockHitResult rayTrace(RayTraceContext context) { + return region.rayTrace(context); + } + + @Override + public BlockHitResult rayTraceBlock(Vec3d p_217296_1_, Vec3d p_217296_2_, BlockPos p_217296_3_, VoxelShape p_217296_4_, + BlockState p_217296_5_) { + return region.rayTraceBlock(p_217296_1_, p_217296_2_, p_217296_3_, p_217296_4_, p_217296_5_); + } + + @Override + public boolean canPlace(BlockState state, BlockPos pos, EntityContext context) { + return region.canPlace(state, pos, context); + } + + @Override + public boolean intersectsEntities(Entity entity) { + return region.intersectsEntities(entity); + } + + @Override + public boolean doesNotCollide(Box box) { + return region.doesNotCollide(box); + } + + @Override + public boolean doesNotCollide(Entity entity) { + return region.doesNotCollide(entity); + } + + @Override + public boolean doesNotCollide(Entity entity, Box box) { + return region.doesNotCollide(entity, box); + } + + @Override + public boolean doesNotCollide(Entity entity, Box entityBoundingBox, Set otherEntities) { + return region.doesNotCollide(entity, entityBoundingBox, otherEntities); + } + + @Override + public Stream getCollisions(Entity entity, Box box, Set excluded) { + return region.getCollisions(entity, box, excluded); + } + + @Override + public Stream getBlockCollisions(Entity entity, Box box) { + return region.getBlockCollisions(entity, box); + } + + @Override + public boolean breakBlock(BlockPos pos, boolean drop) { + return region.breakBlock(pos, drop); + } + + + private static Chunk getMainChunk(ChunkRegion region) { + int x = region.getCenterChunkX(); + int z = region.getCenterChunkZ(); + return region.getChunk(x, z); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/RegionFix.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/RegionFix.java new file mode 100644 index 0000000..5a46777 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/fix/RegionFix.java @@ -0,0 +1,50 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.fix; + +import net.minecraft.world.ChunkRegion; +import net.minecraft.world.gen.chunk.ChunkGenerator; + +// fixes hard-coded water and world height values +public class RegionFix extends RegionDelegate { + + private final ChunkGenerator generator; + + public RegionFix(ChunkRegion region, ChunkGenerator generator) { + super(region.getWorld(), region); + this.generator = generator; + } + + @Override + public int getSeaLevel() { + return generator.getSeaLevel(); + } + + @Override + public int getHeight() { + return generator.getMaxY(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/Test.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/Test.java new file mode 100644 index 0000000..57df63f --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/Test.java @@ -0,0 +1,44 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.test; + +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.ModBiomes; +import net.minecraft.world.biome.Biome; + +public class Test { + + public static boolean fixedBiome = true; + + public static Terrain getTerrainType(Terrains terrains) { + return terrains.mountains; + } + + public static Biome getBiome() { + return ModBiomes.TAIGA_SCRUB; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/TestBiomeProvider.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/TestBiomeProvider.java new file mode 100644 index 0000000..728d0e9 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/TestBiomeProvider.java @@ -0,0 +1,44 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.test; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.biome.Biome; + +public class TestBiomeProvider extends BiomeProvider { + + public TestBiomeProvider(TerraContext chunkContext) { + super(chunkContext); + } + + @Override + public Biome getBiome(Cell cell, int x, int z) { + return Test.getBiome(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/TestChunkGenerator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/TestChunkGenerator.java new file mode 100644 index 0000000..c02dbcf --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/chunk/test/TestChunkGenerator.java @@ -0,0 +1,86 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.test; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.cell.Populator; +import com.terraforged.core.region.RegionCache; +import com.terraforged.core.region.RegionGenerator; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.WorldGeneratorFactory; +import com.terraforged.core.world.heightmap.WorldHeightmap; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.TerraChunkGenerator; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.gen.chunk.ChunkGeneratorConfig; + +public class TestChunkGenerator extends TerraChunkGenerator { + + private final BiomeProvider biomeProvider; + + public TestChunkGenerator(TerraContext context, BiomeProvider biomeProvider, ChunkGeneratorConfig settings) { + super(context, biomeProvider, settings); + this.biomeProvider = new TestBiomeProvider(context); + } + + @Override + protected RegionCache createRegionCache(TerraContext context) { + return RegionGenerator.builder() + .factory(new WorldGeneratorFactory(context, new TestHeightMap(context))) + .pool(ThreadPool.getFixed()) + .size(3, 2) + .build() + .toCache(true); + } + + @Override + public BiomeProvider getBiomeSource() { + return biomeProvider; + } + + private static class TestHeightMap extends WorldHeightmap { + + private final Populator populator; + + public TestHeightMap(GeneratorContext context) { + super(context); + this.populator = getPopulator(Test.getTerrainType(context.terrain)); + } + + @Override + public void apply(Cell cell, float x, float y) { + super.apply(cell, x, y); + populator.apply(cell, x, y); + } + + @Override + public void tag(Cell cell, float x, float y) { + populator.tag(cell, x, y); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/TerraCommand.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/TerraCommand.java new file mode 100644 index 0000000..8aa85b8 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/TerraCommand.java @@ -0,0 +1,272 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.WorldGenerator; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.TerraChunkGenerator; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.command.arg.BiomeArgType; +import com.terraforged.mod.command.arg.TerrainArgType; +import com.terraforged.mod.command.search.BiomeSearchTask; +import com.terraforged.mod.command.search.BothSearchTask; +import com.terraforged.mod.command.search.Search; +import com.terraforged.mod.command.search.TerrainSearchTask; +import com.terraforged.mod.data.DataGen; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +import net.minecraft.text.Texts; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.source.BiomeSource; +import net.minecraft.world.biome.source.HorizontalVoronoiBiomeAccessType; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.gen.chunk.ChunkGenerator; + +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +public class TerraCommand { + + public static void register(CommandDispatcher dispatcher) { + dispatcher.register(command()); + } + + private static LiteralArgumentBuilder command() { + return CommandManager.literal("terra") + .requires(source -> source.hasPermissionLevel(2)) + .then(CommandManager.literal("query") + .executes(TerraCommand::query)) + .then(CommandManager.literal("data") + .then(CommandManager.literal("dump") + .executes(TerraCommand::dump))) + .then(CommandManager.literal("debug") + .executes(TerraCommand::debugBiome)) + .then(CommandManager.literal("locate") + .then(CommandManager.argument("biome", BiomeArgType.biome()) + .executes(TerraCommand::findBiome) + .then(CommandManager.argument("terrain", TerrainArgType.terrain()) + .executes(TerraCommand::findTerrainAndBiome))) + .then(CommandManager.argument("terrain", TerrainArgType.terrain()) + .executes(TerraCommand::findTerrain) + .then(CommandManager.argument("biome", BiomeArgType.biome()) + .executes(TerraCommand::findTerrainAndBiome)))); + } + + private static int query(CommandContext context) throws CommandSyntaxException { + getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + BlockPos pos = context.getSource().getPlayer().getBlockPos(); + BiomeProvider biomeProvider = getBiomeProvider(context); + Cell cell = biomeProvider.lookupPos(pos.getX(), pos.getZ()); + Biome biome = biomeProvider.getBiome(cell, pos.getX(), pos.getZ()); + context.getSource().sendFeedback( + new LiteralText("Terrain=" + cell.tag.getName() + ", Biome=" + Registry.BIOME.getId(biome)), + false + ); + + return Command.SINGLE_SUCCESS; + } + + private static int dump(CommandContext context) throws CommandSyntaxException { + context.getSource().sendFeedback( + new LiteralText("Exporting data"), + true + ); + DataGen.dumpData(); + return Command.SINGLE_SUCCESS; + } + + private static int debugBiome(CommandContext context) throws CommandSyntaxException { + ServerPlayerEntity player = context.getSource().getPlayer(); + BlockPos position = player.getBlockPos(); + int x = position.getX(); + int y = position.getY(); + int z = position.getZ(); + + long seed = player.getServerWorld().getSeed(); + Biome actual = player.getServerWorld().getBiome(position); + Biome biome2 = HorizontalVoronoiBiomeAccessType.INSTANCE + .getBiome(seed, x, 0, z, player.getServerWorld().getChunkManager().getChunkGenerator().getBiomeSource()); + + context.getSource().sendFeedback(new LiteralText( + "Actual Biome = " + Registry.BIOME.getId(actual) + + "\nLookup Biome = " + Registry.BIOME.getId(biome2)), + false + ); + + return Command.SINGLE_SUCCESS; + } + + private static int findTerrain(CommandContext context) throws CommandSyntaxException { + // get the generator's context + TerraContext terraContext = getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + Terrain terrain = TerrainArgType.getTerrain(context, "terrain"); + Terrain target = getTerrainInstance(terrain, terraContext.terrain); + BlockPos pos = context.getSource().getPlayer().getBlockPos(); + UUID playerID = context.getSource().getPlayer().getUuid(); + MinecraftServer server = context.getSource().getMinecraftServer(); + WorldGenerator worldGenerator = terraContext.factory.get(); + Search search = new TerrainSearchTask(pos, worldGenerator, target); + doSearch(server, playerID, search); + context.getSource().sendFeedback(new LiteralText("Searching..."), false); + + return Command.SINGLE_SUCCESS; + } + + private static int findBiome(CommandContext context) throws CommandSyntaxException { + // get the generator's context + TerraContext terraContext = getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + Biome biome = BiomeArgType.getBiome(context, "biome"); + BlockPos pos = context.getSource().getPlayer().getBlockPos(); + UUID playerID = context.getSource().getPlayer().getUuid(); + MinecraftServer server = context.getSource().getMinecraftServer(); + ServerWorld reader = context.getSource().getPlayer().getServerWorld(); + Search search = new BiomeSearchTask(pos, reader, biome); + doSearch(server, playerID, search); + context.getSource().sendFeedback(new LiteralText("Searching..."), false); + + return Command.SINGLE_SUCCESS; + } + + private static int findTerrainAndBiome(CommandContext context) throws CommandSyntaxException { + // get the generator's context + TerraContext terraContext = getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + Terrain terrain = TerrainArgType.getTerrain(context, "terrain"); + Terrain target = getTerrainInstance(terrain, terraContext.terrain); + Biome biome = BiomeArgType.getBiome(context, "biome"); + BlockPos pos = context.getSource().getPlayer().getBlockPos(); + ServerWorld world = context.getSource().getPlayer().getServerWorld(); + UUID playerID = context.getSource().getPlayer().getUuid(); + MinecraftServer server = context.getSource().getMinecraftServer(); + WorldGenerator worldGenerator = terraContext.factory.get(); + Search biomeSearch = new BiomeSearchTask(pos, world, biome); + Search terrainSearch = new TerrainSearchTask(pos, worldGenerator, target); + Search search = new BothSearchTask(pos, biomeSearch, terrainSearch); + doSearch(server, playerID, search); + context.getSource().sendFeedback(new LiteralText("Searching..."), false); + + return Command.SINGLE_SUCCESS; + } + + private static void doSearch(MinecraftServer server, UUID userId, Supplier supplier) { + CompletableFuture.supplyAsync(supplier).thenAcceptAsync(pos -> { + PlayerEntity player = server.getPlayerManager().getPlayer(userId); + if (player == null) { + return; + } + + if (pos.getX() == 0 && pos.getZ() == 0) { + player.sendMessage(new LiteralText("Location not found :[")); + return; + } + + Text result = new LiteralText("Nearest match: ") + .append(createTeleportMessage(pos)); + + player.sendMessage(result); + }, server); + } + + private static Optional getContext(CommandContext context) throws CommandSyntaxException { + MinecraftServer server = context.getSource().getMinecraftServer(); + DimensionType dimension = context.getSource().getPlayer().dimension; + ChunkGenerator generator = server.getWorld(dimension).getChunkManager().getChunkGenerator(); + if (generator instanceof TerraChunkGenerator) { + TerraChunkGenerator gen = (TerraChunkGenerator) generator; + return Optional.of(gen.getContext()); + } + return Optional.empty(); + } + + // the terrain parsed from the command will not be the same instance as used in the + // world generator, so find the matching instance by name + private static Terrain getTerrainInstance(Terrain find, Terrains terrains) { + for (Terrain t : terrains.index) { + if (t.getName().equals(find.getName())) { + return t; + } + } + return find; + } + + private static BiomeProvider getBiomeProvider(CommandContext context) { + return (BiomeProvider) context.getSource().getWorld().getChunkManager().getChunkGenerator().getBiomeSource(); + } + + private static CommandSyntaxException createException(String type, String message, Object... args) { + return new CommandSyntaxException( + new SimpleCommandExceptionType(new LiteralText(type)), + new LiteralText(String.format(message, args)) + ); + } + + private static Text createTeleportMessage(BlockPos pos) { + return Texts.bracketed(new TranslatableText( + "chat.coordinates", pos.getX(), "~", pos.getZ() + )).styled((style) -> style.setColor(Formatting.GREEN) + .setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tp @s " + pos.getX() + " ~ " + pos.getZ())) + .setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableText("chat.coordinates.tooltip"))) + ); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/arg/BiomeArgType.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/arg/BiomeArgType.java new file mode 100644 index 0000000..bd32ec5 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/arg/BiomeArgType.java @@ -0,0 +1,71 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.arg; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.server.command.CommandSource; +import net.minecraft.text.LiteralText; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; + +import java.util.concurrent.CompletableFuture; + +public class BiomeArgType implements ArgumentType { + + @Override + public Biome parse(StringReader reader) throws CommandSyntaxException { + Identifier resourcelocation = Identifier.fromCommandInput(reader); + return Registry.BIOME.getOrEmpty(resourcelocation) + .orElseThrow(() -> createException("Invalid biome", "%s is not a valid biome", resourcelocation)); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder suggestions) { + return CommandSource.suggestIdentifiers(Registry.BIOME.getIds(), suggestions); + } + + private static CommandSyntaxException createException(String type, String message, Object... args) { + return new CommandSyntaxException( + new SimpleCommandExceptionType(new LiteralText(type)), + new LiteralText(String.format(message, args)) + ); + } + + public static ArgumentType biome() { + return new BiomeArgType(); + } + + public static Biome getBiome(CommandContext context, String name) { + return context.getArgument(name, Biome.class); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/arg/TerrainArgType.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/arg/TerrainArgType.java new file mode 100644 index 0000000..8994b66 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/arg/TerrainArgType.java @@ -0,0 +1,116 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.arg; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import com.terraforged.core.settings.Settings; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import net.minecraft.server.command.CommandSource; +import net.minecraft.text.LiteralText; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class TerrainArgType implements ArgumentType { + + private final List terrains = getTerrains(); + + @Override + public Terrain parse(StringReader reader) throws CommandSyntaxException { + int cursor = reader.getCursor(); + String name = reader.readString(); + for (Terrain terrain : terrains) { + if (terrain.getName().equalsIgnoreCase(name)) { + return terrain; + } + } + reader.setCursor(cursor); + throw createException("Invalid terrain", "%s is not a valid terrain type", name); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder suggestions) { + return CommandSource.suggestMatching(terrains.stream().map(Terrain::getName), suggestions); + } + + public static ArgumentType terrain() { + return new TerrainArgType(); + } + + public static Terrain getTerrain(CommandContext context, String name) { + return context.getArgument(name, Terrain.class); + } + + private static CommandSyntaxException createException(String type, String message, Object... args) { + return new CommandSyntaxException( + new SimpleCommandExceptionType(new LiteralText(type)), + new LiteralText(String.format(message, args)) + ); + } + + private static List getTerrains() { + Terrains terrains = Terrains.create(new Settings()); + List result = new ArrayList<>(); + + for (int i = 0; i < terrains.index.size(); i++) { + Terrain terrain = terrains.index.get(i); + result.add(terrain); + if (dontMix(terrain, terrains)) { + continue; + } + for (int j = i + 1; j < terrains.index.size(); j++) { + Terrain other = terrains.index.get(j); + if (dontMix(other, terrains)) { + continue; + } + Terrain mix = new Terrain(terrain.getName() + "-" + other.getName(), -1); + result.add(mix); + } + } + + return result; + } + + private static boolean dontMix(Terrain terrain, Terrains terrains) { + return terrain == terrains.ocean + || terrain == terrains.deepOcean + || terrain == terrains.river + || terrain == terrains.riverBanks + || terrain == terrains.beach + || terrain == terrains.coast + || terrain == terrains.volcano + || terrain == terrains.volcanoPipe + || terrain == terrains.lake; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/BiomeSearchTask.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/BiomeSearchTask.java new file mode 100644 index 0000000..3ef85e6 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/BiomeSearchTask.java @@ -0,0 +1,27 @@ +package com.terraforged.mod.command.search; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldView; +import net.minecraft.world.biome.Biome; + +public class BiomeSearchTask extends Search { + + private final Biome biome; + private final WorldView reader; + + public BiomeSearchTask(BlockPos center, WorldView reader, Biome biome) { + super(center, 128); + this.reader = reader; + this.biome = biome; + } + + @Override + public int getSpacing() { + return 10; + } + + @Override + public boolean test(BlockPos pos) { + return reader.getGeneratorStoredBiome(pos.getX() >> 2, pos.getY(), pos.getZ() >> 2) == biome; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/BothSearchTask.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/BothSearchTask.java new file mode 100644 index 0000000..8dd576e --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/BothSearchTask.java @@ -0,0 +1,27 @@ +package com.terraforged.mod.command.search; + +import net.minecraft.util.math.BlockPos; + +public class BothSearchTask extends Search { + + private final int spacing; + private final Search a; + private final Search b; + + public BothSearchTask(BlockPos center, Search a, Search b) { + super(center, Math.min(a.getMinRadius(), b.getMinRadius())); + this.spacing = Math.min(a.getSpacing(), b.getSpacing()); + this.a = a; + this.b = b; + } + + @Override + public int getSpacing() { + return spacing; + } + + @Override + public boolean test(BlockPos pos) { + return a.test(pos) && b.test(pos); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/Search.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/Search.java new file mode 100644 index 0000000..a27dc80 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/Search.java @@ -0,0 +1,84 @@ +package com.terraforged.mod.command.search; + +import net.minecraft.util.math.BlockPos; + +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +public abstract class Search implements Supplier { + + protected static final int MIN_RADIUS = 128; + protected static final int MAX_RADIUS = 24000; + + private final BlockPos center; + private final int minRadius; + private final int maxRadius; + private final double minRadius2; + + public Search(BlockPos center) { + this(center, MIN_RADIUS); + } + + public Search(BlockPos center, int minRadius) { + this(center, minRadius, MAX_RADIUS); + } + + public Search(BlockPos center, int minRadius, int maxRadius) { + this.center = center; + this.minRadius = minRadius; + this.minRadius2 = minRadius * minRadius; + this.maxRadius = Math.min(maxRadius, MAX_RADIUS); + } + + public int getMinRadius() { + return minRadius; + } + + public int getSpacing() { + return 16; + } + + @Override + public BlockPos get() { + int radius = maxRadius; + + int x = 0; + int z = 0; + int dx = 0; + int dz = -1; + int size = radius + 1 + radius; + long max = (long) size * (long) size; + long timeOut = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(30); + BlockPos.Mutable pos = new BlockPos.Mutable(); + + for (long i = 0; i < max; i++) { + if (System.currentTimeMillis() > timeOut) { + break; + } + + if ((-radius <= x) && (x <= radius) && (-radius <= z) && (z <= radius)) { + pos.set(center.getX() + (x * getSpacing()), center.getY(), center.getZ() + (z * getSpacing())); + if (center.getSquaredDistance(pos) >= minRadius2) { + if (test(pos)) { + return pos.toImmutable(); + } + } + } + + if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) { + size = dx; + dx = -dz; + dz = size; + } + + x += dx; + z += dz; + } + + System.out.println("LAST POS: " + pos); + + return BlockPos.ORIGIN; + } + + public abstract boolean test(BlockPos pos); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/TerrainSearchTask.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/TerrainSearchTask.java new file mode 100644 index 0000000..a48e45c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/command/search/TerrainSearchTask.java @@ -0,0 +1,30 @@ +package com.terraforged.mod.command.search; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.WorldGenerator; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.util.math.BlockPos; + +public class TerrainSearchTask extends Search { + + private final Terrain type; + private final WorldGenerator generator; + private final Cell cell = new Cell<>(); + + public TerrainSearchTask(BlockPos center, WorldGenerator generator, Terrain type) { + super(center, 256); + this.type = type; + this.generator = generator; + } + + @Override + public int getSpacing() { + return 20; + } + + @Override + public boolean test(BlockPos pos) { + generator.getHeightmap().apply(cell, pos.getX(), pos.getZ()); + return cell.tag == type; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/DataGen.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/DataGen.java new file mode 100644 index 0000000..2139a28 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/DataGen.java @@ -0,0 +1,72 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import net.minecraft.util.Identifier; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; + +public class DataGen { + + public static void dumpData() { + File dataDir = new File("data"); + WorldGenBiomes.genBiomeMap(dataDir); + WorldGenBlocks.genBlockTags(dataDir); + WorldGenFeatures.genBiomeFeatures(dataDir); + } + + protected static void write(File file, IOConsumer consumer) { + if (file.getParentFile().exists() || file.getParentFile().mkdirs()) { + try (Writer writer = new BufferedWriter(new FileWriter(file))) { + consumer.accept(writer); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + protected static void write(JsonElement json, Writer writer) { + new GsonBuilder().setPrettyPrinting().create().toJson(json, writer); + } + + protected static String getJsonPath(String type, Identifier location) { + if (location == null) { + return "unknown"; + } + return location.getNamespace() + "/" + type + "/" + location.getPath() + ".json"; + } + + public interface IOConsumer { + + void accept(Writer writer) throws IOException; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenBiomes.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenBiomes.java new file mode 100644 index 0000000..53f4c9d --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenBiomes.java @@ -0,0 +1,83 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.provider.BiomeHelper; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.Set; + +public class WorldGenBiomes extends DataGen { + + public static void genBiomeMap(File dataDir) { + BiomeMap map = BiomeHelper.getDefaultBiomeMap(); + for (BiomeType type : BiomeType.values()) { + genBiomes(dataDir, type, map); + } + + try (Writer writer = new BufferedWriter(new FileWriter(new File("biome_map.json")))) { + new GsonBuilder().setPrettyPrinting().create().toJson(map.toJson(), writer); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void genBiomes(File dir, BiomeType type, BiomeMap map) { + String path = getJsonPath("tags/biomes", getName(type)); + + write(new File(dir, path), writer -> { + Set biomes = map.getBiomes(type); + JsonObject root = new JsonObject(); + JsonArray values = new JsonArray(); + + root.addProperty("replaceable", false); + root.add("values", values); + + biomes.stream() + .map(b -> String.valueOf(Registry.BIOME.getId(b))) + .sorted() + .forEach(values::add); + + write(root, writer); + }); + } + + private static Identifier getName(BiomeType type) { + return new Identifier("terraforged", type.name().toLowerCase()); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenBlocks.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenBlocks.java new file mode 100644 index 0000000..2498d66 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenBlocks.java @@ -0,0 +1,64 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.mod.material.Materials; +import net.minecraft.block.Block; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +import java.io.File; +import java.util.Collection; + +public class WorldGenBlocks extends DataGen { + + public static void genBlockTags(File dataDir) { + if (dataDir.exists() || dataDir.mkdirs()) { + Materials materials = new Materials(); + printMaterials(dataDir, "stone", materials.getStone()); + printMaterials(dataDir, "dirt", materials.getDirt()); + printMaterials(dataDir, "clay", materials.getClay()); + printMaterials(dataDir, "sediment",materials.getSediment()); + printMaterials(dataDir, "ore", materials.getOre()); + } + } + + private static void printMaterials(File dir, String name, Collection blocks) { + String path = getJsonPath("tags/blocks", new Identifier("terraforged", name)); + write(new File(dir, path), writer -> { + JsonObject root = new JsonObject(); + JsonArray values = new JsonArray(); + root.addProperty("replace", false); + root.add("values", values); + for (Block block : blocks) { + values.add(String.valueOf(Registry.BLOCK.getId(block))); + } + write(root, writer); + }); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenFeatures.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenFeatures.java new file mode 100644 index 0000000..38c7016 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/data/WorldGenFeatures.java @@ -0,0 +1,68 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.JsonOps; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.feature.ConfiguredFeature; + +import java.io.File; + +public class WorldGenFeatures extends DataGen { + + public static void genBiomeFeatures(File dataDir) { + if (dataDir.exists() || dataDir.mkdirs()) { + for (Biome biome : Registry.BIOME) { + genBiomeFeatures(dataDir, biome); + } + } + } + + private static void genBiomeFeatures(File dir, Biome biome) { + write(new File(dir, getJsonPath("features", Registry.BIOME.getId(biome))), writer -> { + JsonObject root = new JsonObject(); + for (GenerationStep.Feature type : GenerationStep.Feature.values()) { + JsonArray features = new JsonArray(); + for (ConfiguredFeature feature : biome.getFeaturesForStep(type)) { + try { + Dynamic dynamic = feature.serialize(JsonOps.INSTANCE); + features.add(dynamic.getValue()); + } catch (NullPointerException e) { + new NullPointerException("Badly written feature: " + Registry.FEATURE.getId(feature.feature)).printStackTrace(); + } + } + root.add(type.getName(), features); + } + write(root, writer); + }); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/ChunkPopulator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/ChunkPopulator.java new file mode 100644 index 0000000..87e826f --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/ChunkPopulator.java @@ -0,0 +1,49 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import net.minecraft.world.chunk.IChunk; + +public class ChunkPopulator implements ColumnDecorator { + + public static final ChunkPopulator INSTANCE = new ChunkPopulator(); + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.tag == context.terrains.volcanoPipe && context.cell.riverMask > 0.25F) { + int lavaStart = Math.max(context.levels.waterY + 10, y - 30); + int lavaEnd = Math.max(5, context.levels.waterY - 10); + fillDown(context, chunk, x, z, lavaStart, lavaEnd, States.LAVA.get()); + y = lavaEnd; + } else if (y < context.levels.waterLevel) { + fillDown(context, chunk, x, z, context.levels.waterY, y, States.WATER.get()); + } + fillDown(context, chunk, x, z, y, 0, States.STONE.get()); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/BedrockDecorator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/BedrockDecorator.java new file mode 100644 index 0000000..b5e03cf --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/BedrockDecorator.java @@ -0,0 +1,43 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import net.minecraft.world.chunk.IChunk; + +import java.util.Random; + +public class BedrockDecorator implements ColumnDecorator { + + private final Random random = new Random(); + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + fillDown(context, chunk, x, z, 1 + random.nextInt(4), -1, States.BEDROCK.get()); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/CoastDecorator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/CoastDecorator.java new file mode 100644 index 0000000..686d4b8 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/CoastDecorator.java @@ -0,0 +1,76 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.util.VariablePredicate; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.block.BlockState; +import net.minecraft.world.chunk.IChunk; + +public class CoastDecorator implements ColumnDecorator { + + private final Terrains terrains; + private final BlockState sand; + private final BlockState gravel; + private final VariablePredicate height; + + public CoastDecorator(TerraContext context) { + int min = context.levels.waterLevel - 5; + int max = context.levels.waterLevel + 16; + sand = States.SAND.get(); + gravel = States.GRAVEL.get(); + terrains = context.terrain; + height = VariablePredicate.height( + context.seed, + context.levels, + min, + max, + 75, + 1 + ); + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.tag != terrains.beach) { + return; + } + + if (!height.test(context.cell, x, z)) { + return; + } + + if (context.cell.temperature < 0.3F) { + setState(chunk, x, y, z, gravel, false); + } else { + setState(chunk, x, y, z, sand, false); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/ErosionDecorator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/ErosionDecorator.java new file mode 100644 index 0000000..cd59f52 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/ErosionDecorator.java @@ -0,0 +1,193 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.material.Materials; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.material.Material; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.surfacebuilders.ISurfaceBuilderConfig; + +public class ErosionDecorator implements ColumnDecorator { + + private static final int ROCK_VAR = 30; + private static final int ROCK_MIN = 140; + + private static final int DIRT_VAR = 40; + private static final int DIRT_MIN = 95; + + public static final float ROCK_STEEPNESS = 0.65F; + private static final float DIRT_STEEPNESS = 0.475F; + private static final float SCREE_STEEPNESS = 0.4F; + + public static final float HEIGHT_MODIFIER = 6F / 255F; + public static final float SLOPE_MODIFIER = 3F / 255F; + + private static final float SEDIMENT_MODIFIER = 256; + private static final float SEDIMENT_NOISE = 3F / 255F; + private static final float SCREE_VALUE = 0.55F; + + private final int seed1; + private final int seed2; + private final int seed3; + private final float minY; + private final Terrains terrain; + private final Materials materials; + + public ErosionDecorator(TerraContext context) { + this.terrain = context.terrain; + this.seed1 = context.seed.next(); + this.seed2 = context.seed.next(); + this.seed3 = context.seed.next(); + this.minY = context.levels.ground(4); + this.materials = context.materials; + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.value < minY || context.cell.tag == terrain.river || context.cell.tag == terrain.riverBanks) { + return; + } + + if (context.cell.tag == terrain.volcanoPipe) { + return; + } + + int topY = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, x, z); + if (topY - 1 > y) { + y = topY; + } + + ISurfaceBuilderConfig config = context.biome.getSurfaceBuilderConfig(); + BlockState top = config.getTop(); + BlockState middle = config.getUnder(); + + if (materials.isErodible(top.getBlock())) { + BlockState material = getMaterial(x, z, context, top, middle); + if (material != top) { + if (materials.isStone(material.getBlock())) { + erodeRock(context, chunk, x, y, z); + return; + } else { + fillDown(context, chunk, x, z, y, y - 4, material); + } + } + placeScree(chunk, context, x, y, z); + } + } + + protected void erodeRock(DecoratorContext context, IChunk chunk, int dx, int y, int dz) { + int depth = 32; + BlockState material = Blocks.GRAVEL.getDefaultState(); + // find the uppermost layer of rock & record it's depth + for (int dy = 3; dy < 32; dy++) { + context.pos.setY(y - dy); + BlockState state = chunk.getBlockState(context.pos); + if (materials.isStone(state.getBlock())) { + material = state; + depth = dy + 1; + break; + } + } + + // fill downwards to the first rock layer + for (int dy = 0; dy < depth; dy++) { + context.pos.setY(y - dy); + chunk.setBlockState(context.pos, material, false); + } + } + + protected void placeScree(IChunk chunk, DecoratorContext context, int x, int y, int z) { + float steepness = context.cell.steepness + context.climate.getRand().getValue(x, z, seed2) * SLOPE_MODIFIER; + if (steepness < SCREE_STEEPNESS) { + return; + } + + float sediment = context.cell.sediment * SEDIMENT_MODIFIER; + float noise = context.climate.getRand().getValue(x, z, seed3) * SEDIMENT_NOISE; + if (sediment + noise > SCREE_VALUE) { + fillDown(context, chunk, x, z, y, y - 2, States.GRAVEL.get()); + } + } + + public boolean erodeRock(float x, float z, float steepness, float height) { + return steepness > ROCK_STEEPNESS || height > ColumnDecorator.getNoise(x, z, seed1, ROCK_VAR, ROCK_MIN); + } + + public boolean erodeDirt(float x, float z, float steepness, float height) { + return steepness > DIRT_STEEPNESS && height > ColumnDecorator.getNoise(x, z, seed2, DIRT_VAR, DIRT_MIN); + } + + private BlockState getMaterial(float x, float z, DecoratorContext context, BlockState top, BlockState middle) { + float height = context.cell.value + context.climate.getRand().getValue(x, z, seed1) * HEIGHT_MODIFIER; + float steepness = context.cell.steepness + context.climate.getRand().getValue(x, z, seed2) * SLOPE_MODIFIER; + + if (steepness > ROCK_STEEPNESS || height > ColumnDecorator.getNoise(x, z, seed1, ROCK_VAR, ROCK_MIN)) { + return rock(middle); + } + + if (steepness > DIRT_STEEPNESS && height > ColumnDecorator.getNoise(x, z, seed2, DIRT_VAR, DIRT_MIN)) { + return ground(top); + } + + return top; + } + + private static BlockState rock(BlockState state) { + if (state.getMaterial() == Material.ROCK) { + return state; + } + return States.STONE.get(); + } + + private static BlockState ground(BlockState state) { + if (state.getMaterial() == Material.ORGANIC) { + return States.DIRT.get(); + } + if (state.getMaterial() == Material.ROCK) { + return States.GRAVEL.get(); + } + if (state.getMaterial() == Material.EARTH) { + return state; + } + if (state.getMaterial() == Material.SAND) { + if (state.getBlock() == Blocks.SAND) { + return States.SANDSTONE.get(); + } + if (state.getBlock() == Blocks.RED_SAND) { + return States.RED_SANDSTONE.get(); + } + } + return States.COARSE_DIRT.get(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/GeologyDecorator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/GeologyDecorator.java new file mode 100644 index 0000000..af2af9c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/GeologyDecorator.java @@ -0,0 +1,56 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.chunk.surface.ChunkSurfaceBuffer; +import com.terraforged.mod.material.geology.GeoManager; +import net.minecraft.world.chunk.IChunk; + +public class GeologyDecorator implements ColumnDecorator { + + private final GeoManager geology; + + public GeologyDecorator(GeoManager geology) { + this.geology = geology; + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int dy, int z) { + + } + + @Override + public void decorate(ChunkSurfaceBuffer buffer, DecoratorContext context, int x, int y, int z) { + int top = buffer.getSurfaceBottom(); + geology.getGeology(context.biome).getStrata(x, z).downwards(x, top, z, (py, state) -> { + context.pos.setPos(x, py, z); + buffer.getDelegate().setBlockState(context.pos, state, false); + return true; + }); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/RiverDecorator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/RiverDecorator.java new file mode 100644 index 0000000..62b5946 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/base/RiverDecorator.java @@ -0,0 +1,84 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.chunk.TerraContext; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.block.BlockState; +import net.minecraft.world.chunk.IChunk; + +public class RiverDecorator implements ColumnDecorator { + + private final Levels levels; + private final Terrain river; + private final Terrain riverBank; + + private final BlockState dirt; + private final BlockState sand; + private final BlockState gravel; + + private final Module noise1; + + public RiverDecorator(TerraContext context) { + Seed seed = context.seed.nextSeed(); + this.levels = context.levels; + this.river = context.terrain.river; + this.riverBank = context.terrain.riverBanks; + this.dirt = States.DIRT.get(); + this.sand = States.SAND.get(); + this.gravel = States.GRAVEL.get(); + this.noise1 = Source.perlin(seed.next(), 50, 1); + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.tag == river) { + chunk.setBlockState(context.pos.setPos(x, y, z), dirt, false); + return; + } + if (context.cell.tag == riverBank) { + float value = noise1.getValue(x, z) * 5; + if (y + value >= levels.waterY) { + if (context.cell.steepness > 0.5) { + chunk.setBlockState(context.pos.setPos(x, y, z), gravel, false); + } else if (context.cell.steepness < 0.3) { + chunk.setBlockState(context.pos.setPos(x, y, z), sand, false); + } else { + chunk.setBlockState(context.pos.setPos(x, y, z), dirt, false); + } + } else { + chunk.setBlockState(context.pos.setPos(x, y, z), dirt, false); + } + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/feature/LayerDecorator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/feature/LayerDecorator.java new file mode 100644 index 0000000..5467be8 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/feature/LayerDecorator.java @@ -0,0 +1,87 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.feature; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.api.material.layer.LayerMaterial; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.mod.material.MaterialHelper; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.IChunk; + +public class LayerDecorator implements ColumnDecorator { + + private final LayerManager layerManager; + + public LayerDecorator(LayerManager layerManager) { + this.layerManager = layerManager; + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + context.pos.setPos(x, y + 1, z); + + // if block is already a layer-type then simply set the layer property + BlockState state = chunk.getBlockState(context.pos); + LayerMaterial material = layerManager.getMaterial(state.getBlock()); + if (material != null) { + setLayer(chunk, context.pos, material, context.cell, context.levels, 0F); + return; + } + + if (MaterialHelper.isAir(state.getBlock())) { + return; + } + + // block is non-solid (grass/flower etc) + if (!state.getMaterial().blocksMovement()) { + // block below is solid + if (chunk.getBlockState(context.pos.setPos(x, y, z)).getMaterial().blocksMovement()) { + // block above is air + if (MaterialHelper.isAir(chunk.getBlockState(context.pos.setPos(x, y + 2, z)).getBlock())) { +// setLayer(chunk, pos.setPos(x, y + 1, z), context.cell, context.levels, 0.25F); + } + } + } + } + + private void setLayer(IChunk chunk, BlockPos pos, LayerMaterial material, Cell cell, Levels levels, float min) { + float height = cell.value * levels.worldHeight; + float depth = material.getDepth(height); + if (depth > min) { + int level = material.getLevel(depth); + BlockState layer = material.getState(level); + if (MaterialHelper.isAir(layer.getBlock())) { + return; + } + chunk.setBlockState(pos, layer, false); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/feature/SnowEroder.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/feature/SnowEroder.java new file mode 100644 index 0000000..2e3f125 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/feature/SnowEroder.java @@ -0,0 +1,93 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.feature; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.decorator.base.ErosionDecorator; +import me.dags.noise.source.Rand; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; + +import java.util.function.Predicate; + +public class SnowEroder extends ErosionDecorator { + + private static final float SNOW_ROCK_STEEPNESS = 0.45F; + private static final float SNOW_ROCK_HEIGHT = 95F / 255F; + + private final int seed1; + private final int seed2; + private final int seed3; + private final Rand rand; + + public SnowEroder(TerraContext context) { + super(context); + this.seed1 = context.seed.next(); + this.seed2 = context.seed.next(); + this.seed3 = context.seed.next(); + this.rand = context.factory.getHeightmap().getClimate().getRand(); + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + int surface = chunk.getTopBlockY(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, x, z); + if (y - surface > 0) { + if (y - surface > 4) { + return; + } + y = surface; + } + + if (context.biome.getTemperature(context.pos.setPos(x, y, z)) <= 0.25) { + float var = -ColumnDecorator.getNoise(x, z, seed1, 16, 0); + float hNoise = rand.getValue(x, z, seed2) * HEIGHT_MODIFIER; + float sNoise = rand.getValue(x, z, seed3) * SLOPE_MODIFIER; + float vModifier = context.cell.tag == context.terrains.volcano ? 0.15F : 0F; + float height = context.cell.value + var + hNoise + vModifier; + float steepness = context.cell.steepness + var + sNoise + vModifier; + if (snowErosion(x, z, steepness, height)) { + Predicate predicate = Heightmap.Type.MOTION_BLOCKING.getHeightLimitPredicate(); + for (int dy = 2; dy > 0; dy--) { + context.pos.setY(y + dy); + BlockState state = chunk.getBlockState(context.pos); + if (!predicate.test(state) || state.getBlock() == Blocks.SNOW) { + chunk.setBlockState(context.pos, Blocks.AIR.getDefaultState(), false); + } + } + } + } + } + + private boolean snowErosion(float x, float z, float steepness, float height) { + return steepness > ROCK_STEEPNESS + || (steepness > SNOW_ROCK_STEEPNESS && height > SNOW_ROCK_HEIGHT) + || super.erodeDirt(x, z, steepness, height); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/surface/DesertDunes.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/surface/DesertDunes.java new file mode 100644 index 0000000..7089486 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/surface/DesertDunes.java @@ -0,0 +1,98 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.surface; + +import com.terraforged.api.chunk.surface.Surface; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.api.material.layer.LayerMaterial; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.biome.provider.DesertBiomes; +import com.terraforged.mod.chunk.TerraContext; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.func.CellFunc; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; + +public class DesertDunes implements Surface { + + private final int maxHeight; + private final Levels levels; + private final Module module; + private final Terrains terrains; + private final DesertBiomes deserts; + private final BlockPos.Mutable pos = new BlockPos.Mutable(); + + public DesertDunes(TerraContext context, int maxHeight, DesertBiomes deserts) { + Module dunes = Source.cell(context.seed.next(), 80, CellFunc.DISTANCE) + .warp(context.seed.next(), 70, 1, 70); + this.terrains = context.terrain; + this.levels = context.levels; + this.maxHeight = maxHeight; + this.deserts = deserts; + this.module = dunes; + } + + @Override + public void buildSurface(int x, int z, int surface, SurfaceContext ctx) { + float value = module.getValue(x, z) * getMask(ctx.cell); + float baseHeight = ctx.cell.value * levels.worldHeight; + float duneHeight = baseHeight + value * maxHeight; + int duneBase = (int) baseHeight; + int duneTop = (int) duneHeight; + if (duneTop < levels.waterLevel || duneTop <= baseHeight) { + return; + } + + LayerMaterial material = deserts.getSandLayers(ctx.biome); + if (material == null) { + return; + } + + fill(x, z, duneBase, duneTop, ctx, ctx.chunk, material.getFull()); + + float depth = material.getDepth(duneHeight); + int levels = material.getLevel(depth); + BlockState top = material.getState(levels); + ctx.chunk.setBlockState(pos.setPos(x, duneTop, z), top, false); + } + + public static Surface create(TerraContext context, BiomeProvider provider) { + return create(context, provider.getModifierManager().getDesertBiomes()); + } + + public static Surface create(TerraContext context, DesertBiomes desertBiomes) { + return new DesertDunes(context, 25, desertBiomes); + } + + private static float getMask(Cell cell) { + return cell.biomeMask(0F, 0.75F) * cell.mask(0.4F, 0.5F, 0F, 0.8F); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/surface/FrozenOcean.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/surface/FrozenOcean.java new file mode 100644 index 0000000..f20c5fa --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/decorator/surface/FrozenOcean.java @@ -0,0 +1,115 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.surface; + +import com.terraforged.api.chunk.surface.Surface; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.mod.chunk.TerraContext; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; + +public class FrozenOcean implements Surface { + + private final Module up; + private final Module down; + private final Module fadeUp; + private final Module bergTop; + private final Module seaFloor; + private final Levels levels; + + public FrozenOcean(TerraContext context, int height, int depth) { + Levels levels = context.levels; + Module shape = Source.perlin(context.seed.next(), 65, 3) + .warp(context.seed.next(), 15, 1, 10) + .cache(); + Module mask = shape.threshold(0.6).cache(); + Module fadeDown = shape.clamp(0.6, 0.725).map(0, 1); + + this.levels = levels; + + this.fadeUp = shape.clamp(0.6, 0.65).map(0, 1); + + this.up = Source.ridge(context.seed.next(), 50, 3) + .mult(mask) + .mult(fadeUp) + .scale(levels.scale(height)); + + this.down = Source.ridge(context.seed.next(), 60, 3) + .mult(mask) + .mult(fadeDown) + .scale(levels.scale(depth)); + + this.bergTop = Source.perlin(context.seed.next(), 25, 2) + .scale(levels.scale(3)) + .bias(levels.scale(2)); + + this.seaFloor = Source.perlin(context.seed.next(), 50, 1) + .scale(levels.scale(3)) + .bias(levels.scale(1)); + } + + @Override + public void buildSurface(int x, int z, int height, SurfaceContext ctx) { + int center = levels.waterLevel - 5; + int top = center + (int) (up.getValue(x, z) * levels.worldHeight); + int topDepth = (int) (bergTop.getValue(x, z) * levels.worldHeight); + int bottom = center - (int) (down.getValue(x, z) * levels.worldHeight); + + // set iceberg materials + BlockPos.Mutable pos = new BlockPos.Mutable(x, height, z); + for (int dy = top; dy > bottom; dy--) { + pos.setY(dy); + BlockState state = getMaterial(x, dy, z, top, topDepth); + ctx.chunk.setBlockState(pos, state, false); + } + + // set ocean floor to gravel + int floorBed = (int) (ctx.cell.value * ctx.levels.worldHeight); + int floorDepth = (int) (seaFloor.getValue(x, z) * levels.worldHeight); + for (int dy = 0; dy < floorDepth; dy++) { + pos.setY(floorBed - dy); + ctx.chunk.setBlockState(pos, SurfaceBuilder.GRAVEL, false); + } + } + + private BlockState getMaterial(int x, int y, int z, int top, int topDepth) { + if (y >= top - topDepth && fadeUp.getValue(x, z) == 1) { + return States.SNOW_BLOCK.get(); + } + return States.PACKED_ICE.get(); + } + + private static float getMask(Cell cell) { + return NoiseUtil.map(cell.biomeTypeMask * cell.riverMask, 0F, 0.3F, 0.3F); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/Matchers.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/Matchers.java new file mode 100644 index 0000000..bcd94e8 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/Matchers.java @@ -0,0 +1,39 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature; + +import com.terraforged.feature.matcher.feature.FeatureMatcher; + +public class Matchers { + + public static final FeatureMatcher STONE_BLOBS = FeatureMatcher.builder() + .or("minecraft:ore").and("minecraft:dirt") + .or("minecraft:ore").and("minecraft:gravel") + .or("minecraft:ore").and("minecraft:granite") + .or("minecraft:ore").and("minecraft:diorite") + .or("minecraft:ore").and("minecraft:andesite") + .build(); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/TerrainHelper.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/TerrainHelper.java new file mode 100644 index 0000000..3b9c0fe --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/TerrainHelper.java @@ -0,0 +1,178 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature; + +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectList; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.structure.PoolStructurePiece; +import net.minecraft.structure.StructurePiece; +import net.minecraft.structure.StructureStart; +import net.minecraft.structure.pool.StructurePool; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.BlockBox; +import net.minecraft.world.Heightmap; +import net.minecraft.world.IWorld; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.StructureFeature; + +public class TerrainHelper { + + private final Module noise; + private final float radius; + + public TerrainHelper(int seed, float radius) { + this.noise = Source.perlin(++seed, 8, 1).alpha(0.75); + this.radius = radius; + } + + public void flatten(IWorld world, Chunk chunk, int chunkStartX, int chunkStartZ) { + ObjectList pieces = new ObjectArrayList<>(10); + collectPieces(world, chunk, pieces); + buildBases(chunk, pieces, chunkStartX, chunkStartZ); + } + + // see NoiseChunkGenerator + private void collectPieces(IWorld world, Chunk chunk, ObjectList pieces) { + ChunkPos pos = chunk.getPos(); + for (StructureFeature structure : Feature.JIGSAW_STRUCTURES) { + String name = structure.getName(); + LongIterator structureIds = chunk.getStructureReferences(name).iterator(); + + while (structureIds.hasNext()) { + long id = structureIds.nextLong(); + ChunkPos structurePos = new ChunkPos(id); + Chunk neighbourChunk = world.getChunk(structurePos.getCenterBlockPos()); + StructureStart structurestart = neighbourChunk.getStructureStart(name); + if (structurestart != null && structurestart.isInExistingChunk()) { + for (StructurePiece structurepiece : structurestart.getChildren()) { + if (structurepiece.method_16654(pos, 12) && structurepiece instanceof PoolStructurePiece) { + PoolStructurePiece piece = (PoolStructurePiece) structurepiece; + StructurePool.Projection placement = piece.getPoolElement().getProjection(); + if (placement == StructurePool.Projection.RIGID) { + pieces.add(piece); + } + } + } + } + } + } + } + + // try to fill in type air beneath village pieces with the biomes default filler block + private void buildBases(Chunk chunk, ObjectList pieces, int chunkStartX, int chunkStartZ) { + BlockPos.Mutable pos = new BlockPos.Mutable(); + BlockBox chunkBounds = new BlockBox(chunkStartX, chunkStartZ, chunkStartX + 15, chunkStartZ + 15); + for (PoolStructurePiece piece : pieces) { + BlockBox pieceBounds = piece.getBoundingBox(); + + int length = Math.min(pieceBounds.maxX - pieceBounds.minX, pieceBounds.maxZ - pieceBounds.minZ); + int borderRadius = Math.max(5, NoiseUtil.round(length * radius)); + BlockBox expanded = expand(pieceBounds, borderRadius); + + if (!expanded.intersects(chunkBounds)) { + continue; + } + + // intersecting area between the generator bounds and the village piece bounds + int startX = Math.max(chunkStartX, expanded.minX); + int startZ = Math.max(chunkStartZ, expanded.minZ); + int endX = Math.min(chunkStartX + 15, expanded.maxX); + int endZ = Math.min(chunkStartZ + 15, expanded.maxZ); + + // iterate the intersecting area + for (int z = startZ; z <= endZ; z++) { + for (int x = startX; x <= endX; x++) { + // local generator coords + int dx = x & 15; + int dz = z & 15; + + // the paste position of the village piece + BlockPos position = piece.getPos(); + + int offset = piece.getGroundLevelDelta(); + int level = position.getY() + (offset - 1); + int surface = chunk.sampleHeightmap(Heightmap.Type.OCEAN_FLOOR_WG, dx, dz) - 1; + int height = level - surface; + if (height <= 0) { + continue; + } + + float radius2 = Math.max(1, borderRadius * borderRadius * noise.getValue(x, z)); + float alpha = getAlpha(pieceBounds, radius2, x, z); + if (alpha == 0F) { + continue; + } + + if (alpha < 1F) { + alpha = alpha * alpha; + height = NoiseUtil.round(alpha * height); + } + + BlockState state = Blocks.STONE.getDefaultState(); + for (int dy = surface + height; dy >= surface; dy--) { + pos.set(dx, dy, dz); + if (chunk.getBlockState(pos).isOpaque()) { + break; + } + chunk.setBlockState(pos.set(dx, dy, dz), state, false); + } + } + } + } + } + + private static BlockBox expand(BlockBox box, int radius) { + return new BlockBox( + box.minX - radius, + box.minY, + box.minZ - radius, + box.maxX + radius, + box.maxY, + box.maxZ + radius + ); + } + + private static float getAlpha(BlockBox box, float radius2, int x, int y) { + int dx = x < box.minX ? box.minX - x : x > box.maxX ? x - box.maxX : 0; + int dy = y < box.minZ ? box.minZ - y : y > box.maxZ ? y - box.maxZ : 0; + int d2 = dx * dx + dy * dy; + if (d2 == 0) { + return 1F; + } + if (d2 > radius2) { + return 0F; + } + return 1 - (d2 / radius2); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/predicate/TreeLine.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/predicate/TreeLine.java new file mode 100644 index 0000000..fd9f6d6 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/predicate/TreeLine.java @@ -0,0 +1,57 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.predicate; + +import com.terraforged.core.world.climate.Climate; +import com.terraforged.feature.predicate.FeaturePredicate; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; + +public class TreeLine implements FeaturePredicate { + + private final int worldHeight; + private final Climate climate; + + public TreeLine(TerraContext context) { + this.worldHeight = context.levels.worldHeight; + this.climate = context.heightmap.getClimate(); + } + + @Override + public boolean test(IChunk chunk, Biome biome) { + int x = chunk.getPos().getXStart() + 8; + int z = chunk.getPos().getZStart() + 8; + int treeline = getTreeline(x, z); + int y = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, 8, 8); + return y < treeline; + } + + private int getTreeline(int x, int z) { + return (int) (climate.getTreeLine(x, z) * worldHeight); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingConfig.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingConfig.java new file mode 100644 index 0000000..70b4333 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingConfig.java @@ -0,0 +1,122 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.google.gson.reflect.TypeToken; +import com.mojang.datafixers.types.DynamicOps; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class SaplingConfig { + + private static final TypeToken> TOKEN = new TypeToken>() { + }; + + private final Map normal; + private final Map giant; + + public SaplingConfig() { + normal = new HashMap<>(); + giant = new HashMap<>(); + } + + public SaplingConfig(T config, DynamicOps ops) { + this.normal = getSection("normal", config, ops); + this.giant = getSection("giant", config, ops); + } + + public SaplingConfig addNormal(ResourceLocation name, int weight) { + normal.put(name, weight); + return this; + } + + public SaplingConfig addNormal(String name, int weight) { + normal.put(new ResourceLocation(name), weight); + return this; + } + + public SaplingConfig addGiant(ResourceLocation name, int weight) { + giant.put(name, weight); + return this; + } + + public SaplingConfig addGiant(String name, int weight) { + giant.put(new ResourceLocation(name), weight); + return this; + } + + private Map getSection(String key, T config, DynamicOps ops) { + return ops.get(config, key).flatMap(ops::getMapValues).map(map -> { + Map backing = new HashMap<>(); + + for (Map.Entry entry : map.entrySet()) { + String name = ops.getStringValue(entry.getKey()).orElse(""); + int weight = ops.getNumberValue(entry.getValue()).orElse(0).intValue(); + if (name.isEmpty() || weight == 0) { + continue; + } + + ResourceLocation loc = new ResourceLocation(name); + backing.put(loc, weight); + } + + return backing; + }).orElse(Collections.emptyMap()); + } + + public List> getNormal() { + return build(normal); + } + + public List> getGiant() { + return build(giant); + } + + @SuppressWarnings("unchecked") + public static List> build(Map map) { + List> list = new LinkedList<>(); + for (Map.Entry entry : map.entrySet()) { + Feature feature = ForgeRegistries.FEATURES.getValue(entry.getKey()); + if (feature == null) { + continue; + } + + if (TOKEN.getRawType().isAssignableFrom(feature.getClass())) { + Feature noConfFeature = (Feature) feature; + list.add(noConfFeature); + } + } + return list; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingFeature.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingFeature.java new file mode 100644 index 0000000..b8204ff --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingFeature.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class SaplingFeature { + + private final List> normal; + private final List> giant; + + public SaplingFeature(SaplingConfig config) { + this.normal = new ArrayList<>(config.getNormal()); + this.giant = new ArrayList<>(config.getGiant()); + } + + public Feature nextNormal(Random random) { + if (normal.isEmpty()) { + return null; + } + return normal.get(random.nextInt(normal.size())); + } + + public Feature nextGiant(Random random) { + if (giant.isEmpty()) { + return null; + } + return giant.get(random.nextInt(giant.size())); + } + + public int getNormalCount() { + return normal.size(); + } + + public int getGiantCount() { + return giant.size(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingListener.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingListener.java new file mode 100644 index 0000000..18e2e24 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingListener.java @@ -0,0 +1,141 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.terraforged.mod.TerraWorld; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.SaplingBlock; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; +import net.minecraft.world.WorldType; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraftforge.event.world.SaplingGrowTreeEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) +public class SaplingListener { + + private static final BlockPos[] NONE = {BlockPos.ZERO}; + + private static final Vec3i[][] DIRECTIONS = { + {new Vec3i(0, 0, 1), new Vec3i(1, 0, 1), new Vec3i(1, 0, 0)}, + {new Vec3i(1, 0, 0), new Vec3i(1, 0, -1), new Vec3i(0, 0, -1)}, + {new Vec3i(0, 0, -1), new Vec3i(-1, 0, -1), new Vec3i(-1, 0, 0)}, + {new Vec3i(-1, 0, 0), new Vec3i(-1, 0, 1), new Vec3i(0, 0, 1)}, + }; + + @SubscribeEvent + public static void onTreeGrow(SaplingGrowTreeEvent event) { + if (!TerraWorld.isTerraWorld(event.getWorld())) { + return; + } + + IWorld world = event.getWorld(); + BlockPos pos = event.getPos(); + Block block = world.getBlockState(pos).getBlock(); + if (block instanceof SaplingBlock) { + // get the sapling feature for the given block type + SaplingFeature tree = SaplingManager.getSapling(block.getRegistryName()); + + // tree is null if the sapling type hasn't been configured + if (tree == null) { + return; + } + + // check for a 2x2 arrangement of sapling blocks around the position + Vec3i[] directions = getNeighbourDirections(world, block, pos); + + // length is 1 if a full 2x2 arrangement could not be found + if (directions.length == 1) { + placeNormal(tree, event, directions); + } else { + placeGiant(tree, event, block, directions); + } + } + } + + private static void placeNormal(SaplingFeature tree, SaplingGrowTreeEvent event, Vec3i[] directions) { + SaplingPlacer.placeTree(tree.nextNormal(event.getRand()), event, directions); + } + + private static void placeGiant(SaplingFeature tree, SaplingGrowTreeEvent event, Block type, Vec3i[] directions) { + Feature feature = tree.nextGiant(event.getRand()); + + // if no giant tree exists for this sapling type try and place a normal one instead + if (feature == null) { + placeNormal(tree, event, directions); + return; + } + + // do not continue if unable to place the tree + if (!SaplingPlacer.placeTree(feature, event, directions)) { + return; + } + + // iterate through the contributing saplings and remove any that were not destroyed during tree creation + BlockPos pos = event.getPos(); + for (Vec3i dir : directions) { + BlockPos blockPos = pos.add(dir); + BlockState state = event.getWorld().getBlockState(blockPos); + if (state.getBlock() == type) { + event.getWorld().removeBlock(blockPos, false); + } + } + } + + private static Vec3i[] getNeighbourDirections(IWorld world, Block block, BlockPos pos) { + for (Vec3i[] dirs : DIRECTIONS) { + boolean match = true; + for (Vec3i dir : dirs) { + BlockState state = world.getBlockState(pos.add(dir)); + if (state.getBlock() != block) { + match = false; + break; + } + } + if (match) { + return dirs; + } + } + return NONE; + } + + private static boolean isTerraWorld(IWorld world) { + if (world instanceof World) { + return isTerraWorld(((World) world).getWorldType()); + } + return false; + } + + private static boolean isTerraWorld(WorldType type) { + return type.getName().equals("terraforged"); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingManager.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingManager.java new file mode 100644 index 0000000..9335703 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingManager.java @@ -0,0 +1,90 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.mojang.datafixers.types.DynamicOps; +import com.terraforged.mod.Log; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.util.ResourceLocation; + +import java.util.HashMap; +import java.util.Map; + +public class SaplingManager { + + private static final Map saplings = new HashMap<>(); + + public static SaplingFeature getSapling(ResourceLocation name) { + return saplings.get(name); + } + + public static void register(Block block, SaplingConfig config) { + register(block.getRegistryName(), config); + } + + public static void register(ResourceLocation location, T config, DynamicOps ops) { + register(location, new SaplingConfig(config, ops)); + } + + public static void register(ResourceLocation location, SaplingConfig config) { + saplings.put(location, new SaplingFeature(config)); + } + + public static void init() { + register(Blocks.OAK_SAPLING, new SaplingConfig() + .addNormal("terraforged:oak_small", 4) + .addNormal("terraforged:oak_forest", 3) + .addNormal("terraforged:oak_large", 2) + .addGiant("terraforged:oak_huge", 1)); + + register(Blocks.BIRCH_SAPLING, new SaplingConfig() + .addNormal("terraforged:birch_small", 4) + .addNormal("terraforged:birch_forest", 3) + .addNormal("terraforged:birch_large", 1)); + + register(Blocks.JUNGLE_SAPLING, new SaplingConfig() + .addNormal("terraforged:jungle_small", 4) + .addGiant("terraforged:jungle_large", 1)); + + register( + Blocks.SPRUCE_SAPLING, + new SaplingConfig() + .addNormal("terraforged:spruce_small", 4) + .addNormal("terraforged:spruce_large", 1) + .addGiant("terraforged:redwood_huge", 1)); + + register(Blocks.DARK_OAK_SAPLING, new SaplingConfig() + .addNormal("terraforged:dark_oak_small", 4) + .addNormal("terraforged:dark_oak_large", 1)); + + register(Blocks.ACACIA_SAPLING, new SaplingConfig() + .addNormal("terraforged:acacia_small", 2) + .addNormal("terraforged:acacia_large", 1)); + + Log.info("Registered saplings"); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingPlacer.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingPlacer.java new file mode 100644 index 0000000..5c335ab --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/SaplingPlacer.java @@ -0,0 +1,149 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.terraforged.feature.template.decorator.DecoratedFeature; +import com.terraforged.feature.template.decorator.DecoratorWorld; +import com.terraforged.feature.template.feature.TemplateFeature; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.IWorld; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraft.world.server.ServerChunkProvider; +import net.minecraftforge.event.world.SaplingGrowTreeEvent; +import net.minecraftforge.eventbus.api.Event; + +public class SaplingPlacer { + + public static boolean placeTree(Feature feature, SaplingGrowTreeEvent event, Vec3i[] dirs) { + if (feature == null) { + return false; + } + + event.setResult(Event.Result.DENY); + + if (feature instanceof DecoratedFeature) { + return placeDecorated((DecoratedFeature) feature, event, dirs); + } + + return placeNormal(feature, event, dirs); + } + + private static boolean placeDecorated(DecoratedFeature feature, SaplingGrowTreeEvent event, Vec3i[] dirs) { + if (!(event.getWorld().getChunkProvider() instanceof ServerChunkProvider)) { + return false; + } + + TreeGrowBuffer buffer = new TreeGrowBuffer(event.getWorld(), event.getPos()); + W world = feature.wrap(buffer); + + ChunkGenerator generator = ((ServerChunkProvider) event.getWorld().getChunkProvider()).getChunkGenerator(); + feature.placeFeature(world, generator, event.getRand(), event.getPos(), NoFeatureConfig.NO_FEATURE_CONFIG); + + // check that the tree can grow here + if (overheadIsSolid(event.getWorld(), event.getPos(), buffer.getTopY())) { + return false; + } + + BlockPos translation = buffer.getBaseMin().add(getMin(dirs)); + + // apply buffer to world with translation + applyBuffer(buffer, event.getWorld(), translation); + + // translate the decoration positions and apply in the world + world.setDelegate(event.getWorld()); + world.translate(translation); + feature.decorate(world, event.getRand()); + return true; + } + + private static boolean placeNormal(Feature feature, SaplingGrowTreeEvent event, Vec3i[] dirs) { + // apply the feature to a buffer + TreeGrowBuffer buffer = new TreeGrowBuffer(event.getWorld(), event.getPos()); + buffer.placeFeature(feature, event.getPos(), event.getRand()); + + // check that the tree can grow here + if (overheadIsSolid(event.getWorld(), event.getPos(), buffer.getTopY())) { + return false; + } + + // get the min position in the 2x2 grid + BlockPos translation = buffer.getBaseMin().add(getMin(dirs)); + + // copy the feature from the buffer to the world while translating each block + applyBuffer(buffer, event.getWorld(), translation); + return true; + } + + private static void applyBuffer(TreeGrowBuffer buffer, IWorld world, BlockPos translation) { + try (BlockPos.PooledMutable pos = BlockPos.PooledMutable.retain()) { + for (TemplateFeature.BlockInfo block : buffer.getChanges()) { + int x = block.getPos().getX() + translation.getX(); + int y = block.getPos().getY(); + int z = block.getPos().getZ() + translation.getZ(); + + pos.setPos(x, y, z); + + BlockState current = world.getBlockState(pos); + if (current.isSolid()) { + continue; + } + + world.setBlockState(pos, block.getState(), 2); + } + } + } + + private static boolean overheadIsSolid(IWorld world, BlockPos pos, int topY) { + try (BlockPos.PooledMutable blockPos = BlockPos.PooledMutable.retain()) { + for (int y = pos.getY(); y <= topY; y++) { + blockPos.setPos(pos.getX(), y, pos.getZ()); + BlockState state = world.getBlockState(pos); + if (state.isSolid()) { + return true; + } + } + return false; + } + } + + private static Vec3i getMin(Vec3i[] dirs) { + Vec3i min = Vec3i.NULL_VECTOR; + for (Vec3i dir : dirs) { + if (dir.getX() < min.getX() && dir.getZ() <= min.getZ()) { + min = dir; + continue; + } + if (dir.getZ() < min.getZ() && dir.getX() <= min.getX()) { + min = dir; + } + } + return min; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/TreeGrowBuffer.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/TreeGrowBuffer.java new file mode 100644 index 0000000..27a5371 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/feature/tree/TreeGrowBuffer.java @@ -0,0 +1,126 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.terraforged.feature.template.feature.TemplateFeature; +import com.terraforged.feature.util.WorldDelegate; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.IWorld; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.IFeatureConfig; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraft.world.server.ServerChunkProvider; + +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + +public class TreeGrowBuffer extends WorldDelegate { + + private int topY = 0; + private final BlockPos pos; + private final MutableVec3i baseMin = new MutableVec3i(0); + private final MutableVec3i baseMax = new MutableVec3i(0); + private final List changes = new LinkedList<>(); + + public TreeGrowBuffer(IWorld delegate, BlockPos pos) { + super(delegate); + this.pos = pos; + } + + public int getTopY() { + return topY; + } + + public BlockPos getBaseMin() { + return new BlockPos(-baseMin.x, baseMin.y, -baseMin.z); + } + + public BlockPos getBaseMax() { + return new BlockPos(baseMax.x, baseMax.y, baseMax.z); + } + + public Iterable getChanges() { + return changes; + } + + @Override + public boolean setBlockState(BlockPos pos, BlockState state, int i) { + if (pos.getY() < this.pos.getY()) { + return false; + } + if (state.isSolid()) { + recordPos(pos); + } + changes.add(new TemplateFeature.BlockInfo(pos, state)); + return true; + } + + public void placeFeature(Feature feature, BlockPos pos, Random random) { + placeFeature(feature, pos, random, NoFeatureConfig.NO_FEATURE_CONFIG); + } + + public void placeFeature(Feature feature, BlockPos pos, Random random, T config) { + if (getChunkProvider() instanceof ServerChunkProvider) { + ServerChunkProvider chunkProvider = (ServerChunkProvider) getChunkProvider(); + feature.place(this, chunkProvider.getChunkGenerator(), random, pos, config); + } + } + + private void recordPos(BlockPos pos) { + if (pos.getY() > topY) { + topY = pos.getY(); + baseMax.max(pos.subtract(this.pos)); + } else if (pos.getY() == this.pos.getY()) { + baseMin.min(pos.subtract(this.pos)); + } + } + + private static class MutableVec3i { + + private int x, y, z; + + private MutableVec3i(int start) { + x = start; + y = start; + z = start; + } + + private void min(Vec3i vec) { + x = Math.min(x, vec.getX()); + y = Math.min(y, vec.getY()); + z = Math.min(z, vec.getZ()); + } + + private void max(Vec3i vec) { + x = Math.max(x, vec.getX()); + y = Math.max(y, vec.getY()); + z = Math.max(z, vec.getZ()); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/OverlayRenderer.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/OverlayRenderer.java new file mode 100644 index 0000000..2cc9fde --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/OverlayRenderer.java @@ -0,0 +1,33 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import net.minecraft.client.gui.screen.Screen; + +public interface OverlayRenderer { + + void renderOverlays(Screen screen, int mouseX, int mouseY); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/OverlayScreen.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/OverlayScreen.java new file mode 100644 index 0000000..4514719 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/OverlayScreen.java @@ -0,0 +1,87 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import com.terraforged.mod.gui.element.CheckBox; +import com.terraforged.mod.gui.element.Element; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.util.text.TranslationTextComponent; + +public class OverlayScreen extends Screen implements OverlayRenderer { + + public boolean showTooltips = false; + + public OverlayScreen() { + super(new TranslationTextComponent("")); + super.minecraft = Minecraft.getInstance(); + super.font = minecraft.fontRenderer; + } + + @Override + public T addButton(T buttonIn) { + return super.addButton(buttonIn); + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.render(mouseX, mouseY, partialTicks); + if (showTooltips) { + renderOverlays(this, mouseX, mouseY); + } + } + + @Override + public void renderOverlays(Screen screen, int mouseX, int mouseY) { + for (Widget button : buttons) { + if (button.isMouseOver(mouseX, mouseY)) { + if (button instanceof Element) { + screen.renderTooltip(((Element) button).getTooltip(), mouseX, mouseY); + return; + } + } + } + } + + @Override + protected void init() { + addButton(new CheckBox("Tooltips", showTooltips) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + showTooltips = isChecked(); + } + + @Override + public void render(int mouseX, int mouseY, float partial) { + this.x = OverlayScreen.this.width - width - 12; + this.y = 8; + super.render(mouseX, mouseY, partial); + } + }); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/ScrollPane.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/ScrollPane.java new file mode 100644 index 0000000..211044b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/ScrollPane.java @@ -0,0 +1,123 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import com.terraforged.mod.gui.element.Element; +import com.terraforged.mod.gui.preview.Preview; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.IGuiEventListener; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.client.gui.widget.list.AbstractOptionList; + +import java.util.Collections; +import java.util.List; + +public class ScrollPane extends AbstractOptionList implements OverlayRenderer { + + private boolean hovered = false; + + public ScrollPane(int slotHeightIn) { + super(Minecraft.getInstance(), 0, 0, 0, 0, slotHeightIn); + } + + public void addButton(Widget button) { + super.addEntry(new Entry(button)); + } + + @Override + public void renderOverlays(Screen screen, int x, int y) { + for (Entry entry : this.children()) { + if (entry.isMouseOver(x, y) && entry.option.isMouseOver(x, y)) { + Widget button = entry.option; + if (button instanceof Element) { + screen.renderTooltip(((Element) button).getTooltip(), x, y); + return; + } + } + } + } + + @Override + public int getRowWidth() { + return width - 20; + } + + @Override + public void render(int x, int y, float partialTicks) { + super.render(x, y, partialTicks); + hovered = isMouseOver(x, y); + } + + @Override + protected int getScrollbarPosition() { + return getRight(); + } + + @Override + public boolean mouseScrolled(double x, double y, double direction) { + return hovered && super.mouseScrolled(x, y, direction); + } + + public class Entry extends AbstractOptionList.Entry { + + public final Widget option; + + public Entry(Widget option) { + this.option = option; + } + + @Override + public List children() { + return Collections.singletonList(option); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + return option.mouseClicked(x, y, button); + } + + @Override + public boolean mouseReleased(double x, double y, int button) { + return option.mouseReleased(x, y, button); + } + + @Override + public void render(int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean wut, float partialTicks) { + int optionWidth = Math.min(396, width); + int padding = (width - optionWidth) / 2; + option.x = left + padding; + option.y = top; + option.visible = true; + option.setWidth(optionWidth); + option.setHeight(height); + if (option instanceof Preview) { + option.setHeight(option.getWidth()); + } + option.render(mouseX, mouseY, partialTicks); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/SettingsScreen.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/SettingsScreen.java new file mode 100644 index 0000000..d6be899 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/SettingsScreen.java @@ -0,0 +1,257 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.element.TerraLabel; +import com.terraforged.mod.gui.page.FeaturePage; +import com.terraforged.mod.gui.page.FilterPage; +import com.terraforged.mod.gui.page.GeneratorPage; +import com.terraforged.mod.gui.page.Page; +import com.terraforged.mod.gui.page.RiverPage; +import com.terraforged.mod.gui.page.StructurePage; +import com.terraforged.mod.gui.page.TerrainPage; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.settings.SettingsHelper; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.CreateWorldScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.button.Button; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.Util; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; + +public class SettingsScreen extends OverlayScreen { + + private static final Button.IPressable NO_ACTION = b -> {}; + + private final Page[] pages; + private final CreateWorldScreen parent; + private final PreviewPage preview = new PreviewPage(); + private final TerraSettings settings = new TerraSettings(); + + private int pageIndex = 0; + + public SettingsScreen(CreateWorldScreen parent) { + NBTHelper.deserialize(parent.chunkProviderSettingsJson, settings); + this.parent = parent; + this.pages = new Page[]{ + new GeneratorPage(settings, preview), + new TerrainPage(settings, preview), + new RiverPage(settings, preview), + new FilterPage(settings, preview), + new FeaturePage(settings), + new StructurePage(settings) + }; + } + + @Override + protected void init() { + super.buttons.clear(); + super.children.clear(); + + int buttonsCenter = width / 2; + int buttonWidth = 50; + int buttonHeight = 20; + int buttonPad = 2; + int buttonsRow = height - 25; + + if (pageIndex < pages.length) { + Page page = pages[pageIndex]; + TerraLabel title = new TerraLabel(page.getTitle()); + title.visible = true; + title.x = 16; + title.y = 15; + buttons.add(title); + + try { + page.initPage(10, 30, this); + preview.initPage(10, 30, this); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + // -52 + addButton(new Button(buttonsCenter - buttonWidth - buttonPad, buttonsRow, buttonWidth, buttonHeight, "Cancel" + , b -> onClose())); + + // +2 + addButton(new Button(buttonsCenter + buttonPad, buttonsRow, buttonWidth, buttonHeight, "Done", b -> { + for (Page page : pages) { + page.save(); + } + parent.chunkProviderSettingsJson = NBTHelper.serializeCompact(settings); + onClose(); + })); + + + // -106 + addButton(new Button(buttonsCenter - (buttonWidth * 2 + (buttonPad * 3)), buttonsRow, buttonWidth, + buttonHeight, "<<", NO_ACTION) { + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.active = hasPrevious(); + super.render(mouseX, mouseY, partialTicks); + } + + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + if (hasPrevious()) { + pageIndex--; + init(); + } + } + + private boolean hasPrevious() { + return pageIndex > 0; + } + }); + + // +56 + addButton(new Button(buttonsCenter + buttonWidth + (buttonPad * 3), buttonsRow, buttonWidth, buttonHeight, + ">>", NO_ACTION) { + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.active = hasNext(); + super.render(mouseX, mouseY, partialTicks); + } + + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + if (hasNext()) { + pageIndex++; + init(); + } + } + + private boolean hasNext() { + return pageIndex + 1 < pages.length; + } + }); + + addButton(new Button(width - buttonWidth - 15, buttonsRow, buttonWidth, buttonHeight, "Export", NO_ACTION) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + export(settings); + } + }); + + super.init(); + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.renderBackground(); + pages[pageIndex].visit(pane -> pane.render(mouseX, mouseY, partialTicks)); + preview.visit(pane -> pane.render(mouseX, mouseY, partialTicks)); + super.render(mouseX, mouseY, partialTicks); + } + + @Override + public void renderOverlays(Screen screen, int mouseX, int mouseY) { + super.renderOverlays(screen, mouseX, mouseY); + pages[pageIndex].visit(pane -> pane.renderOverlays(screen, mouseX, mouseY)); + preview.visit(pane -> pane.renderOverlays(screen, mouseX, mouseY)); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + boolean a = pages[pageIndex].action(pane -> pane.mouseClicked(x, y, button)); + boolean b = preview.action(pane -> pane.mouseClicked(x, y, button)); + boolean c = super.mouseClicked(x, y, button); + return a || b || c; + } + + @Override + public boolean mouseReleased(double x, double y, int button) { + boolean a = pages[pageIndex].action(pane -> pane.mouseReleased(x, y, button)); + boolean b = preview.action(pane -> pane.mouseReleased(x, y, button)); + boolean c = super.mouseReleased(x, y, button); + return a || b || c; + } + + @Override + public boolean mouseDragged(double x, double y, int button, double dx, double dy) { + boolean a = pages[pageIndex].action(pane -> pane.mouseDragged(x, y, button, dx, dy)); + boolean b = preview.action(pane -> pane.mouseDragged(x, y, button, dx, dy)); + boolean c = super.mouseDragged(x, y, button, dx, dy); + return a || b || c; + } + + @Override + public boolean mouseScrolled(double x, double y, double direction) { + boolean a = pages[pageIndex].action(pane -> pane.mouseScrolled(x, y, direction)); + boolean b = preview.action(pane -> pane.mouseScrolled(x, y, direction)); + boolean c = super.mouseScrolled(x, y, direction); + return a || b || c; + } + + @Override + public boolean keyPressed(int i, int j, int k) { + boolean a = pages[pageIndex].action(pane -> pane.keyPressed(i, j, k)); + boolean b = preview.action(pane -> pane.keyPressed(i, j, k)); + boolean c = super.keyPressed(i, j, k); + return a || b || c; + } + + @Override + public void onClose() { + for (Page page : pages) { + page.close(); + } + preview.close(); + Minecraft.getInstance().displayGuiScreen(parent); + } + + private void export(Settings settings) { + for (Page page : pages) { + page.save(); + } + CompoundNBT tag = NBTHelper.serializeCompact(settings); + JsonElement json = NBTHelper.toJson(tag); + File config = new File(Minecraft.getInstance().gameDir, "config"); + File file = new File(config, SettingsHelper.SETTINGS_FILE_NAME); + try (Writer writer = new BufferedWriter(new FileWriter(file))) { + new GsonBuilder().setPrettyPrinting().create().toJson(json, writer); + Util.getOSType().openURI(file.getParentFile().toURI()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/CheckBox.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/CheckBox.java new file mode 100644 index 0000000..5a6cfeb --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/CheckBox.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +public class CheckBox extends TerraButton implements Element { + + private boolean checked = false; + + public CheckBox(String displayString, boolean isChecked) { + super(displayString); + this.visible = true; + this.width = 70; + this.height = 16; + checked = isChecked; + } + + public boolean isChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + } + + @Override + public void onClick(double x, double y) { + super.onClick(x, y); + checked = !checked; + } + + @Override + public void render(int x, int y, float ticks) { + active = !checked; + super.render(x, y, ticks); + active = true; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/Element.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/Element.java new file mode 100644 index 0000000..2596595 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/Element.java @@ -0,0 +1,59 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.INBT; +import net.minecraft.nbt.ListNBT; +import net.minecraftforge.common.util.Constants; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +public interface Element { + + AtomicInteger ID_COUNTER = new AtomicInteger(0); + + default List getTooltip() { + return Collections.emptyList(); + } + + static int nextID() { + return ID_COUNTER.getAndAdd(1); + } + + static List readTooltip(CompoundNBT value) { + if (value.contains("#comment")) { + ListNBT comment = value.getList("#comment", Constants.NBT.TAG_STRING); + return comment.stream() + .map(INBT::getString) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraButton.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraButton.java new file mode 100644 index 0000000..5966e4c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraButton.java @@ -0,0 +1,35 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraftforge.fml.client.gui.widget.ExtendedButton; + +public class TerraButton extends ExtendedButton implements Element { + + public TerraButton(String displayString) { + super(0, 0, 200, 20, displayString, b -> {}); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraLabel.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraLabel.java new file mode 100644 index 0000000..8acddf5 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraLabel.java @@ -0,0 +1,52 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; + +public class TerraLabel extends TerraButton { + +// private final GuiLabel label; + + public TerraLabel(String text) { + super(text); + visible = true; +// label = new GuiLabel( +// Collections.singletonList(text), +// 0xFFFFFF, +// Minecraft.getInstance().fontRenderer +// ); +// label.visible = true; + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + Minecraft minecraft = Minecraft.getInstance(); + FontRenderer fontrenderer = minecraft.fontRenderer; + fontrenderer.drawStringWithShadow(getMessage(), x, y + (height - 8) / 2, 0xFFFFFF); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraSlider.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraSlider.java new file mode 100644 index 0000000..0f3fd6e --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/TerraSlider.java @@ -0,0 +1,100 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraftforge.fml.client.gui.widget.Slider; + +import java.util.List; + +public abstract class TerraSlider extends Slider implements Slider.ISlider, Element { + + private final CompoundNBT value; + private final List tooltip; + + private Runnable callback = () -> {}; + + public TerraSlider(String prefix, CompoundNBT value, boolean decimal) { + super(0, 0, 100, 20, prefix, "", value.getFloat("#min"), value.getFloat("#max"), 0F, decimal, true, b -> {}); + this.value = value; + this.parent = this; + this.tooltip = Element.readTooltip(value); + } + + public TerraSlider callback(Runnable callback) { + this.callback = callback; + return this; + } + + @Override + public List getTooltip() { + return tooltip; + } + + @Override + public void onChangeSliderValue(Slider slider) { + onChange(slider, value); + } + + @Override + public void onRelease(double mouseX, double mouseY) { + super.onRelease(mouseX, mouseY); + callback.run(); + } + + protected abstract void onChange(Slider slider, CompoundNBT value); + + public static class Int extends TerraSlider { + + public Int(String prefix, CompoundNBT value) { + super(prefix, value, false); + setValue(value.getInt("value")); + updateSlider(); + } + + @Override + protected void onChange(Slider slider, CompoundNBT value) { + value.putInt("value", slider.getValueInt()); + } + } + + public static class Float extends TerraSlider { + + public Float(String prefix, CompoundNBT value) { + super(prefix, value, true); + precision = 3; + setValue(value.getFloat("value")); + updateSlider(); + } + + @Override + protected void onChange(Slider slider, CompoundNBT value) { + int i = (int) (slider.getValue() * 1000); + float f = i / 1000F; + value.putFloat("value", f); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/Toggle.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/Toggle.java new file mode 100644 index 0000000..2dd2163 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/element/Toggle.java @@ -0,0 +1,86 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraftforge.common.util.Constants; + +public class Toggle extends TerraButton { + + private final String prefix; + private final CompoundNBT value; + private final ListNBT options; + + private int index; + private Runnable callback = () -> {}; + + public Toggle(String prefix, CompoundNBT value) { + super(value.getString("value")); + this.value = value; + this.prefix = prefix; + this.options = value.getList("#options", Constants.NBT.TAG_STRING); + for (int i = 0; i < options.size(); i++) { + String s = options.getString(i); + if (s.equals(value.getString("value"))) { + index = i; + break; + } + } + setMessage(prefix + value.getString("value")); + } + + public Toggle callback(Runnable runnable) { + this.callback = runnable; + return this; + } + + @Override + public boolean mouseClicked(double mx, double my, int button) { + if (super.isValidClickButton(button)) { + int direction = button == 0 ? 1 : -1; + this.playDownSound(Minecraft.getInstance().getSoundHandler()); + this.onClick(mx, my, direction); + return true; + } + return false; + } + + private void onClick(double mouseX, double mouseY, int direction) { + super.onClick(mouseX, mouseY); + index += direction; + if (index >= options.size()) { + index = 0; + } else if (index < 0) { + index = options.size() - 1; + } + String option = options.getString(index); + value.putString("value", option); + setMessage(prefix + option); + callback.run(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/BasePage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/BasePage.java new file mode 100644 index 0000000..e802b99 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/BasePage.java @@ -0,0 +1,33 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +public abstract class BasePage extends Page { + + public BasePage() { + super(4, 0, 0.7F, 0.3F); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/FeaturePage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/FeaturePage.java new file mode 100644 index 0000000..dfa0ead --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/FeaturePage.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class FeaturePage extends BasePage { + + private final TerraSettings settings; + private final CompoundNBT featureSettings; + + public FeaturePage(TerraSettings settings) { + this.settings = settings; + this.featureSettings = NBTHelper.serialize(settings.features); + } + + @Override + public String getTitle() { + return "Feature Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(featureSettings, settings.features); + } + + @Override + public void init(OverlayScreen parent) { + Column left = getColumn(0); + addElements(left.left, left.top, left, featureSettings, false, left.scrollPane::addButton, NO_CALLBACK); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/FilterPage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/FilterPage.java new file mode 100644 index 0000000..25cd306 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/FilterPage.java @@ -0,0 +1,65 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class FilterPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT filterSettings; + + public FilterPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.filterSettings = NBTHelper.serialize(settings.filters); + } + + @Override + public String getTitle() { + return "Filter Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(filterSettings, settings.filters); + } + + @Override + public void init(OverlayScreen parent) { + Column column = getColumn(0); + addElements(0, 0, column, filterSettings, true, column.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(filterSettings, settings.filters)); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/GeneratorPage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/GeneratorPage.java new file mode 100644 index 0000000..5308f50 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/GeneratorPage.java @@ -0,0 +1,65 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class GeneratorPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT generatorSettings; + + public GeneratorPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.generatorSettings = NBTHelper.serialize(settings.generator); + } + + @Override + public String getTitle() { + return "Generator Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(generatorSettings, settings.generator); + } + + @Override + public void init(OverlayScreen parent) { + Column left = getColumn(0); + addElements(left.left, left.top, left, generatorSettings, true, left.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(generatorSettings, settings.generator)); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/Page.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/Page.java new file mode 100644 index 0000000..68c365e --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/Page.java @@ -0,0 +1,201 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.mod.gui.OverlayRenderer; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.ScrollPane; +import com.terraforged.mod.gui.element.TerraButton; +import com.terraforged.mod.gui.element.TerraLabel; +import com.terraforged.mod.gui.element.TerraSlider; +import com.terraforged.mod.gui.element.Toggle; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.client.gui.IGuiEventListener; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.INBT; +import net.minecraftforge.common.util.Constants; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Function; + +public abstract class Page implements IGuiEventListener, OverlayRenderer { + + protected static final Runnable NO_CALLBACK = () -> {}; + + private static final int SLIDER_HEIGHT = 20; + private static final int SLIDER_PAD = 2; + + private final Column[] columns; + private final float[] sizes; + private final int hpad; + private final int vpad; + protected OverlayScreen parent; + + public Page(int hpad, int vpad, float... columnSizes) { + this.hpad = hpad; + this.vpad = vpad; + this.sizes = columnSizes; + this.columns = new Column[columnSizes.length]; + } + + public abstract void save(); + + public abstract void init(OverlayScreen parent); + + @Override + public void renderOverlays(Screen screen, int mouseX, int mouseY) { + for (Column column : columns) { + if (column.scrollPane.children().isEmpty()) { + continue; + } + column.scrollPane.renderOverlays(screen, mouseX, mouseY); + } + } + + public void visit(Consumer consumer) { + for (Column column : columns) { + if (column.scrollPane.children().isEmpty()) { + continue; + } + consumer.accept(column.scrollPane); + } + } + + public boolean action(Function action) { + boolean result = false; + for (Column column : columns) { + if (column.scrollPane.children().isEmpty()) { + continue; + } + boolean b = action.apply(column.scrollPane); + result = b || result; + } + return result; + } + + public void close() { + + } + + public String getTitle() { + return ""; + } + + public Column getColumn(int index) { + return columns[index]; + } + + public final void initPage(int marginH, int marginV, OverlayScreen parent) { + this.parent = parent; + int top = marginV; + int left = marginH; + int pageWidth = parent.width - (marginH * 2); + int pageHeight = parent.height; + for (int i = 0; i < columns.length; i++) { + int columnWidth = Math.round(sizes[i] * pageWidth) - (2 * hpad); + Column column = new Column(left, top, columnWidth, pageHeight, hpad, vpad); + columns[i] = column; + left += columnWidth + (2 * hpad); + } + init(parent); + } + + public void addElements(int x, int y, Column column, CompoundNBT settings, Consumer consumer, Runnable callback) { + addElements(x, y, column, settings, false, consumer, callback); + } + + public void addElements(int x, int y, Column column, CompoundNBT settings, boolean deep, Consumer consumer, Runnable callback) { + AtomicInteger top = new AtomicInteger(y); + + NBTHelper.stream(settings).forEach(value -> { + String name = value.getString("#display"); + Widget button = createButton(name, value, callback); + if (button != null) { + button.setWidth(column.width); + button.setHeight(SLIDER_HEIGHT); + button.x = x; + button.y = top.getAndAdd(SLIDER_HEIGHT + SLIDER_PAD); + consumer.accept(button); + } else if (deep) { + INBT child = value.get("value"); + if (child == null || child.getId() != Constants.NBT.TAG_COMPOUND) { + return; + } + TerraLabel label = new TerraLabel(name); + label.x = x; + label.y = top.getAndAdd(SLIDER_HEIGHT + SLIDER_PAD); + consumer.accept(label); + addElements(x, label.y, column, (CompoundNBT) child, consumer, callback); + } + }); + } + + public Widget createButton(String name, CompoundNBT value, Runnable callback) { + INBT tag = value.get("value"); + if (tag == null) { + return null; + } + + byte type = tag.getId(); + if (type == Constants.NBT.TAG_INT) { + return new TerraSlider.Int(name + ": ", value).callback(callback); + } else if (type == Constants.NBT.TAG_FLOAT) { + return new TerraSlider.Float(name + ": ", value).callback(callback); + } else if (type == Constants.NBT.TAG_STRING && value.contains("#options")) { + return new Toggle(name + ": ", value).callback(callback); + } else if (type == Constants.NBT.TAG_STRING) { + return new TerraButton(name); + } else { + return null; + } + } + + public static class Column { + + public final int left; + public final int right; + public final int top; + public final int bottom; + public final int width; + public final int height; + public final ScrollPane scrollPane; + + private Column(int left, int top, int width, int height, int vpad, int hpad) { + this.left = left + vpad; + this.right = left + width - vpad; + this.top = top + hpad; + this.bottom = height - hpad; + this.width = width; + this.height = height; + this.scrollPane = new ScrollPane(22); + this.scrollPane.updateSize(width, height, 30, height - 30); + this.scrollPane.setLeftPos(this.left); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/RiverPage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/RiverPage.java new file mode 100644 index 0000000..484093b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/RiverPage.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class RiverPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT riverSettings; + + public RiverPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.riverSettings = NBTHelper.serialize(settings.rivers); + } + + @Override + public String getTitle() { + return "River Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(riverSettings, settings.rivers); + } + + @Override + public void init(OverlayScreen parent) { + Column center = getColumn(0); + center.scrollPane.setScrollAmount(0D); + addElements(0, 0, center, riverSettings, true, center.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(riverSettings, settings.rivers)); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/StructurePage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/StructurePage.java new file mode 100644 index 0000000..ed8a522 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/StructurePage.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class StructurePage extends BasePage { + + private final TerraSettings settings; + private final CompoundNBT structureSettings; + + public StructurePage(TerraSettings settings) { + this.settings = settings; + this.structureSettings = NBTHelper.serialize(settings.structures); + } + + @Override + public String getTitle() { + return "Structure Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(structureSettings, settings.structures); + } + + @Override + public void init(OverlayScreen parent) { + Column left = getColumn(0); + addElements(left.left, left.top, left, structureSettings, false, left.scrollPane::addButton, NO_CALLBACK); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/TerrainPage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/TerrainPage.java new file mode 100644 index 0000000..a5514ce --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/page/TerrainPage.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class TerrainPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT terrainSettings; + + public TerrainPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.terrainSettings = NBTHelper.serialize(settings.terrain); + } + + @Override + public String getTitle() { + return "Terrain Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(terrainSettings, settings.terrain); + } + + @Override + public void init(OverlayScreen parent) { + Column center = getColumn(0); + center.scrollPane.setScrollAmount(0D); + addElements(0, 0, center, terrainSettings, true, center.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(terrainSettings, settings.terrain)); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/Preview.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/Preview.java new file mode 100644 index 0000000..29599f8 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/Preview.java @@ -0,0 +1,259 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.Region; +import com.terraforged.core.region.RegionGenerator; +import com.terraforged.core.settings.Settings; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.WorldGeneratorFactory; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.util.nbt.NBTHelper; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.AbstractGui; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.widget.button.Button; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.NativeImage; +import net.minecraft.nbt.CompoundNBT; + +import java.awt.*; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class Preview extends Button { + + private static final int FACTOR = 4; + private static final int BLOCK_SIZE = 256;//Size.chunkToBlock(1 << FACTOR); + private static final float[] LEGEND_SCALES = {1, 0.9F, 0.75F, 0.6F}; + + private final int offsetX; + private final int offsetZ; + private final Random random = new Random(System.currentTimeMillis()); + private final PreviewSettings previewSettings = new PreviewSettings(); + private final DynamicTexture texture = new DynamicTexture(new NativeImage(BLOCK_SIZE, BLOCK_SIZE, true)); + + private int seed; + private long lastUpdate = 0L; + private Settings settings = new Settings(); + private Future task = null; + private Region region = null; + + private String[] labels = {"Area: ", "Terrain: ", "Biome: "}; + private String[] values = {"", "", ""}; + + public Preview() { + super(0, 0, 0, 0, "", b -> {}); + this.seed = random.nextInt(); + this.offsetX = random.nextInt(50000) - 25000; + this.offsetZ = random.nextInt(50000) - 25000; + } + + public void regenerate() { + this.seed = random.nextInt(); + } + + public void close() { + texture.close(); + } + + @Override + public void render(int mx, int my, float partialTicks) { + preRender(); + + texture.bindTexture(); + RenderSystem.enableBlend(); + RenderSystem.enableRescaleNormal(); + RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + + AbstractGui.blit(x, y, 0, 0, width, height, width, height); + RenderSystem.disableRescaleNormal(); + + updateLegend(mx, my); + renderLegend(labels, values, x + 1, y + height + 2, 15, 0xFFFFFF); + } + + public void update(Settings settings, CompoundNBT prevSettings) { + long time = System.currentTimeMillis(); + if (time - lastUpdate < 50) { + return; + } + lastUpdate = time; + + NBTHelper.deserialize(prevSettings, previewSettings); + settings.generator.seed = seed; + + task = generate(settings, prevSettings); + } + + private void preRender() { + if (task != null && task.isDone()) { + try { + region = task.get(); + render(region); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.getCause().printStackTrace(); + } finally { + task = null; + } + } + } + + private void render(Region region) { + NativeImage image = texture.getTextureData(); + if (image == null) { + return; + } + + RenderMode renderer = previewSettings.mode; + Terrains terrains = Terrains.create(settings); + GeneratorContext context = new GeneratorContext(terrains, settings); + + int stroke = 2; + int width = region.getBlockSize().size; + region.iterate((cell, x, z) -> { + if (x < stroke || z < stroke || x >= width - stroke || z >= width - stroke) { + image.setPixelRGBA(x, z, Color.black.getRGB()); + } else { + Color color = renderer.color(cell, context); + image.setPixelRGBA(x, z, RenderMode.rgba(color)); + } + }); + + texture.updateDynamicTexture(); + } + + private Future generate(Settings settings, CompoundNBT prevSettings) { + NBTHelper.deserialize(prevSettings, previewSettings); + settings.generator.seed = seed; + this.settings = settings; + + GeneratorContext context = new GeneratorContext(Terrains.create(settings), settings); + + RegionGenerator renderer = RegionGenerator.builder() + .factory(new WorldGeneratorFactory(context)) + .pool(ThreadPool.getCommon()) + .size(FACTOR, 0) + .build(); + + return renderer.generate(offsetX, offsetZ, 101 - previewSettings.zoom, false); + } + + private void updateLegend(int mx ,int my) { + if (region != null) { + int zoom = (101 - previewSettings.zoom); + int width = Math.max(1, region.getBlockSize().size * zoom); + int height = Math.max(1, region.getBlockSize().size * zoom); + values[0] = width + "x" + height; + + if (mx >= this.x && mx <= this.x + this.width && my >= this.y && my <= this.y + this.height) { + float fx = (mx - this.x) / (float) this.width; + float fz = (my - this.y) / (float) this.height; + int ix = NoiseUtil.round(fx * region.getBlockSize().size); + int iz = NoiseUtil.round(fz * region.getBlockSize().size); + Cell cell = region.getCell(ix, iz); + values[1] = getTerrainName(cell); + values[2] = getBiomeName(cell); + } + } + } + + private float getLegendScale() { + int index = Minecraft.getInstance().gameSettings.guiScale - 1; + if (index < 0 || index >= LEGEND_SCALES.length) { + // index=-1 == GuiScale(AUTO) which is the same as GuiScale(4) + // values above 4 don't exist but who knows what mods might try set it to + // in both cases use the smallest acceptable scale + index = LEGEND_SCALES.length - 1; + } + return LEGEND_SCALES[index]; + } + + private void renderLegend(String[] labels, String[] values, int left, int top, int lineHeight, int color) { + float scale = getLegendScale(); + lineHeight = Math.round(lineHeight * scale); + + RenderSystem.pushMatrix(); + RenderSystem.translatef(left, top, 0); + RenderSystem.scalef(scale, scale, 1); + + FontRenderer renderer = Minecraft.getInstance().fontRenderer; + int spacing = 0; + for (String s : labels) { + spacing = Math.max(spacing, renderer.getStringWidth(s)); + } + + int maxX = this.x + this.width; + for (int i = 0; i < labels.length && i < values.length; i++) { + String label = labels[i]; + String value = values[i]; + + while (left + spacing + Minecraft.getInstance().fontRenderer.getStringWidth(value) > maxX) { + value = value.substring(0, value.length() - 1); + } + + drawString(renderer, label, 0, i * lineHeight, color); + drawString(renderer, value, spacing, i * lineHeight, color); + } + + RenderSystem.popMatrix(); + } + + private static String getTerrainName(Cell cell) { + String terrain = cell.tag.getName().toLowerCase(); + if (terrain.contains("river")) { + return "river"; + } + return terrain; + } + + private static String getBiomeName(Cell cell) { + String terrain = cell.tag.getName().toLowerCase(); + if (terrain.contains("ocean")) { + if (cell.temperature < 0.3) { + return "cold_ocean"; + } + if (cell.temperature > 0.6) { + return "warm_ocean"; + } + return "ocean"; + } + if (terrain.contains("river")) { + return "river"; + } + return cell.biomeType.name().toLowerCase(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java new file mode 100644 index 0000000..cb51588 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java @@ -0,0 +1,100 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.element.TerraButton; +import com.terraforged.mod.gui.page.BasePage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +import java.util.function.Consumer; + +public class PreviewPage extends BasePage { + + private final Preview preview = new Preview(); + private final Settings settings = new Settings(); + private final CompoundNBT previewerSettings = NBTHelper.serialize(new PreviewSettings()); + + public PreviewPage() { + + } + + public void apply(Consumer consumer) { + consumer.accept(settings); + preview.update(settings, previewerSettings); + } + + @Override + public void close() { + preview.close(); + } + + @Override + public void save() { + + } + + @Override + public void init(OverlayScreen parent) { + Column right = getColumn(1); + preview.x = 0; + preview.y = 0; + preview.setWidth(256); + preview.setHeight(256); + + addElements(right.left, right.top, right, previewerSettings, right.scrollPane::addButton, this::update); + right.scrollPane.addButton(new TerraButton("New Seed") { + @Override + public void onPress() { + preview.regenerate(); + update(); + } + }); + + right.scrollPane.addButton(preview); + + // used to pad the scroll-pane out so that the preview legend scrolls on larger gui scales + TerraButton spacer = createSpacer(); + for (int i = 0; i < 6; i++) { + right.scrollPane.addButton(spacer); + } + + update(); + } + + private void update() { + preview.update(settings, previewerSettings); + } + + private static TerraButton createSpacer() { + return new TerraButton("") { + @Override + public void render(int x, int y, float tick) { } + }; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/PreviewSettings.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/PreviewSettings.java new file mode 100644 index 0000000..661c80c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/PreviewSettings.java @@ -0,0 +1,36 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.terraforged.core.util.serialization.annotation.Range; + +public class PreviewSettings { + + @Range(min = 1, max = 100) + public int zoom = 100 - 32; + + public RenderMode mode = RenderMode.BIOME_TYPE; +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/RenderMode.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/RenderMode.java new file mode 100644 index 0000000..3bb8caa --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/gui/preview/RenderMode.java @@ -0,0 +1,83 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.util.NoiseUtil; + +import java.awt.*; + +public enum RenderMode { + BIOME_TYPE, + TEMPERATURE, + MOISTURE, + BIOME_SHAPE, + ; + + public Color color(Cell cell, GeneratorContext context) { + float baseHeight = Levels.getSeaLevel(context.settings.generator); + if (cell.value < baseHeight) { + return new Color(40, 140, 200); + } + + float bands = 10F; + float alpha = 0.15F; + float elevation = (cell.value - baseHeight) / (1F - baseHeight); + + int band = NoiseUtil.round(elevation * bands); + float scale = 1F - alpha; + float bias = alpha * (band / bands); + + float saturation = 0.7F; + float brightness = 0.8F; + + switch (this) { + case BIOME_SHAPE: + return Color.getHSBColor(cell.biome, saturation, brightness); + case BIOME_TYPE: + Color color = cell.biomeType.getColor(); + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), new float[3]); + return Color.getHSBColor(hsb[0], hsb[1], (hsb[2] * scale) + bias); + case MOISTURE: + return Color.getHSBColor(step(1 - cell.moisture, 8) * 0.65F, saturation, brightness); + case TEMPERATURE: + return Color.getHSBColor(step(cell.temperature, 8) * 0.65F, saturation, brightness); + default: + return Color.black; + } + } + + private static float step(float value, int steps) { + return ((float) NoiseUtil.round(value * steps)) / steps; + } + + public static int rgba(Color color) { + return color.getRed() + (color.getGreen() << 8) + (color.getBlue() << 16) + (255 << 24); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/MaterialHelper.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/MaterialHelper.java new file mode 100644 index 0000000..fdc1360 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/MaterialHelper.java @@ -0,0 +1,151 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material; + +import com.google.common.collect.Sets; +import com.terraforged.core.util.concurrent.ObjectPool; +import com.terraforged.mod.util.DummyBlockReader; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.ConcretePowderBlock; +import net.minecraft.block.material.Material; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.feature.ConfiguredFeature; +import net.minecraft.world.gen.feature.DecoratedFeatureConfig; +import net.minecraft.world.gen.feature.OreFeatureConfig; +import net.minecraftforge.common.Tags; +import net.minecraftforge.registries.IForgeRegistryEntry; + +import java.util.Set; + +public class MaterialHelper { + + private static final Set BLACKLIST = Sets.newHashSet( + Blocks.INFESTED_CHISELED_STONE_BRICKS, + Blocks.INFESTED_COBBLESTONE, + Blocks.INFESTED_CRACKED_STONE_BRICKS, + Blocks.INFESTED_MOSSY_STONE_BRICKS, + Blocks.INFESTED_STONE, + Blocks.INFESTED_STONE_BRICKS, + Blocks.SLIME_BLOCK, + Blocks.RED_SAND, + Blocks.SOUL_SAND, + // honey etc + Blocks.HONEY_BLOCK, + Blocks.HONEYCOMB_BLOCK, + Blocks.BEE_NEST, + Blocks.BEEHIVE, + Blocks.COMPOSTER + ); + + public static boolean isAir(Block block) { + return block == Blocks.AIR || block == Blocks.CAVE_AIR || block == Blocks.VOID_AIR; + } + + public static boolean isGrass(Block block) { + return block == Blocks.GRASS_BLOCK || block == Blocks.MYCELIUM; + } + + public static boolean isStone(Block block) { + return Tags.Blocks.STONE.contains(block) + && !isBlacklisted(block) + && !("" + block.getRegistryName()).contains("polished_"); + } + + public static boolean isDirt(Block block) { + return Tags.Blocks.DIRT.contains(block) + && !isBlacklisted(block); + } + + public static boolean isClay(Block block) { + return block.getDefaultState().getMaterial() == Material.CLAY + && !isBlacklisted(block); + } + + public static boolean isSand(Block block) { + return BlockTags.SAND.contains(block) + && !isBlacklisted(block) + && !(block instanceof ConcretePowderBlock); + } + + public static boolean isSediment(Block block) { + return (isSand(block) || isGravel(block)) + && !isBlacklisted(block) + && !(block instanceof ConcretePowderBlock); + } + + public static boolean isGravel(Block block) { + return getName(block).contains("gravel"); + } + + public static boolean isOre(Block block) { + return Tags.Blocks.ORES.contains(block) + && !isBlacklisted(block); + } + + public static boolean isBlacklisted(Block block) { + return BLACKLIST.contains(block); + } + + public static String getName(IForgeRegistryEntry entry) { + return "" + entry.getRegistryName(); + } + + public static String getNamespace(IForgeRegistryEntry entry) { + ResourceLocation name = entry.getRegistryName(); + if (name == null) { + return "unknown"; + } + return name.getNamespace(); + } + + public static float getHardness(BlockState state) { + try (ObjectPool.Item reader = DummyBlockReader.pooled()) { + reader.getValue().set(state); + return state.getBlockHardness(reader.getValue(), BlockPos.ZERO); + } + } + + public static boolean isCube(BlockState state) { + try (ObjectPool.Item reader = DummyBlockReader.pooled()) { + reader.getValue().set(state); + return state.isNormalCube(reader.getValue(), BlockPos.ZERO); + } + } + + public static OreFeatureConfig getOreConfig(ConfiguredFeature feature) { + if (feature.config instanceof DecoratedFeatureConfig) { + DecoratedFeatureConfig config = (DecoratedFeatureConfig) feature.config; + if (config.feature.config instanceof OreFeatureConfig) { + return (OreFeatureConfig) config.feature.config; + } + } + return null; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/Materials.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/Materials.java new file mode 100644 index 0000000..aa42ad1 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/Materials.java @@ -0,0 +1,163 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material; + +import com.terraforged.api.material.MaterialTags; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.api.material.state.States; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.tags.Tag; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Predicate; + +public class Materials { + + private final Set stone = create(MaterialTags.WG_ROCK); + private final Set dirt = create(MaterialTags.WG_EARTH); + private final Set clay = create(MaterialTags.WG_CLAY); + private final Set sediment = create(MaterialTags.WG_SEDIMENT); + private final Set ore = create(MaterialTags.WG_ORE); + private final Set erodible = create(MaterialTags.WG_ERODIBLE); + private final LayerManager layerManager = new LayerManager(); + + public Materials() { + Predicate filter = getTagFilter(); + for (Block block : ForgeRegistries.BLOCKS) { + if (filter.test(block)) { + continue; + } + + if (!MaterialHelper.isCube(block.getDefaultState())) { + continue; + } + + if (MaterialHelper.isStone(block)) { + stone.add(block); + } else if (MaterialHelper.isDirt(block)) { + dirt.add(block); + } else if (MaterialHelper.isClay(block)) { + clay.add(block); + } else if (MaterialHelper.isSediment(block)) { + sediment.add(block); + } else if (MaterialHelper.isOre(block)) { + ore.add(block); + } + } + + if (stone.isEmpty()) { + stone.add(Blocks.STONE); + } + } + + public LayerManager getLayerManager() { + return layerManager; + } + + public boolean isStone(Block block) { + return stone.contains(block); + } + + public boolean isEarth(Block block) { + return dirt.contains(block); + } + + public boolean isClay(Block block) { + return clay.contains(block); + } + + public boolean isSediment(Block block) { + return sediment.contains(block); + } + + public boolean isOre(Block block) { + return ore.contains(block); + } + + public boolean isErodible(Block block) { + return erodible.contains(block); + } + + public Collection getStone() { + if (stone.isEmpty()) { + return Collections.singleton(States.STONE.getBlock()); + } + return Collections.unmodifiableSet(stone); + } + + public Collection getDirt() { + if (dirt.isEmpty()) { + return Collections.singleton(States.DIRT.getBlock()); + } + return Collections.unmodifiableSet(dirt); + } + + public Collection getClay() { + if (clay.isEmpty()) { + return Collections.singleton(States.STONE.getBlock()); + } + return Collections.unmodifiableSet(clay); + } + + public Collection getSediment() { + if (sediment.isEmpty()) { + return Collections.singleton(States.CLAY.getBlock()); + } + return Collections.unmodifiableSet(sediment); + } + + public Collection getOre() { + if (ore.isEmpty()) { + return Collections.singleton(States.STONE.getBlock()); + } + return Collections.unmodifiableSet(ore); + } + + private static Set create(Tag tag) { + return new HashSet<>(tag.getAllElements()); + } + + private static Predicate getTagFilter() { + Set namespaces = new HashSet<>(); + collectNamespace(namespaces, MaterialTags.WG_ROCK.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_EARTH.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_EARTH.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_SEDIMENT.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_ORE.getAllElements()); + return b -> namespaces.contains(MaterialHelper.getNamespace(b)); + } + + private static void collectNamespace(Set set, Collection blocks) { + for (Block block : blocks) { + set.add(MaterialHelper.getNamespace(block)); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/geology/GeoGenerator.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/geology/GeoGenerator.java new file mode 100644 index 0000000..75a770a --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/geology/GeoGenerator.java @@ -0,0 +1,118 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material.geology; + +import com.terraforged.api.material.geology.StrataConfig; +import com.terraforged.api.material.geology.StrataGenerator; +import com.terraforged.core.world.geology.Strata; +import com.terraforged.mod.material.MaterialHelper; +import com.terraforged.mod.material.Materials; +import me.dags.noise.Source; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Random; + +public class GeoGenerator implements StrataGenerator { + + private final List rock; + private final List soil; + private final List clay; + private final List sediment; + private final List types = new ArrayList<>(); + + public GeoGenerator(Materials materials) { + types.add(Source.PERLIN); + rock = new ArrayList<>(materials.getStone()); + soil = new ArrayList<>(materials.getDirt()); + clay = new ArrayList<>(materials.getClay()); + sediment = new ArrayList<>(materials.getSediment()); + } + + @Override + public Strata generate(int seed, int scale, StrataConfig config) { + Random random = new Random(); + Strata.Builder builder = Strata.builder(++seed, Source.build(++seed, scale, 3)); + addLayer(seed + 1, random, config.soil, soil, builder); + addLayer(seed + 2, random, config.sediment, sediment, builder); + addLayer(seed + 3, random, config.clay, clay, builder); + addLayer(seed + 4, random, config.rock, rock, builder); + return builder.build(); + } + + private void addLayer(int seed, Random random, StrataConfig.Config config, List materials, Strata.Builder builder) { + random.setSeed(seed); + List layers = generateLayers(materials, config, random); + layers.forEach(l -> builder.add(l.type, l.state, l.depth)); + } + + private List generateLayers(List materials, StrataConfig.Config config, Random random) { + int lastIndex = -1; + int layers = config.getLayers(random.nextFloat()); + List result = new ArrayList<>(); + for (int i = 0; i < layers; i++) { + int attempts = 3; + int index = random.nextInt(materials.size()); + while (--attempts >= 0 && index == lastIndex) { + index = random.nextInt(materials.size()); + } + if (index != lastIndex) { + lastIndex = index; + BlockState material = materials.get(index).getDefaultState(); + float depth = config.getDepth(random.nextFloat()); + Source type = nextType(random); + result.add(new Layer(material, depth, type)); + } + } + return result; + } + + private Source nextType(Random random) { + int index = random.nextInt(types.size()); + return types.get(index); + } + + private List sortHardness(List layers) { + layers.sort(Comparator.comparing(s -> MaterialHelper.getHardness(s.state))); + return layers; + } + + private static class Layer { + + private final BlockState state; + private final float depth; + private final Source type; + + private Layer(BlockState state, float depth, Source type) { + this.state = state; + this.depth = depth; + this.type = type; + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/geology/GeoManager.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/geology/GeoManager.java new file mode 100644 index 0000000..2b6634b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/material/geology/GeoManager.java @@ -0,0 +1,116 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material.geology; + +import com.terraforged.api.material.geology.GeologyManager; +import com.terraforged.api.material.geology.StrataConfig; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.geology.Geology; +import com.terraforged.core.world.geology.Strata; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.material.Materials; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.block.BlockState; +import net.minecraft.world.biome.Biome; + +import java.util.HashMap; +import java.util.Map; + +public class GeoManager implements GeologyManager { + + private final Module selector; + private final Materials materials; + private final GeoGenerator builder; + private final Geology general; + private final Map> specific = new HashMap<>(); + + public GeoManager(TerraContext context) { + int scale = context.settings.generator.land.regionSize / 2; + this.selector = Source.cell(context.seed.next(), scale) + .warp(context.seed.next(), scale / 4, 2, scale / 2D) + .warp(context.seed.next(), 15, 2, 30); + this.builder = new GeoGenerator(context.materials); + this.general = new Geology<>(selector); + this.materials = context.materials; + init(context.seed); + } + + public GeoGenerator getStrataGenerator() { + return builder; + } + + @Override + public void register(Strata strata) { + general.add(strata); + } + + @Override + public void register(Biome biome, Strata strata) { + register(biome, strata, false); + } + + /** + * Register a biome specific strata group. + * If a specific geology doesn't exist for a given biome, the global geology can optionally be added using + * the 'inheritGlobal' flag. + */ + public void register(Biome biome, Strata strata, boolean inheritGlobal) { + Geology geology = specific.get(biome); + if (geology == null) { + geology = new Geology<>(selector); + specific.put(biome, geology); + if (inheritGlobal) { + geology.add(general); + } + } + geology.add(strata); + } + + /** + * Register/replace a biome-specific geology group + */ + public void register(Biome biome, Geology geology) { + specific.put(biome, geology); + } + + public Geology getGeology(Biome biome) { + return specific.getOrDefault(biome, general); + } + + public Strata getStrata(Biome biome, float value) { + return getGeology(biome).getStrata(value); + } + + private void init(Seed seed) { + StrataConfig config = new StrataConfig(); + GeoGenerator generator = new GeoGenerator(materials); + for (int i = 0; i < 10; i++) { + Strata strata = generator.generate(seed.next(), 128, config); + general.add(strata); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/FeatureSettings.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/FeatureSettings.java new file mode 100644 index 0000000..e623ae5 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/FeatureSettings.java @@ -0,0 +1,48 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.settings; + +import com.terraforged.core.util.serialization.annotation.Comment; +import com.terraforged.core.util.serialization.annotation.Serializable; + +@Serializable +public class FeatureSettings { + + @Comment("Modifies layer block levels (ie snow) to fit the terrain") + public boolean smoothLayerDecorator = true; + + @Comment("Generates strata (rock layers) instead of just stone") + public boolean strataDecorator = true; + + @Comment("Replace surface materials where erosion has occurred") + public boolean erosionDecorator = true; + + @Comment("Removes snow from the terrain where it shouldn't naturally settle") + public boolean naturalSnowDecorator = true; + + @Comment("Use custom biome features in place of vanilla ones (such as trees)") + public boolean customBiomeFeatures = true; +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/SettingsHelper.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/SettingsHelper.java new file mode 100644 index 0000000..172f54d --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/SettingsHelper.java @@ -0,0 +1,67 @@ +package com.terraforged.mod.settings; + +import com.google.gson.Gson; +import com.terraforged.mod.Log; +import com.terraforged.mod.TerraWorld; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.world.IWorld; +import net.minecraft.world.storage.WorldInfo; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + +public class SettingsHelper { + + public static final String SETTINGS_FILE_NAME = "terraforged-generator.json"; + private static boolean dedicated = false; + + public static void setDedicatedServer() { + dedicated = true; + } + + public static int getVersion(WorldInfo info) { + if (info.getGeneratorOptions().isEmpty()) { + // if options have not been set then the world has been created + // during the current runtime .: is not legacy + return TerraWorld.VERSION; + } + + CompoundNBT version = info.getGeneratorOptions().getCompound("version"); + if (version.isEmpty()) { + // version tag is absent in legacy worlds .: is legacy + return 0; + } + + return version.getInt("value"); + } + + public static TerraSettings getSettings(IWorld world) { + if (dedicated) { + try (Reader reader = new BufferedReader(new FileReader(new File("config", SETTINGS_FILE_NAME)))) { + Log.info("Loading generator settings from json"); + return new Gson().fromJson(reader, TerraSettings.class); + } catch (Throwable ignored) { + return getSettings(world.getWorldInfo()); + } + } + return getSettings(world.getWorldInfo()); + } + + public static TerraSettings getSettings(WorldInfo info) { + TerraSettings settings = new TerraSettings(); + if (!info.getGeneratorOptions().isEmpty()) { + NBTHelper.deserialize(info.getGeneratorOptions(), settings); + } + return settings; + } + + public static void syncSettings(WorldInfo info, TerraSettings settings, int version) { + settings.version = version; + settings.generator.seed = info.getSeed(); + CompoundNBT options = NBTHelper.serialize(settings); + info.setGeneratorOptions(options); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/StructureSettings.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/StructureSettings.java new file mode 100644 index 0000000..cc77d11 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/StructureSettings.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.settings; + +import com.terraforged.core.util.serialization.annotation.Comment; +import com.terraforged.core.util.serialization.annotation.Range; +import com.terraforged.core.util.serialization.annotation.Serializable; + +@Serializable +public class StructureSettings { + + @Range(min = 1, max = 10) + @Comment("Controls the distance between villages") + public int villageDistance = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between mansions") + public int mansionDistance = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between strongholds") + public int strongholdDistance = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between biome structures") + public int biomeStructureDistance = 2; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between ocean monuments") + public int oceanMonumentSpacing = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the separation between ocean monuments") + public int oceanMonumentSeparation = 4; +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/TerraSettings.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/TerraSettings.java new file mode 100644 index 0000000..dee2fbb --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/settings/TerraSettings.java @@ -0,0 +1,39 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.settings; + +import com.terraforged.core.settings.Settings; +import com.terraforged.core.util.serialization.annotation.Serializable; + +@Serializable +public class TerraSettings extends Settings { + + public int version = 1; + + public FeatureSettings features = new FeatureSettings(); + + public StructureSettings structures = new StructureSettings(); +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/DummyBlockReader.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/DummyBlockReader.java new file mode 100644 index 0000000..a4197e4 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/DummyBlockReader.java @@ -0,0 +1,77 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util; + +import com.terraforged.core.util.concurrent.ObjectPool; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.BlockView; + +public class DummyBlockReader implements BlockView { + + private static final ObjectPool pool = new ObjectPool<>(10, DummyBlockReader::new); + + private BlockState state; + private FluidState fluid; + + public DummyBlockReader set(BlockState state) { + return set(state, Fluids.EMPTY.getDefaultState()); + } + + public DummyBlockReader set(FluidState fluid) { + return set(Blocks.AIR.getDefaultState(), fluid); + } + + public DummyBlockReader set(BlockState state, FluidState fluid) { + this.state = state; + this.fluid = fluid; + return this; + } + + //@Nullable + @Override + public BlockEntity getBlockEntity(BlockPos pos) { + return null; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return state; + } + + @Override + public FluidState getFluidState(BlockPos pos) { + return fluid; + } + + public static ObjectPool.Item pooled() { + return pool.get(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/Environment.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/Environment.java new file mode 100644 index 0000000..d539ac0 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/Environment.java @@ -0,0 +1,43 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util; + +import com.terraforged.mod.Log; + +public class Environment { + + private static final boolean dev = System.getProperty("dev") != null; + + public static boolean isDev() { + return dev; + } + + static { + if (dev) { + Log.info("Running in developer mode!"); + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/ListUtils.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/ListUtils.java new file mode 100644 index 0000000..608d5be --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/ListUtils.java @@ -0,0 +1,74 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util; + +import me.dags.noise.util.NoiseUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ListUtils { + + public static T get(List list, float value, T def) { + if (list.isEmpty()) { + return def; + } + return get(list, list.size() - 1, value, def); + } + + public static T get(List list, int maxIndex, float value, T def) { + int index = NoiseUtil.round(value * maxIndex); + if (index < list.size()) { + return list.get(index); + } + return def; + } + + public static List minimize(List list) { + Map counts = count(list); + List result = new ArrayList<>(list.size()); + int min = counts.values().stream().min(Integer::compareTo).orElse(1); + for (T t : list) { + int count = counts.get(t); + int amount = count / min; + for (int i = 0; i < amount; i++) { + result.add(t); + } + } + return result; + } + + public static Map count(List list) { + Map map = new HashMap<>(list.size()); + for (T t : list) { + int count = map.getOrDefault(t, 0); + map.put(t, ++count); + } + return map; + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java new file mode 100644 index 0000000..1635d55 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java @@ -0,0 +1,116 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.nbt; + +import com.google.gson.JsonElement; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.JsonOps; +import com.terraforged.core.util.serialization.serializer.Serializer; +import net.minecraft.datafixer.NbtOps; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; + +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Stream; + +public class NBTHelper { + + public static JsonElement toJson(CompoundTag tag) { + Dynamic input = new Dynamic<>(NbtOps.INSTANCE, tag); + Dynamic output = input.convert(JsonOps.INSTANCE); + return output.getValue(); + } + + public static Stream stream(CompoundTag tag) { + return tag.getKeys().stream() + .map(tag::getCompound) + .sorted(Comparator.comparing(t -> t.getInt("#order"))); + + } + + public static CompoundTag serialize(Object object) { + try { + NBTWriter writer = new NBTWriter(); + writer.readFrom(object); + return writer.compound(); + } catch (IllegalAccessException e) { + return new CompoundTag(); + } + } + + public static CompoundTag serializeCompact(Object object) { + try { + NBTWriter writer = new NBTWriter(); + writer.readFrom(object); + return stripMetadata(writer.compound()); + } catch (IllegalAccessException e) { + return new CompoundTag(); + } + } + + public static CompoundTag readCompact(Object object) { + try { + NBTWriter writer = new NBTWriter(); + writer.readFrom(object); + new Serializer().serialize(object, writer); + return writer.compound(); + } catch (IllegalAccessException e) { + return new CompoundTag(); + } + } + + public static T stripMetadata(T tag) { + if (tag instanceof CompoundTag) { + CompoundTag compound = (CompoundTag) tag; + List keys = new LinkedList<>(compound.getKeys()); + for (String key : keys) { + if (key.charAt(0) == '#') { + compound.remove(key); + } else { + stripMetadata(compound.get(key)); + } + } + } else if (tag instanceof ListTag) { + ListTag list = (ListTag) tag; + for (int i = 0; i < list.size(); i++) { + stripMetadata(list.get(i)); + } + } + return tag; + } + + public static void deserialize(CompoundTag settings, Object object) { + try { + NBTReader reader = new NBTReader(settings); + reader.writeTo(object); + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTReader.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTReader.java new file mode 100644 index 0000000..af8157c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTReader.java @@ -0,0 +1,121 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.nbt; + +import com.terraforged.core.util.serialization.serializer.Reader; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.Tag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; + +import java.util.Collection; + +public class NBTReader implements Reader { + + private final Tag root; + + public NBTReader(Tag root) { + this.root = root; + } + + @Override + public int getSize() { + if (root instanceof CompoundTag) { + return ((CompoundTag) root).getSize(); + } + if (root instanceof ListTag) { + return ((ListTag) root).size(); + } + return 1; + } + + @Override + public NBTReader getChild(String key) { + return new NBTReader(((CompoundTag) root).get(key)); + } + + @Override + public NBTReader getChild(int index) { + return new NBTReader(((ListTag) root).get(index)); + } + + @Override + public Collection getKeys() { + return ((CompoundTag) root).getKeys(); + } + + @Override + public String getString(String key) { + return ((CompoundTag) root).getString(key); + } + + @Override + public float getFloat(String key) { + return ((CompoundTag) root).getFloat(key); + } + + @Override + public int getInt(String key) { + return ((CompoundTag) root).getInt(key); + } + + @Override + public String getString(int index) { + return ((ListTag) root).getString(index); + } + + @Override + public float getFloat(int index) { + return ((ListTag) root).getFloat(index); + } + + @Override + public int getInt(int index) { + return ((ListTag) root).getInt(index); + } + + @Override + public String getString() { + return root.asString(); + } + + @Override + public boolean getBool() { + return ((ByteTag) root).getByte() == 1; + } + + @Override + public float getFloat() { + return ((FloatTag) root).getFloat(); + } + + @Override + public int getInt() { + return ((IntTag) root).getInt(); + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTWriter.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTWriter.java new file mode 100644 index 0000000..5c21b7e --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/nbt/NBTWriter.java @@ -0,0 +1,132 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.nbt; + +import com.terraforged.core.util.serialization.serializer.Writer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; + +public class NBTWriter implements Writer { + + private final Context root = new Context(null); + + private String name = ""; + private Context context = root; + + public NBTWriter() { + + } + + public Tag root() { + return root.value; + } + + public CompoundTag compound() { + return (CompoundTag) root(); + } + + public ListTag list() { + return (ListTag) root(); + } + + private NBTWriter begin(Tag value) { + if (root.value == null) { + root.value = value; + context.value = value; + } else { + append(value); + context = new Context(context); + context.value = value; + } + return this; + } + + private NBTWriter append(Tag value) { + if (context.value instanceof CompoundTag) { + ((CompoundTag) context.value).put(name, value); + } else if (context.value instanceof ListTag) { + ((ListTag) context.value).add(value); + } + return this; + } + + @Override + public NBTWriter name(String name) { + this.name = name; + return this; + } + + @Override + public NBTWriter beginObject() { + return begin(new CompoundTag()); + } + + @Override + public NBTWriter endObject() { + context = context.parent; + return this; + } + + @Override + public NBTWriter beginArray() { + return begin(new ListTag()); + } + + @Override + public NBTWriter endArray() { + context = context.parent; + return this; + } + + @Override + public NBTWriter value(String value) { + return append(StringTag.of(value)); + } + + @Override + public NBTWriter value(float value) { + return append(FloatTag.of(value)); + } + + @Override + public NBTWriter value(int value) { + return append(IntTag.of(value)); + } + + private static class Context { + + private final Context parent; + private Tag value; + + private Context(Context root) { + this.parent = root; + } + } +} diff --git a/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/setup/SetupHooks.java b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/setup/SetupHooks.java new file mode 100644 index 0000000..2050267 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/java/com/terraforged/mod/util/setup/SetupHooks.java @@ -0,0 +1,76 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.setup; + +import com.terraforged.api.biome.modifier.ModifierManager; +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorManager; +import com.terraforged.api.chunk.surface.SurfaceManager; +import com.terraforged.api.event.SetupEvent; +import com.terraforged.api.material.geology.GeologyManager; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.terrain.provider.TerrainProvider; +import com.terraforged.feature.modifier.FeatureModifiers; + +import java.util.List; + +public class SetupHooks { + + public static T setup(T provider, GeneratorContext context) { + SetupEvent.TERRAIN.invoker().handle(provider, context); + return provider; + } + + public static T setup(T manager, GeneratorContext context) { + SetupEvent.SURFACE.invoker().handle(manager, context); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + SetupEvent.BIOME_MODIFIER.invoker().handle(manager, context); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + SetupEvent.LAYERS.invoker().handle(manager, context); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + SetupEvent.GEOLOGY.invoker().handle(manager, context); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + SetupEvent.FEATURES.invoker().handle(manager, context); + return manager; + } + + public static void setup(List base, List feature, GeneratorContext context) { + SetupEvent.DECORATORS.invoker().handle(new DecoratorManager(base, feature), context); + } +} diff --git a/TerraForgedMod-fabric/src/main/resources/assets/terraforged/lang/en_us.json b/TerraForgedMod-fabric/src/main/resources/assets/terraforged/lang/en_us.json new file mode 100644 index 0000000..529f20c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/assets/terraforged/lang/en_us.json @@ -0,0 +1,12 @@ +{ + "generator.terraforged": "TerraForged", + "generator.terratest": "TerraTest", + "biome.terraforged.cold_steppe": "Cold Steppe", + "biome.terraforged.marshland": "Marshland", + "biome.terraforged.savanna_scrub": "Savanna Scrub", + "biome.terraforged.shattered_savanna_scrub": "Shattered Savanna Scrub", + "biome.terraforged.snowy_taiga_scrub": "Snowy Taiga Scrub", + "biome.terraforged.steppe": "Steppe", + "biome.terraforged.taiga_scrub": "Taiga Scrub", + "biome.terraforged.warm_beach": "Warm Beach" +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/biomes.txt b/TerraForgedMod-fabric/src/main/resources/biomes.txt new file mode 100644 index 0000000..8abd632 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/biomes.txt @@ -0,0 +1,13 @@ +#TerraForged BiomeType Hex Colors (do not include hash/pound character) +#Fri Jan 10 23:15:10 GMT 2020 +ALPINE=4b7835 +TAIGA=4b7835 +TEMPERATE_RAINFOREST=3c602b +TUNDRA=ba9d47 +TROPICAL_RAINFOREST=4aa73a +SAVANNA=389a38 +GRASSLAND=429545 +TEMPERATE_FOREST=456938 +STEPPE=c3aa61 +DESERT=e5d98f +COLD_STEPPE=a7a374 \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/coal.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/coal.json new file mode 100644 index 0000000..ffc6646 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/coal.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:coal" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 17, + "target": "natural_stone", + "state": { + "Name": "minecraft:coal_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 20, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 160 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/diamond.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/diamond.json new file mode 100644 index 0000000..a937721 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/diamond.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:diamond_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 8, + "target": "natural_stone", + "state": { + "Name": "minecraft:diamond_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 1, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 32 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/gold.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/gold.json new file mode 100644 index 0000000..4bcbeba --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/gold.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:gold_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 9, + "target": "natural_stone", + "state": { + "Name": "minecraft:gold_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 2, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 80 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/gold_extra.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/gold_extra.json new file mode 100644 index 0000000..58d0771 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/gold_extra.json @@ -0,0 +1,39 @@ +{ + "biomes": [ + "minecraft:badlands*", + "minecraft:eroded_badlands*", + "minecraft:modified_badlands*", + "minecraft:modified_wooded_badlands*", + "minecraft:wooded_badlands*" + ], + "match": [ + [ + "minecraft:ore", + "minecraft:gold_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 9, + "target": "natural_stone", + "state": { + "Name": "minecraft:gold_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 20, + "bottom_offset": 64, + "top_offset": 64, + "maximum": 112 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/iron.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/iron.json new file mode 100644 index 0000000..e324866 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/iron.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:iron_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 9, + "target": "natural_stone", + "state": { + "Name": "minecraft:iron_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 20, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 112 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/lapis.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/lapis.json new file mode 100644 index 0000000..189b069 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/lapis.json @@ -0,0 +1,31 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:lapis_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 7, + "target": "natural_stone", + "state": { + "Name": "minecraft:lapis_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_depth_average", + "config": { + "count": 1, + "baseline": 32, + "spread": 32 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/redstone.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/redstone.json new file mode 100644 index 0000000..55fa194 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/ores/redstone.json @@ -0,0 +1,35 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:redstone_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 8, + "target": "natural_stone", + "state": { + "Name": "minecraft:redstone_ore", + "Properties": { + "lit": "false" + } + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 8, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 64 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/shrubs/dead_bush.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/shrubs/dead_bush.json new file mode 100644 index 0000000..f19f718 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/shrubs/dead_bush.json @@ -0,0 +1,42 @@ +{ + "match": [ + [ + "minecraft:decorated", + "minecraft:dead_bush" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_patch", + "config": { + "state_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:dead_bush" + } + }, + "block_placer": { + "type": "minecraft:simple_block_placer" + }, + "whitelist": [], + "blacklist": [], + "tries": 2, + "xspread": 7, + "yspread": 3, + "zspread": 7, + "can_replace": false, + "project": true, + "need_water": false + } + }, + "decorator": { + "name": "minecraft:count_heightmap_double", + "config": { + "count": 3 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/shrubs/forest_grass.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/shrubs/forest_grass.json new file mode 100644 index 0000000..e6a19e9 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/shrubs/forest_grass.json @@ -0,0 +1,52 @@ +{ + "biomes": [ + "minecraft:birch_forest", + "minecraft:birch_forest_hills", + "minecraft:forest", + "minecraft:forest_hills", + "minecraft:dark_forest", + "minecraft:dark_forest_hills" + ], + "match": [ + [ + "minecraft:decorated", + "minecraft:grass" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_patch", + "config": { + "state_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:grass" + } + }, + "block_placer": { + "type": "minecraft:simple_block_placer" + }, + "whitelist": [], + "blacklist": [], + "tries": 32, + "xspread": 7, + "yspread": 3, + "zspread": 7, + "can_replace": false, + "project": true, + "need_water": false + } + }, + "decorator": { + "name": "minecraft:noise_heightmap_double", + "config": { + "noise_level": -0.8, + "below_noise": 5, + "above_noise": 10 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/acacia.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/acacia.json new file mode 100644 index 0000000..cf5e9ac --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/acacia.json @@ -0,0 +1,42 @@ +{ + "match": [ + [ + "minecraft:acacia_log", + "minecraft:acacia_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:acacia_large", + "config": {}, + "chance": 0.4 + }, + { + "name": "terraforged:acacia_small", + "config": {}, + "chance": 0.15 + } + ], + "default": { + "name": "terraforged:acacia_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 0, + "extra_chance": 0.2, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/birch.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/birch.json new file mode 100644 index 0000000..aa2313d --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/birch.json @@ -0,0 +1,45 @@ +{ + "biomes": [ + "minecraft:birch_forest*" + ], + "match": [ + [ + "minecraft:birch_log", + "minecraft:birch_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:birch_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:birch_large", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:birch_forest", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 21, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/birch_oak.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/birch_oak.json new file mode 100644 index 0000000..e9ffca8 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/birch_oak.json @@ -0,0 +1,57 @@ +{ + "biomes": [ + "minecraft:wooded_hills" + ], + "match": [ + [ + "minecraft:birch_log", + "minecraft:birch_leaves", + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:birch_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:birch_large", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_large", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:birch_forest", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 20, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/dark_oak.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/dark_oak.json new file mode 100644 index 0000000..5c82c0e --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/dark_oak.json @@ -0,0 +1,126 @@ +{ + "biomes": [ + "minecraft:dark_forest", + "minecraft:dark_forest_hills" + ], + "match": [ + [ + "minecraft:dark_oak_log", + "minecraft:dark_oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "minecraft:huge_brown_mushroom", + "config": { + "cap_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:brown_mushroom_block", + "Properties": { + "east": "true", + "south": "true", + "north": "true", + "west": "true", + "up": "true", + "down": "false" + } + } + }, + "stem_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:mushroom_stem", + "Properties": { + "east": "true", + "south": "true", + "north": "true", + "west": "true", + "up": "false", + "down": "false" + } + } + }, + "foliage_radius": 3 + }, + "chance": 0.025 + }, + { + "name": "minecraft:huge_red_mushroom", + "config": { + "cap_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:red_mushroom_block", + "Properties": { + "east": "true", + "south": "true", + "north": "true", + "west": "true", + "up": "true", + "down": "false" + } + } + }, + "stem_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:mushroom_stem", + "Properties": { + "east": "true", + "south": "true", + "north": "true", + "west": "true", + "up": "false", + "down": "false" + } + } + }, + "foliage_radius": 2 + }, + "chance": 0.05 + }, + { + "name": "terraforged:dark_oak_large", + "config": {}, + "chance": 0.3 + }, + { + "name": "terraforged:dark_oak_small", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:birch_forest", + "config": {}, + "chance": 0.05 + }, + { + "name": "terraforged:oak_forest", + "config": {}, + "chance": 0.025 + } + ], + "default": { + "name": "terraforged:dark_oak_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 10, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/jungle.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/jungle.json new file mode 100644 index 0000000..f13ec01 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/jungle.json @@ -0,0 +1,73 @@ +{ + "match": [ + [ + "minecraft:mega_jungle_tree" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:jungle_small", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:jungle_large", + "config": {}, + "chance": 0.3 + }, + { + "name": "terraforged:jungle_huge", + "config": {}, + "chance": 0.4 + }, + { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:jungle_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_leaves", + "Properties": { + "distance": "7", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 4 + }, + "chance": 0.5 + } + ], + "default": { + "name": "terraforged:jungle_small", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 15, + "extra_chance": 0.25, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_badlands.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_badlands.json new file mode 100644 index 0000000..6166a24 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_badlands.json @@ -0,0 +1,43 @@ +{ + "biomes": [ + "minecraft:wooded_badlands*", + "minecraft:shattered_savanna*", + "minecraft:modified_badlands*", + "minecraft:modified_wooded*" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:oak_small", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:oak_small", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 4, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_forest.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_forest.json new file mode 100644 index 0000000..dd1ff71 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_forest.json @@ -0,0 +1,45 @@ +{ + "biomes": [ + "minecraft:forest" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:oak_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_large", + "config": {}, + "chance": 0.3 + } + ], + "default": { + "name": "terraforged:oak_forest", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 10, + "extra_chance": 0.1, + "extra_count": 2 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_plains.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_plains.json new file mode 100644 index 0000000..da7e09d --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/oak_plains.json @@ -0,0 +1,46 @@ +{ + "biomes": [ + "minecraft:plains", + "minecraft:flower_forest" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:oak_huge", + "config": {}, + "chance": 0.1 + }, + { + "name": "terraforged:oak_small", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:oak_small", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 0, + "extra_chance": 0.02, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/pine.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/pine.json new file mode 100644 index 0000000..e3b26b3 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/pine.json @@ -0,0 +1,44 @@ +{ + "biomes": [ + "minecraft:taiga", + "minecraft:taiga_hills", + "minecraft:taiga_mountains", + "minecraft:taiga_scrub" + ], + "match": [ + [ + "minecraft:normal_tree", + "minecraft:spruce_log", + "minecraft:spruce_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:pine", + "config": {}, + "chance": 0.3 + } + ], + "default": { + "name": "terraforged:pine", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 8, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/redwood.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/redwood.json new file mode 100644 index 0000000..69f0998 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/redwood.json @@ -0,0 +1,46 @@ +{ + "match": [ + [ + "minecraft:mega_spruce_tree" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:redwood_huge", + "config": {}, + "chance": 0.025641026 + }, + { + "name": "terraforged:pine", + "config": {}, + "chance": 0.15 + }, + { + "name": "terraforged:redwood_large", + "config": {}, + "chance": 0.33333334 + } + ], + "default": { + "name": "terraforged:redwood_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 10, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/spruce.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/spruce.json new file mode 100644 index 0000000..f145636 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/spruce.json @@ -0,0 +1,46 @@ +{ + "biomes": [ + "minecraft:snowy_taiga", + "minecraft:snowy_taiga_hills", + "minecraft:snowy_taiga_mountains", + "minecraft:snowy_taiga_scrub", + "minecraft:snowy_tundra", + "minecraft:wooded_mountains" + ], + "match": [ + [ + "minecraft:normal_tree", + "minecraft:spruce_log", + "minecraft:spruce_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:pine", + "config": {}, + "chance": 0.3 + } + ], + "default": { + "name": "terraforged:pine", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 8, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/willow.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/willow.json new file mode 100644 index 0000000..ba31490 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/features/trees/willow.json @@ -0,0 +1,48 @@ +{ + "action": "replace", + "biomes": [ + "minecraft:swamp", + "minecraft:swamp_hills" + ], + "match": [ + [ + "minecraft:normal_tree", + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:willow_small", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:willow_large", + "config": {}, + "chance": 0.35 + } + ], + "default": { + "name": "terraforged:willow_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 8, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_1.nbt new file mode 100644 index 0000000..d6dc4ac Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_2.nbt new file mode 100644 index 0000000..d6dc4ac Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_1.nbt new file mode 100644 index 0000000..17e91d1 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_2.nbt new file mode 100644 index 0000000..c80c016 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_1.nbt new file mode 100644 index 0000000..de1dc6d Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_2.nbt new file mode 100644 index 0000000..fbfe087 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_1.nbt new file mode 100644 index 0000000..a207f2e Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_2.nbt new file mode 100644 index 0000000..e20cd28 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_3.nbt new file mode 100644 index 0000000..e14b0e1 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_4.nbt new file mode 100644 index 0000000..03675e3 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_1.nbt new file mode 100644 index 0000000..3ecd569 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_2.nbt new file mode 100644 index 0000000..a729f97 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_3.nbt new file mode 100644 index 0000000..28c32ab Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/large/birch_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_1.nbt new file mode 100644 index 0000000..7d6a7e5 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_2.nbt new file mode 100644 index 0000000..680adee Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_1.nbt new file mode 100644 index 0000000..6499e1c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_2.nbt new file mode 100644 index 0000000..559a1b0 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_1.nbt new file mode 100644 index 0000000..b0dced8 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_2.nbt new file mode 100644 index 0000000..bcd2635 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_3.nbt new file mode 100644 index 0000000..3d5c4a8 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_4.nbt new file mode 100644 index 0000000..f7a72fc Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_5.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_5.nbt new file mode 100644 index 0000000..a20faf1 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_5.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_1.nbt new file mode 100644 index 0000000..f4cefe7 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_2.nbt new file mode 100644 index 0000000..aca73e6 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_3.nbt new file mode 100644 index 0000000..e271a5d Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_1.nbt new file mode 100644 index 0000000..4c39cfd Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_2.nbt new file mode 100644 index 0000000..9202c79 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_1.nbt new file mode 100644 index 0000000..533df04 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_2.nbt new file mode 100644 index 0000000..0b86d6b Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_3.nbt new file mode 100644 index 0000000..31b9186 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_4.nbt new file mode 100644 index 0000000..eb1f0f2 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_5.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_5.nbt new file mode 100644 index 0000000..ac2da9d Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_5.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_6.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_6.nbt new file mode 100644 index 0000000..398d72c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_6.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_1.nbt new file mode 100644 index 0000000..6f0516a Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_2.nbt new file mode 100644 index 0000000..76ff007 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_3.nbt new file mode 100644 index 0000000..ca3719c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_4.nbt new file mode 100644 index 0000000..cc3a06f Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_1.nbt new file mode 100644 index 0000000..37c90f7 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_2.nbt new file mode 100644 index 0000000..eae5e04 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_3.nbt new file mode 100644 index 0000000..14dc95b Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_1.nbt new file mode 100644 index 0000000..2e0d9de Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_2.nbt new file mode 100644 index 0000000..c044495 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_1.nbt new file mode 100644 index 0000000..7f40e0b Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_2.nbt new file mode 100644 index 0000000..63982e3 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_1.nbt new file mode 100644 index 0000000..aecb79c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_2.nbt new file mode 100644 index 0000000..aecb79c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_3.nbt new file mode 100644 index 0000000..fb741e8 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_4.nbt new file mode 100644 index 0000000..8dccea0 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_5.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_5.nbt new file mode 100644 index 0000000..0d95ab0 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/large/oak_5.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_1.nbt new file mode 100644 index 0000000..66cd106 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_2.nbt new file mode 100644 index 0000000..e5e5f52 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_1.nbt new file mode 100644 index 0000000..39338cb Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_2.nbt new file mode 100644 index 0000000..441a181 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_3.nbt new file mode 100644 index 0000000..5788941 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_4.nbt new file mode 100644 index 0000000..31e8968 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_1.nbt new file mode 100644 index 0000000..873740e Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_2.nbt new file mode 100644 index 0000000..cbfaff2 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_3.nbt new file mode 100644 index 0000000..53d7c1b Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_1.nbt new file mode 100644 index 0000000..ae5ee8c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_2.nbt new file mode 100644 index 0000000..1f8c56c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_1.nbt new file mode 100644 index 0000000..19f44b4 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_2.nbt new file mode 100644 index 0000000..dcd6a0c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_1.nbt new file mode 100644 index 0000000..8e59f5c Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_2.nbt new file mode 100644 index 0000000..e952b2a Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_1.nbt new file mode 100644 index 0000000..d261f77 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_2.nbt new file mode 100644 index 0000000..35f97ba Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_3.nbt new file mode 100644 index 0000000..438ed8f Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_4.nbt new file mode 100644 index 0000000..1b8af9b Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_5.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_5.nbt new file mode 100644 index 0000000..b405fc5 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_5.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_6.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_6.nbt new file mode 100644 index 0000000..d12955d Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_6.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_1.nbt new file mode 100644 index 0000000..f662868 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_2.nbt new file mode 100644 index 0000000..afa43f1 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_3.nbt new file mode 100644 index 0000000..abaaa84 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_4.nbt new file mode 100644 index 0000000..a9b8c42 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_1.nbt new file mode 100644 index 0000000..5ec0972 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_2.nbt new file mode 100644 index 0000000..3e43aa5 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_1.nbt new file mode 100644 index 0000000..f98ae16 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_2.nbt new file mode 100644 index 0000000..195d494 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_3.nbt new file mode 100644 index 0000000..afa1449 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_4.nbt new file mode 100644 index 0000000..ecd2945 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_5.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_5.nbt new file mode 100644 index 0000000..4521bd6 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_5.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_1.nbt new file mode 100644 index 0000000..2a8ba15 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_2.nbt new file mode 100644 index 0000000..195d494 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_3.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_3.nbt new file mode 100644 index 0000000..e2b27f8 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_3.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_4.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_4.nbt new file mode 100644 index 0000000..9a1f793 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_4.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_1.nbt new file mode 100644 index 0000000..9ca0260 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_2.nbt new file mode 100644 index 0000000..b5852e6 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_1.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_1.nbt new file mode 100644 index 0000000..5066472 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_1.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_2.nbt b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_2.nbt new file mode 100644 index 0000000..5434dd9 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_2.nbt differ diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/alpine.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/alpine.json new file mode 100644 index 0000000..3c7bc00 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/alpine.json @@ -0,0 +1,12 @@ +{ + "replaceable": false, + "values": [ + "minecraft:gravelly_mountains", + "minecraft:modified_gravelly_mountains", + "minecraft:mountains", + "minecraft:snowy_mountains", + "minecraft:snowy_taiga_mountains", + "minecraft:taiga_mountains", + "minecraft:wooded_mountains" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/cold_steppe.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/cold_steppe.json new file mode 100644 index 0000000..7078779 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/cold_steppe.json @@ -0,0 +1,6 @@ +{ + "replaceable": false, + "values": [ + "terraforged:cold_steppe" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/desert.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/desert.json new file mode 100644 index 0000000..d05ad84 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/desert.json @@ -0,0 +1,14 @@ +{ + "replaceable": false, + "values": [ + "minecraft:badlands", + "minecraft:badlands_plateau", + "minecraft:desert", + "minecraft:desert_hills", + "minecraft:desert_lakes", + "minecraft:eroded_badlands", + "minecraft:modified_badlands_plateau", + "minecraft:modified_wooded_badlands_plateau", + "minecraft:wooded_badlands_plateau" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/grassland.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/grassland.json new file mode 100644 index 0000000..e8aa379 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/grassland.json @@ -0,0 +1,7 @@ +{ + "replaceable": false, + "values": [ + "minecraft:plains", + "minecraft:sunflower_plains" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/savanna.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/savanna.json new file mode 100644 index 0000000..4e2b39f --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/savanna.json @@ -0,0 +1,11 @@ +{ + "replaceable": false, + "values": [ + "minecraft:savanna", + "minecraft:savanna_plateau", + "minecraft:shattered_savanna", + "minecraft:shattered_savanna_plateau", + "terraforged:savanna_scrub", + "terraforged:shattered_savanna_scrub" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/steppe.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/steppe.json new file mode 100644 index 0000000..1652fec --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/steppe.json @@ -0,0 +1,6 @@ +{ + "replaceable": false, + "values": [ + "terraforged:steppe" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/taiga.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/taiga.json new file mode 100644 index 0000000..5068d33 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/taiga.json @@ -0,0 +1,11 @@ +{ + "replaceable": false, + "values": [ + "minecraft:giant_spruce_taiga", + "minecraft:giant_tree_taiga", + "minecraft:giant_tree_taiga_hills", + "minecraft:taiga", + "minecraft:taiga_hills", + "terraforged:taiga_scrub" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/temperate_forest.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/temperate_forest.json new file mode 100644 index 0000000..3733c1b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/temperate_forest.json @@ -0,0 +1,13 @@ +{ + "replaceable": false, + "values": [ + "minecraft:birch_forest", + "minecraft:birch_forest_hills", + "minecraft:dark_forest", + "minecraft:flower_forest", + "minecraft:forest", + "minecraft:plains", + "minecraft:tall_birch_forest", + "minecraft:wooded_hills" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/temperate_rainforest.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/temperate_rainforest.json new file mode 100644 index 0000000..37aae65 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/temperate_rainforest.json @@ -0,0 +1,10 @@ +{ + "replaceable": false, + "values": [ + "minecraft:dark_forest", + "minecraft:flower_forest", + "minecraft:forest", + "minecraft:plains", + "minecraft:wooded_hills" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/tropical_rainforest.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/tropical_rainforest.json new file mode 100644 index 0000000..2150999 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/tropical_rainforest.json @@ -0,0 +1,10 @@ +{ + "replaceable": false, + "values": [ + "minecraft:bamboo_jungle", + "minecraft:bamboo_jungle_hills", + "minecraft:jungle", + "minecraft:jungle_hills", + "minecraft:modified_jungle" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/tundra.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/tundra.json new file mode 100644 index 0000000..14046ad --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/biomes/tundra.json @@ -0,0 +1,10 @@ +{ + "replaceable": false, + "values": [ + "minecraft:ice_spikes", + "minecraft:snowy_taiga", + "minecraft:snowy_taiga_hills", + "minecraft:snowy_tundra", + "terraforged:snowy_taiga_scrub" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/clay.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/clay.json new file mode 100644 index 0000000..3dd193a --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/clay.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:clay" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/earth.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/earth.json new file mode 100644 index 0000000..7e53f69 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/earth.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:dirt", + "minecraft:coarse_dirt" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/erodible.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/erodible.json new file mode 100644 index 0000000..8d79529 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/erodible.json @@ -0,0 +1,10 @@ +{ + "replace": false, + "values": [ + "minecraft:dirt", + "minecraft:grass_block", + "minecraft:mycelium", + "minecraft:coarse_dirt", + "minecraft:podzol" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/ore.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/ore.json new file mode 100644 index 0000000..59fe3e2 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/ore.json @@ -0,0 +1,12 @@ +{ + "replace": false, + "values": [ + "minecraft:lapis_ore", + "minecraft:diamond_ore", + "minecraft:coal_ore", + "minecraft:emerald_ore", + "minecraft:gold_ore", + "minecraft:redstone_ore", + "minecraft:iron_ore" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/rock.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/rock.json new file mode 100644 index 0000000..e965f64 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/rock.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "values": [ + "minecraft:granite", + "minecraft:andesite", + "minecraft:stone", + "minecraft:diorite" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/sediment.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/sediment.json new file mode 100644 index 0000000..f605778 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/tags/blocks/sediment.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "minecraft:sand", + "minecraft:gravel", + "minecraft:red_sand" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/acacia_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/acacia_large.json new file mode 100644 index 0000000..3d3c39b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/acacia_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:acacia_large", + "paths": [ + "terraforged:trees/acacia/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/acacia_small.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/acacia_small.json new file mode 100644 index 0000000..7fd1cab --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/acacia_small.json @@ -0,0 +1,9 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:acacia_small", + "paths": [ + "terraforged:trees/acacia/small", + "terraforged:trees/acacia/bush" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_forest.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_forest.json new file mode 100644 index 0000000..8e2334f --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_forest.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:birch_forest", + "paths": [ + "terraforged:trees/birch/forest" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_large.json new file mode 100644 index 0000000..517da81 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_large.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:birch_large", + "paths": [ + "terraforged:trees/birch/large" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_small.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_small.json new file mode 100644 index 0000000..285f490 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/birch_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:birch_small", + "paths": [ + "terraforged:trees/birch/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/dark_oak_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/dark_oak_large.json new file mode 100644 index 0000000..0d08afb --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/dark_oak_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:dark_oak_large", + "paths": [ + "terraforged:trees/dark_oak/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/dark_oak_small.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/dark_oak_small.json new file mode 100644 index 0000000..1cab783 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/dark_oak_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:dark_oak_small", + "paths": [ + "terraforged:trees/dark_oak/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_huge.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_huge.json new file mode 100644 index 0000000..9966e5b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_huge.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:jungle_huge", + "paths": [ + "terraforged:trees/jungle/huge" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_large.json new file mode 100644 index 0000000..2158117 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:jungle_large", + "paths": [ + "terraforged:trees/jungle/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_small.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_small.json new file mode 100644 index 0000000..c242c73 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/jungle_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:jungle_small", + "paths": [ + "terraforged:trees/jungle/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_forest.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_forest.json new file mode 100644 index 0000000..eacbf1f --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_forest.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_forest", + "paths": [ + "terraforged:trees/oak/forest" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_huge.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_huge.json new file mode 100644 index 0000000..15704e9 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_huge.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_huge", + "paths": [ + "terraforged:trees/oak/huge" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_large.json new file mode 100644 index 0000000..dd11f3e --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_large.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_large", + "paths": [ + "terraforged:trees/oak/large" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_small.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_small.json new file mode 100644 index 0000000..cbb9289 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/oak_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_small", + "paths": [ + "terraforged:trees/oak/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/pine.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/pine.json new file mode 100644 index 0000000..8ec0f47 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/pine.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:pine", + "paths": [ + "terraforged:trees/pine" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/redwood_huge.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/redwood_huge.json new file mode 100644 index 0000000..f84b835 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/redwood_huge.json @@ -0,0 +1,21 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:redwood_huge", + "paths": [ + "terraforged:trees/redwood/huge" + ], + "decorators": { + "minecraft:alter_ground": { + "provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:podzol", + "Properties": { + "snowy": "false" + } + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/redwood_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/redwood_large.json new file mode 100644 index 0000000..c9c829c --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/redwood_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:redwood_large", + "paths": [ + "terraforged:trees/redwood/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/spruce_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/spruce_large.json new file mode 100644 index 0000000..4738b7b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/spruce_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:spruce_large", + "paths": [ + "terraforged:trees/spruce/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/spruce_small.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/spruce_small.json new file mode 100644 index 0000000..1e0c950 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/spruce_small.json @@ -0,0 +1,9 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:spruce_small", + "paths": [ + "terraforged:trees/spruce/small", + "terraforged:trees/spruce/bush" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/willow_large.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/willow_large.json new file mode 100644 index 0000000..467ae54 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/willow_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:willow_large", + "paths": [ + "terraforged:trees/willow/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/willow_small.json b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/willow_small.json new file mode 100644 index 0000000..1de4946 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/data/terraforged/templates/trees/willow_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:willow_small", + "paths": [ + "terraforged:trees/willow/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod-fabric/src/main/resources/fabric.mod.json b/TerraForgedMod-fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..65db226 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "id": "terraforged", + "version": "${version}", + + "name": "TerraForged", + "description": "A terrain generator attempting to create more immersive, inspiring worlds to explore and build in!", + "authors": [ + "dags" + ], + "contact": { + "homepage": "https://terraforged.com", + "issues": "https://github.com/TerraForged/TerraForged/issues", + "sources": "https://github.com/TerraForged/TerraForged" + }, + + "license": "MIT", + "icon": "terraforged.png", + + "environment": "*", + "entrypoints": { + "main": [ + "com.terraforged.mod.TerraForgedMod" + ], + "server": [ + "com.terraforged.mod.TerraForgedMod::server" + ] + }, + "mixins": [ + "modid.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "minecraft": "1.15.x" + } +} diff --git a/TerraForgedMod-fabric/src/main/resources/license.txt b/TerraForgedMod-fabric/src/main/resources/license.txt new file mode 100644 index 0000000..0b31935 --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 TerraForged + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/TerraForgedMod-fabric/src/main/resources/pack.mcmeta b/TerraForgedMod-fabric/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..b11415b --- /dev/null +++ b/TerraForgedMod-fabric/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "TerraForged resources", + "pack_format": 5 + } +} diff --git a/TerraForgedMod-fabric/src/main/resources/terraforged.png b/TerraForgedMod-fabric/src/main/resources/terraforged.png new file mode 100644 index 0000000..0d649c9 Binary files /dev/null and b/TerraForgedMod-fabric/src/main/resources/terraforged.png differ diff --git a/gradle.properties b/gradle.properties index eb85b78..1b61cdf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,5 +3,8 @@ mc_version=1.15.2 forge_version=31.1.1 mcp_channel=snapshot mcp_version=20200225-1.15.1 +yarn_build=14 +fabric_loader_version=0.7.8+build.187 +fabric_api_version=0.5.0+build.293-1.15 org.gradle.jvmargs=-Xmx4G org.gradle.daemon=false \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 5e95ef4..c5f0b21 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,10 @@ rootProject.name = "TerraForged" include ":Noise2D" -include ":TerraForgedMod" -include ":TerraForgedAPI" +//include ":TerraForgedMod" +include ":TerraForgedMod-fabric" +//include ":TerraForgedAPI" +include ":TerraForgedAPI-fabric" include ":TerraForgedCore" -include ":FeatureManager" -include ":TerraForgedApp" \ No newline at end of file +//include ":FeatureManager" +include ":FeatureManager-fabric" +include ":TerraForgedApp"