- rewrite BiomeMap
- tweaks to features jsons - forest surface builder - fix unsorted material lists for the strata layer generator
This commit is contained in:
parent
adfcc8b382
commit
3043540791
2
Engine
2
Engine
@ -1 +1 @@
|
||||
Subproject commit 97f83a296a351af688a5f35494b943c0b2b141ae
|
||||
Subproject commit 433db368f37a8f0a538d017610ce5cb11487d7fe
|
@ -39,13 +39,6 @@ public class SurfaceManager {
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private final Map<ResourceLocation, Surface> surfaces = new HashMap<>();
|
||||
|
||||
public SurfaceManager replace(Biome biome, Surface surface) {
|
||||
lock.writeLock().lock();
|
||||
surfaces.put(biome.getRegistryName(), surface);
|
||||
lock.writeLock().unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Surface getSurface(Biome biome) {
|
||||
lock.readLock().lock();
|
||||
Surface surface = surfaces.get(biome.getRegistryName());
|
||||
@ -62,11 +55,44 @@ public class SurfaceManager {
|
||||
return surface;
|
||||
}
|
||||
|
||||
public SurfaceManager extend(Biome biome, Surface surface) {
|
||||
public SurfaceManager replace(Biome biome, Surface surface) {
|
||||
lock.writeLock().lock();
|
||||
surfaces.put(biome.getRegistryName(), surface);
|
||||
lock.writeLock().unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
public SurfaceManager replace(Surface surface, Biome... biomes) {
|
||||
for (Biome biome : biomes) {
|
||||
replace(biome, surface);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SurfaceManager prepend(Biome biome, Surface surface) {
|
||||
Surface result = surface.then(getOrCreateSurface(biome));
|
||||
return replace(biome, result);
|
||||
}
|
||||
|
||||
public SurfaceManager prepend(Surface surface, Biome... biomes) {
|
||||
for (Biome biome : biomes) {
|
||||
prepend(biome, surface);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SurfaceManager append(Biome biome, Surface surface) {
|
||||
Surface result = getOrCreateSurface(biome).then(surface);
|
||||
return replace(biome, result);
|
||||
}
|
||||
|
||||
public SurfaceManager append(Surface surface, Biome... biomes) {
|
||||
for (Biome biome : biomes) {
|
||||
append(biome, surface);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Surface getSurface(SurfaceContext context) {
|
||||
if (context.biome == context.cached.biome) {
|
||||
return context.cached.surface;
|
||||
|
@ -1,53 +0,0 @@
|
||||
package com.terraforged.biome;
|
||||
|
||||
import com.terraforged.api.biome.BiomeVariant;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
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.Feature;
|
||||
import net.minecraft.world.gen.feature.IFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.structure.MineshaftConfig;
|
||||
import net.minecraft.world.gen.feature.structure.MineshaftStructure;
|
||||
import net.minecraft.world.gen.feature.structure.VillageConfig;
|
||||
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
|
||||
|
||||
public class Dunes extends BiomeVariant {
|
||||
|
||||
protected Dunes() {
|
||||
super((new Biome.Builder()).surfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.SAND_SAND_GRAVEL_CONFIG).precipitation(Biome.RainType.NONE).category(Biome.Category.DESERT).depth(0.125F).scale(0.05F).temperature(2.0F).downfall(0.0F).waterColor(4159204).waterFogColor(329011).parent((String)null));
|
||||
this.addStructure(Feature.VILLAGE.withConfiguration(new VillageConfig("village/desert/town_centers", 6)));
|
||||
this.addStructure(Feature.PILLAGER_OUTPOST.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG));
|
||||
this.addStructure(Feature.DESERT_PYRAMID.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG));
|
||||
this.addStructure(Feature.MINESHAFT.withConfiguration(new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL)));
|
||||
this.addStructure(Feature.STRONGHOLD.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG));
|
||||
DefaultBiomeFeatures.addCarvers(this);
|
||||
DefaultBiomeFeatures.addStructures(this);
|
||||
DefaultBiomeFeatures.addMonsterRooms(this);
|
||||
DefaultBiomeFeatures.addStoneVariants(this);
|
||||
DefaultBiomeFeatures.addOres(this);
|
||||
DefaultBiomeFeatures.addDefaultFlowers(this);
|
||||
DefaultBiomeFeatures.addSparseGrass(this);
|
||||
DefaultBiomeFeatures.addDeadBushes(this);
|
||||
DefaultBiomeFeatures.addMushrooms(this);
|
||||
DefaultBiomeFeatures.addFreezeTopLayer(this);
|
||||
this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.RABBIT, 4, 2, 3));
|
||||
this.addSpawn(EntityClassification.AMBIENT, new Biome.SpawnListEntry(EntityType.BAT, 10, 8, 8));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SPIDER, 100, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SKELETON, 100, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.CREEPER, 100, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SLIME, 100, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.WITCH, 5, 1, 1));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE, 19, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 1, 1, 1));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.HUSK, 80, 4, 4));
|
||||
setRegistryName("terraforged", "dunes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBase() {
|
||||
return Biomes.DESERT;
|
||||
}
|
||||
}
|
@ -41,7 +41,6 @@ public class ModBiomes {
|
||||
|
||||
public static final Biome BRICE = register(new Brice());
|
||||
public static final Biome COLD_STEPPE = register(new ColdSteppe());
|
||||
public static final Biome DUNES = register(new Dunes());
|
||||
public static final Biome FIR_FOREST = register(new FirForest());
|
||||
public static final Biome FLOWER_PLAINS = register(new FlowerPlains());
|
||||
public static final Biome FROZEN_LAKE = register(new FrozenLake());
|
||||
|
@ -1,235 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.biome.map;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.terraforged.biome.ModBiomes;
|
||||
import com.terraforged.biome.provider.BiomeHelper;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
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[][] lake;
|
||||
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 defaultLake = this::defaultLake;
|
||||
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();
|
||||
lake = builder.lakes();
|
||||
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 getLake(float temperature, float moisture, float shape) {
|
||||
return get(lake, getCategory(temperature), shape, temperature, defaultLake);
|
||||
}
|
||||
|
||||
@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<Biome> getOceanBiomes(Biome.TempCategory temp) {
|
||||
return Sets.newHashSet(ocean[temp.ordinal() - 1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Biome> getDeepOceanBiomes(Biome.TempCategory temp) {
|
||||
return Sets.newHashSet(deepOcean[temp.ordinal() - 1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Biome> getRivers(Biome.TempCategory 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.TempCategory temp : Biome.TempCategory.values()) {
|
||||
if (temp == Biome.TempCategory.OCEAN) {
|
||||
continue;
|
||||
}
|
||||
JsonArray array = new JsonArray();
|
||||
Biome[] group = biomes[temp.ordinal() - 1];
|
||||
if (group != null) {
|
||||
Set<Biome> 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.TempCategory getCategory(float value) {
|
||||
if (value < 0.25) {
|
||||
return Biome.TempCategory.COLD;
|
||||
}
|
||||
if (value > 0.75) {
|
||||
return Biome.TempCategory.WARM;
|
||||
}
|
||||
return Biome.TempCategory.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 defaultLake(float temperature) {
|
||||
if (temperature < 0.15) {
|
||||
return ModBiomes.FROZEN_LAKE;
|
||||
}
|
||||
return ModBiomes.LAKE;
|
||||
}
|
||||
|
||||
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.TempCategory 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];
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.biome.map;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.terraforged.biome.provider.BiomeHelper;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
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<Biome> getAllBiomes(BiomeType type) {
|
||||
if (type.ordinal() >= biomeTypes.length) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(biomeTypes[type.ordinal()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Biome> 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;
|
||||
}
|
||||
}
|
@ -28,60 +28,50 @@ package com.terraforged.biome.map;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
import com.terraforged.world.heightmap.Levels;
|
||||
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 getBeach(Cell cell);
|
||||
|
||||
Biome getRiver(float temperature, float moisture, float shape);
|
||||
Biome getCoast(Cell cell, Biome current);
|
||||
|
||||
Biome getLake(float temperature, float moisture, float shape);
|
||||
Biome getRiver(Cell cell);
|
||||
|
||||
Biome getWetland(float temperature, float moisture, float shape);
|
||||
Biome getLake(Cell cell);
|
||||
|
||||
Biome getOcean(float temperature, float moisture, float shape);
|
||||
Biome getWetland(Cell cell);
|
||||
|
||||
Biome getDeepOcean(float temperature, float moisture, float shape);
|
||||
Biome getShallowOcean(Cell cell);
|
||||
|
||||
Biome getBiome(BiomeType type, float temperature, float moisture, float shape);
|
||||
Biome getDeepOcean(Cell cell);
|
||||
|
||||
default Biome getBiome(Cell cell) {
|
||||
return getBiome(cell.biomeType, cell.temperature, cell.moisture, cell.biome);
|
||||
}
|
||||
Biome getLand(Cell cell);
|
||||
|
||||
Biome provideBiome(Cell cell, Levels levels);
|
||||
|
||||
List<Biome> getAllBiomes(BiomeType type);
|
||||
|
||||
Set<Biome> getBiomes(BiomeType type);
|
||||
|
||||
Set<Biome> getRivers(Biome.TempCategory temp);
|
||||
|
||||
Set<Biome> getOceanBiomes(Biome.TempCategory temp);
|
||||
|
||||
Set<Biome> getDeepOceanBiomes(Biome.TempCategory temp);
|
||||
|
||||
JsonElement toJson();
|
||||
|
||||
static Biome getBiome(Biome biome) {
|
||||
return biome.delegate.get();
|
||||
}
|
||||
|
||||
interface Builder {
|
||||
|
||||
Builder addOcean(Biome biome, int count);
|
||||
|
||||
Builder addBeach(Biome biome, int count);
|
||||
|
||||
Builder addCoast(Biome biome, int count);
|
||||
|
||||
Builder addRiver(Biome biome, int count);
|
||||
|
||||
Builder addLake(Biome biome, int count);
|
||||
|
||||
Builder addWetland(Biome biome, int count);
|
||||
|
||||
Builder addOcean(Biome biome, int count);
|
||||
|
||||
Builder addBiome(BiomeType type, Biome biome, int count);
|
||||
Builder addLand(BiomeType type, Biome biome, int count);
|
||||
|
||||
BiomeMap build();
|
||||
}
|
||||
|
@ -26,15 +26,10 @@
|
||||
package com.terraforged.biome.map;
|
||||
|
||||
import com.terraforged.biome.provider.BiomeHelper;
|
||||
import com.terraforged.core.util.grid.FixedGrid;
|
||||
import com.terraforged.util.ListUtils;
|
||||
import com.terraforged.world.biome.BiomeData;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
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;
|
||||
@ -43,25 +38,19 @@ import java.util.function.Function;
|
||||
|
||||
public class BiomeMapBuilder implements BiomeMap.Builder {
|
||||
|
||||
private final Map<Biome.TempCategory, List<Biome>> rivers = new HashMap<>();
|
||||
private final Map<Biome.TempCategory, List<Biome>> lakes = new HashMap<>();
|
||||
private final Map<Biome.TempCategory, List<Biome>> wetlands = new HashMap<>();
|
||||
private final Map<Biome.TempCategory, List<Biome>> beaches = new HashMap<>();
|
||||
private final Map<Biome.TempCategory, List<Biome>> oceans = new HashMap<>();
|
||||
private final Map<Biome.TempCategory, List<Biome>> deepOceans = new HashMap<>();
|
||||
private final Map<BiomeType, List<Biome>> map = new EnumMap<>(BiomeType.class);
|
||||
private final Map<Biome, BiomeData> dataMap = new HashMap<>();
|
||||
protected final Map<Biome.TempCategory, List<Biome>> rivers = new HashMap<>();
|
||||
protected final Map<Biome.TempCategory, List<Biome>> lakes = new HashMap<>();
|
||||
protected final Map<Biome.TempCategory, List<Biome>> wetlands = new HashMap<>();
|
||||
protected final Map<Biome.TempCategory, List<Biome>> coasts = new HashMap<>();
|
||||
protected final Map<Biome.TempCategory, List<Biome>> beaches = new HashMap<>();
|
||||
protected final Map<Biome.TempCategory, List<Biome>> oceans = new HashMap<>();
|
||||
protected final Map<Biome.TempCategory, List<Biome>> deepOceans = new HashMap<>();
|
||||
protected final Map<BiomeType, List<Biome>> map = new EnumMap<>(BiomeType.class);
|
||||
|
||||
private final int gridSize;
|
||||
private final Function<BiomeMapBuilder, BiomeMap> constructor;
|
||||
|
||||
BiomeMapBuilder(Function<BiomeMapBuilder, BiomeMap> constructor, int gridSize, List<BiomeData> biomes) {
|
||||
BiomeMapBuilder(Function<BiomeMapBuilder, BiomeMap> constructor) {
|
||||
this.constructor = constructor;
|
||||
this.gridSize = gridSize;
|
||||
|
||||
for (BiomeData data : biomes) {
|
||||
dataMap.put((Biome) data.reference, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,6 +71,13 @@ public class BiomeMapBuilder implements BiomeMap.Builder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeMap.Builder addCoast(Biome biome, int count) {
|
||||
Biome.TempCategory category = BiomeHelper.getTempCategory(biome);
|
||||
add(coasts.computeIfAbsent(category, c -> new ArrayList<>()), biome, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeMapBuilder addRiver(Biome biome, int count) {
|
||||
Biome.TempCategory category = BiomeHelper.getTempCategory(biome);
|
||||
@ -104,7 +100,7 @@ public class BiomeMapBuilder implements BiomeMap.Builder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeMapBuilder addBiome(BiomeType type, Biome biome, int count) {
|
||||
public BiomeMapBuilder addLand(BiomeType type, Biome biome, int count) {
|
||||
add(map.computeIfAbsent(type, t -> new ArrayList<>()), biome, count);
|
||||
return this;
|
||||
}
|
||||
@ -114,87 +110,13 @@ public class BiomeMapBuilder implements BiomeMap.Builder {
|
||||
return constructor.apply(this);
|
||||
}
|
||||
|
||||
Biome[][] rivers() {
|
||||
return collectTemps(rivers);
|
||||
}
|
||||
|
||||
Biome[][] lakes() {
|
||||
return collectTemps(lakes);
|
||||
}
|
||||
|
||||
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<Biome, Float> moisture = b -> dataMap.get(b).rainfall;
|
||||
Function<Biome, Float> temperature = b -> dataMap.get(b).temperature;
|
||||
for (BiomeType type : BiomeType.values()) {
|
||||
List<Biome> list = map.getOrDefault(type, Collections.emptyList());
|
||||
if (list.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
FixedGrid<Biome> grid = FixedGrid.generate(gridSize, list, moisture, temperature);
|
||||
biomes[type.ordinal()] = new BiomeGroup(grid);
|
||||
}
|
||||
|
||||
return biomes;
|
||||
}
|
||||
|
||||
private void add(List<Biome> list, Biome biome, int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
list.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
private Biome[][] collectTemps(Map<Biome.TempCategory, List<Biome>> map) {
|
||||
Biome[][] biomes = new Biome[3][];
|
||||
for (Biome.TempCategory category : Biome.TempCategory.values()) {
|
||||
if (category == Biome.TempCategory.OCEAN) {
|
||||
continue;
|
||||
}
|
||||
List<Biome> 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<BiomeType, List<Biome>> map) {
|
||||
Biome[][] biomes = new Biome[BiomeType.values().length][];
|
||||
for (BiomeType type : BiomeType.values()) {
|
||||
List<Biome> 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<BiomeData> biomes) {
|
||||
return new BiomeMapBuilder(BasicBiomeMap::new, 0, biomes);
|
||||
}
|
||||
|
||||
public static BiomeMap.Builder grid(int size, List<BiomeData> biomes) {
|
||||
return new BiomeMapBuilder(GridBiomeMap::new, size, biomes);
|
||||
public static BiomeMap.Builder create() {
|
||||
return new BiomeMapBuilder(SimpleBiomeMap::new);
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,8 @@ public interface BiomePredicate {
|
||||
return false;
|
||||
}
|
||||
|
||||
BiomePredicate COAST = type(Biome.Category.BEACH, Biome.Category.MUSHROOM).or(name("shore")).or(name("beach"));
|
||||
BiomePredicate BEACH = type(Biome.Category.BEACH).or(name("beach"));
|
||||
BiomePredicate COAST = type(Biome.Category.MUSHROOM).or(name("coast"));
|
||||
BiomePredicate COLD_STEPPE = name("steppe").and(temp(-1, 0.3));
|
||||
BiomePredicate DESERT = type(Biome.Category.DESERT).or(temp(0.9, 2).and(rain(-1, 0.2)));
|
||||
BiomePredicate GRASSLAND = type(Biome.Category.PLAINS);
|
||||
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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.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.world.biome.BiomeType;
|
||||
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<Biome> getAllBiomes(BiomeType type) {
|
||||
BiomeGroup group = biomeTypes[type.ordinal()];
|
||||
if (group == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Biome> biomes = new LinkedList<>();
|
||||
for (MappedList<FixedList<Biome>> row : group.biomes) {
|
||||
for (FixedList<Biome> cell : row) {
|
||||
for (Biome biome : cell) {
|
||||
biomes.add(biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
return biomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Biome> getBiomes(BiomeType type) {
|
||||
BiomeGroup group = biomeTypes[type.ordinal()];
|
||||
if (group == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<Biome> biomes = new HashSet<>();
|
||||
for (MappedList<FixedList<Biome>> row : group.biomes) {
|
||||
for (FixedList<Biome> 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<FixedList<Biome>> row : group.biomes) {
|
||||
int colCount = 0;
|
||||
float maxCol = row.size() - 1;
|
||||
|
||||
JsonObject rowJson = new JsonObject();
|
||||
for (FixedList<Biome> cell : row) {
|
||||
JsonArray colJson = new JsonArray();
|
||||
for (Biome biome : cell.uniqueValues()) {
|
||||
colJson.add(biome.getRegistryName() + "");
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
132
src/main/java/com/terraforged/biome/map/SimpleBiomeMap.java
Normal file
132
src/main/java/com/terraforged/biome/map/SimpleBiomeMap.java
Normal file
@ -0,0 +1,132 @@
|
||||
package com.terraforged.biome.map;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.terraforged.biome.map.defaults.DefaultBiomes;
|
||||
import com.terraforged.biome.map.set.BiomeSet;
|
||||
import com.terraforged.biome.map.set.BiomeTypeSet;
|
||||
import com.terraforged.biome.map.set.RiverSet;
|
||||
import com.terraforged.biome.map.set.TemperatureSet;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
import com.terraforged.world.heightmap.Levels;
|
||||
import com.terraforged.world.terrain.TerrainType;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleBiomeMap implements BiomeMap {
|
||||
|
||||
private final BiomeSet deepOcean;
|
||||
private final BiomeSet shallowOcean;
|
||||
private final BiomeSet beach;
|
||||
private final BiomeSet coast;
|
||||
private final BiomeSet river;
|
||||
private final BiomeSet lake;
|
||||
private final BiomeSet wetland;
|
||||
private final BiomeSet land;
|
||||
private final BiomeSet[] terrainBiomes;
|
||||
|
||||
public SimpleBiomeMap(BiomeMapBuilder builder) {
|
||||
deepOcean = new TemperatureSet(builder.deepOceans, DefaultBiomes::defaultDeepOcean);
|
||||
shallowOcean = new TemperatureSet(builder.oceans, DefaultBiomes::defaultOcean);
|
||||
beach = new TemperatureSet(builder.beaches, DefaultBiomes::defaultBeach);
|
||||
coast = new TemperatureSet(builder.coasts, DefaultBiomes::defaultBiome);
|
||||
river = new RiverSet(builder.rivers, DefaultBiomes::defaultRiver, this);
|
||||
lake = new TemperatureSet(builder.lakes, DefaultBiomes::defaultLake);
|
||||
wetland = new TemperatureSet(builder.wetlands, DefaultBiomes::defaultWetland);
|
||||
land = new BiomeTypeSet(builder.map, DefaultBiomes::defaultBiome);
|
||||
terrainBiomes = new BiomeSet[TerrainType.values().length];
|
||||
terrainBiomes[TerrainType.SHALLOW_OCEAN.ordinal()] = shallowOcean;
|
||||
terrainBiomes[TerrainType.DEEP_OCEAN.ordinal()] = deepOcean;
|
||||
terrainBiomes[TerrainType.WETLAND.ordinal()] = wetland;
|
||||
terrainBiomes[TerrainType.RIVER.ordinal()] = river;
|
||||
terrainBiomes[TerrainType.LAKE.ordinal()] = lake;
|
||||
for (TerrainType type : TerrainType.values()) {
|
||||
if (terrainBiomes[type.ordinal()] == null) {
|
||||
terrainBiomes[type.ordinal()] = land;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Biome provideBiome(Cell cell, Levels levels) {
|
||||
TerrainType type = cell.terrain.getType();
|
||||
if (type.isSubmerged() && cell.value > levels.water) {
|
||||
return land.getBiome(cell);
|
||||
}
|
||||
return terrainBiomes[cell.terrain.getType().ordinal()].getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getDeepOcean(Cell cell) {
|
||||
return deepOcean.getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getShallowOcean(Cell cell) {
|
||||
return shallowOcean.getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBeach(Cell cell) {
|
||||
return beach.getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getCoast(Cell cell, Biome current) {
|
||||
int inland = land.getSize(cell);
|
||||
Biome[] coastal = coast.getSet(cell);
|
||||
int total = inland + coastal.length;
|
||||
int index = NoiseUtil.round((total - 1) * cell.biome);
|
||||
if (index >= inland) {
|
||||
return coastal[index - inland];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getRiver(Cell cell) {
|
||||
return river.getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getLake(Cell cell) {
|
||||
return lake.getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getWetland(Cell cell) {
|
||||
return wetland.getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getLand(Cell cell) {
|
||||
return land.getBiome(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Biome> getAllBiomes(BiomeType type) {
|
||||
int size = land.getSize(type.ordinal());
|
||||
if (size == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(land.getSet(type.ordinal()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJson() {
|
||||
JsonObject root = new JsonObject();
|
||||
root.add("DEEP_OCEAN", deepOcean.toJson());
|
||||
root.add("SHALLOW_OCEAN", shallowOcean.toJson());
|
||||
root.add("BEACH", beach.toJson());
|
||||
root.add("COAST", coast.toJson());
|
||||
root.add("RIVER", river.toJson());
|
||||
root.add("LAKE", lake.toJson());
|
||||
root.add("WETLAND", wetland.toJson());
|
||||
root.add("LAND", land.toJson());
|
||||
return root;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.terraforged.biome.map;
|
||||
package com.terraforged.biome.map.defaults;
|
||||
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
@ -0,0 +1,73 @@
|
||||
package com.terraforged.biome.map.defaults;
|
||||
|
||||
import com.terraforged.biome.ModBiomes;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biomes;
|
||||
|
||||
public class DefaultBiomes {
|
||||
|
||||
public static Biome defaultBeach(float temperature) {
|
||||
if (temperature < 0.25) {
|
||||
return Biomes.SNOWY_BEACH;
|
||||
}
|
||||
if (temperature > 0.75) {
|
||||
return ModBiomes.WARM_BEACH;
|
||||
}
|
||||
return Biomes.BEACH;
|
||||
}
|
||||
|
||||
public static Biome defaultRiver(float temperature) {
|
||||
if (temperature < 0.15) {
|
||||
return Biomes.FROZEN_RIVER;
|
||||
}
|
||||
return Biomes.RIVER;
|
||||
}
|
||||
|
||||
public static Biome defaultLake(float temperature) {
|
||||
if (temperature < 0.15) {
|
||||
return ModBiomes.FROZEN_LAKE;
|
||||
}
|
||||
return ModBiomes.LAKE;
|
||||
}
|
||||
|
||||
public static Biome defaultWetland(float temperature) {
|
||||
if (temperature < 0.15) {
|
||||
return ModBiomes.TAIGA_SCRUB;
|
||||
}
|
||||
return ModBiomes.MARSHLAND;
|
||||
}
|
||||
|
||||
public static Biome defaultOcean(float temperature) {
|
||||
if (temperature < 0.3) {
|
||||
return Biomes.FROZEN_OCEAN;
|
||||
}
|
||||
if (temperature > 0.7) {
|
||||
return Biomes.WARM_OCEAN;
|
||||
}
|
||||
return Biomes.OCEAN;
|
||||
}
|
||||
|
||||
public static 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;
|
||||
}
|
||||
|
||||
public static Biome defaultBiome(float temperature) {
|
||||
if (temperature < 0.3) {
|
||||
return ModBiomes.TAIGA_SCRUB;
|
||||
}
|
||||
if (temperature > 0.7) {
|
||||
return ModBiomes.SAVANNA_SCRUB;
|
||||
}
|
||||
return Biomes.PLAINS;
|
||||
}
|
||||
|
||||
public static boolean overridesRiver(Biome biome) {
|
||||
return biome.getCategory() == Biome.Category.SWAMP || biome.getCategory() == Biome.Category.JUNGLE;
|
||||
}
|
||||
}
|
76
src/main/java/com/terraforged/biome/map/set/BiomeSet.java
Normal file
76
src/main/java/com/terraforged/biome/map/set/BiomeSet.java
Normal file
@ -0,0 +1,76 @@
|
||||
package com.terraforged.biome.map.set;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.terraforged.biome.map.defaults.DefaultBiome;
|
||||
import com.terraforged.biome.provider.BiomeHelper;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.util.ListUtils;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class BiomeSet {
|
||||
|
||||
private static final Biome[] EMPTY = new Biome[0];
|
||||
|
||||
private final Biome[][] biomes;
|
||||
private final DefaultBiome defaultBiome;
|
||||
|
||||
public BiomeSet(Biome[][] biomes, DefaultBiome defaultBiome) {
|
||||
this.biomes = biomes;
|
||||
this.defaultBiome = defaultBiome;
|
||||
}
|
||||
|
||||
public int getSize(int index) {
|
||||
return biomes[index].length;
|
||||
}
|
||||
|
||||
public int getSize(Cell cell) {
|
||||
return biomes[getIndex(cell)].length;
|
||||
}
|
||||
|
||||
public Biome[] getSet(int index) {
|
||||
return biomes[index];
|
||||
}
|
||||
|
||||
public Biome[] getSet(Cell cell) {
|
||||
return biomes[getIndex(cell)];
|
||||
}
|
||||
|
||||
public Biome getBiome(Cell cell) {
|
||||
Biome[] set = biomes[getIndex(cell)];
|
||||
if (set.length == 0) {
|
||||
return defaultBiome.getDefaultBiome(cell.temperature);
|
||||
}
|
||||
return set[NoiseUtil.round((set.length - 1) * cell.biome)];
|
||||
}
|
||||
|
||||
public abstract int getIndex(Cell cell);
|
||||
|
||||
public abstract JsonElement toJson();
|
||||
|
||||
protected static Biome[][] collect(Map<? extends Enum<?>, List<Biome>> map, int size, Function<Enum<?>, Integer> indexer) {
|
||||
Biome[][] biomes = new Biome[size][];
|
||||
for (Enum<?> type : map.keySet()) {
|
||||
int index = indexer.apply(type);
|
||||
if (index < 0 || index >= size) {
|
||||
continue;
|
||||
}
|
||||
List<Biome> list = map.getOrDefault(type, Collections.emptyList());
|
||||
list = ListUtils.minimize(list);
|
||||
list.sort(Comparator.comparing(BiomeHelper::getId));
|
||||
biomes[index] = list.toArray(new Biome[0]);
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (biomes[i] == null) {
|
||||
biomes[i] = EMPTY;
|
||||
}
|
||||
}
|
||||
return biomes;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.terraforged.biome.map.set;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.terraforged.biome.map.defaults.DefaultBiome;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BiomeTypeSet extends BiomeSet {
|
||||
|
||||
public BiomeTypeSet(Map<BiomeType, List<Biome>> map, DefaultBiome defaultBiome) {
|
||||
super(BiomeSet.collect(map, BiomeType.values().length, Enum::ordinal), defaultBiome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(Cell cell) {
|
||||
return cell.biomeType.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJson() {
|
||||
JsonObject root = new JsonObject();
|
||||
for (BiomeType type : BiomeType.values()) {
|
||||
JsonArray array = new JsonArray();
|
||||
root.add(type.name(), array);
|
||||
Stream.of(getSet(type.ordinal())).distinct().map(Biome::getRegistryName).map(Objects::toString).forEach(array::add);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
11
src/main/java/com/terraforged/biome/map/set/Check.java
Normal file
11
src/main/java/com/terraforged/biome/map/set/Check.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.terraforged.biome.map.set;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Check {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String[] s = {null};
|
||||
Stream.of(null).forEach(System.out::println);
|
||||
}
|
||||
}
|
29
src/main/java/com/terraforged/biome/map/set/RiverSet.java
Normal file
29
src/main/java/com/terraforged/biome/map/set/RiverSet.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.terraforged.biome.map.set;
|
||||
|
||||
import com.terraforged.biome.map.BiomeMap;
|
||||
import com.terraforged.biome.map.defaults.DefaultBiome;
|
||||
import com.terraforged.biome.map.defaults.DefaultBiomes;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class RiverSet extends TemperatureSet {
|
||||
|
||||
private final BiomeMap biomes;
|
||||
|
||||
public RiverSet(Map<Biome.TempCategory, List<Biome>> map, DefaultBiome defaultBiome, BiomeMap biomes) {
|
||||
super(map, defaultBiome);
|
||||
this.biomes = biomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(Cell cell) {
|
||||
Biome biome = biomes.getLand(cell);
|
||||
if (DefaultBiomes.overridesRiver(biome)) {
|
||||
return biome;
|
||||
}
|
||||
return super.getBiome(cell);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.terraforged.biome.map.set;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.terraforged.biome.map.defaults.DefaultBiome;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class TemperatureSet extends BiomeSet {
|
||||
|
||||
public TemperatureSet(Map<Biome.TempCategory, List<Biome>> map, DefaultBiome defaultBiome) {
|
||||
super(BiomeSet.collect(map, 3, e -> e.ordinal() - 1), defaultBiome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(Cell cell) {
|
||||
if (cell.temperature < 0.25) {
|
||||
return 0;
|
||||
}
|
||||
if (cell.temperature > 0.75) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJson() {
|
||||
JsonObject root = new JsonObject();
|
||||
for (Biome.TempCategory temp : Biome.TempCategory.values()) {
|
||||
int index = temp.ordinal() - 1;
|
||||
if (index >= 0 && index < 3) {
|
||||
JsonArray array = new JsonArray();
|
||||
root.add(temp.name(), array);
|
||||
Stream.of(getSet(index)).distinct().map(Biome::getRegistryName).map(Objects::toString).forEach(array::add);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
@ -1,53 +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.biome.modifier;
|
||||
|
||||
import com.terraforged.api.biome.modifier.BiomeModifier;
|
||||
import com.terraforged.biome.map.BiomeMap;
|
||||
import com.terraforged.chunk.TerraContext;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.world.heightmap.Levels;
|
||||
import com.terraforged.world.GeneratorContext;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
import com.terraforged.world.terrain.Terrains;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biomes;
|
||||
|
||||
public class BeachModifier implements BiomeModifier {
|
||||
|
||||
private final Levels levels;
|
||||
private final Terrains terrain;
|
||||
private final BiomeMap biomeMap;
|
||||
private final float height;
|
||||
private final Module noise;
|
||||
private final BiomeMap biomes;
|
||||
private final Terrains terrains;
|
||||
|
||||
public BeachModifier(BiomeMap biomeMap, TerraContext context) {
|
||||
this.levels = context.levels;
|
||||
this.terrain = context.terrain;
|
||||
this.biomeMap = biomeMap;
|
||||
public BeachModifier(BiomeMap biomeMap, GeneratorContext context) {
|
||||
this.biomes = biomeMap;
|
||||
this.terrains = context.terrain;
|
||||
this.height = context.levels.water(6);
|
||||
this.noise = Source.perlin(context.seed.next(), 10, 1).scale(context.levels.scale(5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 0;
|
||||
return 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -57,11 +37,13 @@ public class BeachModifier implements BiomeModifier {
|
||||
|
||||
@Override
|
||||
public Biome modify(Biome in, Cell cell, int x, int z) {
|
||||
if (cell.terrain == terrain.beach) {
|
||||
return biomeMap.getBeach(cell.temperature, cell.moisture, cell.biome);
|
||||
if (cell.terrain == terrains.beach && cell.biomeType != BiomeType.DESERT) {
|
||||
if (cell.value + noise.getValue(x, z) < height) {
|
||||
if (in == Biomes.MUSHROOM_FIELDS) {
|
||||
return Biomes.MUSHROOM_FIELD_SHORE;
|
||||
}
|
||||
return biomes.getBeach(cell);
|
||||
}
|
||||
if (cell.terrain == terrain.coast && cell.value <= levels.water) {
|
||||
return biomeMap.getOcean(cell.temperature, cell.moisture, cell.biome);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
@ -47,10 +47,10 @@ public class BiomeModifierManager implements BiomeModifier, ModifierManager {
|
||||
public BiomeModifierManager(TerraContext context, BiomeMap biomes) {
|
||||
desertBiomes = new DesertBiomes(context.materials, biomes.getAllBiomes(BiomeType.DESERT));
|
||||
List<BiomeModifier> modifiers = new ArrayList<>();
|
||||
modifiers.add(new BeachModifier(biomes, context));
|
||||
modifiers.add(new CoastModifier(biomes, context));
|
||||
modifiers.add(new DesertColorModifier(desertBiomes));
|
||||
modifiers.add(new SandBiomeModifier(context));
|
||||
modifiers.add(new MushroomModifier());
|
||||
modifiers.add(new BeachModifier(biomes, context));
|
||||
Collections.sort(modifiers);
|
||||
this.biomeModifiers = modifiers;
|
||||
}
|
||||
|
@ -23,16 +23,42 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.biome.map;
|
||||
package com.terraforged.biome.modifier;
|
||||
|
||||
import com.terraforged.core.util.grid.FixedGrid;
|
||||
import com.terraforged.api.biome.modifier.BiomeModifier;
|
||||
import com.terraforged.biome.map.BiomeMap;
|
||||
import com.terraforged.chunk.TerraContext;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.world.terrain.Terrains;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
public class BiomeGroup {
|
||||
public class CoastModifier implements BiomeModifier {
|
||||
|
||||
public final FixedGrid<Biome> biomes;
|
||||
private final float height;
|
||||
private final Terrains terrain;
|
||||
private final BiomeMap biomeMap;
|
||||
|
||||
public BiomeGroup(FixedGrid<Biome> biomes) {
|
||||
this.biomes = biomes;
|
||||
public CoastModifier(BiomeMap biomeMap, TerraContext context) {
|
||||
this.terrain = context.terrain;
|
||||
this.biomeMap = biomeMap;
|
||||
this.height = context.levels.water(8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Biome biome) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome modify(Biome in, Cell cell, int x, int z) {
|
||||
if (cell.terrain.isCoast()) {
|
||||
return biomeMap.getCoast(cell, in);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ public class DesertColorModifier implements BiomeModifier {
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 0;
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,24 +0,0 @@
|
||||
package com.terraforged.biome.modifier;
|
||||
|
||||
import com.terraforged.api.biome.modifier.BiomeModifier;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biomes;
|
||||
|
||||
public class DunesModifier implements BiomeModifier {
|
||||
|
||||
@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) {
|
||||
return Biomes.DESERT;
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.terraforged.biome.modifier;
|
||||
|
||||
import com.terraforged.api.biome.modifier.BiomeModifier;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biomes;
|
||||
|
||||
public class MushroomModifier implements BiomeModifier {
|
||||
@Override
|
||||
public int priority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Biome biome) {
|
||||
return biome == Biomes.MUSHROOM_FIELD_SHORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome modify(Biome in, Cell cell, int x, int z) {
|
||||
return Biomes.MUSHROOM_FIELDS;
|
||||
}
|
||||
}
|
@ -48,7 +48,7 @@ public class SandBiomeModifier extends AbstractMaxHeightModifier {
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 1;
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,57 +0,0 @@
|
||||
package com.terraforged.biome.provider;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.world.heightmap.Levels;
|
||||
import com.terraforged.world.terrain.TerrainType;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
public class BiomeAccess {
|
||||
|
||||
private static final BiomeAccessor DEEP_OCEAN = (m, c) -> m.getDeepOcean(c.temperature, c.moisture, c.biome);
|
||||
private static final BiomeAccessor SHALLOW_OCEAN = (m, c) -> m.getOcean(c.temperature, c.moisture, c.biome);
|
||||
private static final BiomeAccessor LAKE = (m, c) -> m.getLake(c.temperature, c.moisture, c.biome);
|
||||
private static final BiomeAccessor WETLAND = (m, c) -> m.getWetland(c.temperature, c.moisture, c.biome);
|
||||
private static final BiomeAccessor NORMAL = (m, c) -> m.getBiome(c.biomeType, c.temperature, c.moisture, c.biome);
|
||||
private static final BiomeAccessor RIVER = (m, c) -> {
|
||||
Biome biome = m.getBiome(c.biomeType, c.temperature, c.moisture, c.biome);
|
||||
if (overridesRiver(biome)) {
|
||||
return biome;
|
||||
}
|
||||
return m.getRiver(c.temperature, c.moisture, c.biome);
|
||||
};
|
||||
|
||||
private static final BiomeAccessor[] accessors = createAccessorArray();
|
||||
|
||||
private final Levels levels;
|
||||
|
||||
public BiomeAccess(Levels levels) {
|
||||
this.levels = levels;
|
||||
}
|
||||
|
||||
public BiomeAccessor getAccessor(Cell cell) {
|
||||
TerrainType type = cell.terrain.getType();
|
||||
if (type.isSubmerged() && cell.value > levels.water) {
|
||||
return NORMAL;
|
||||
}
|
||||
return accessors[cell.terrain.getType().ordinal()];
|
||||
}
|
||||
|
||||
private static BiomeAccessor[] createAccessorArray() {
|
||||
BiomeAccessor[] accessors = new BiomeAccessor[TerrainType.values().length];
|
||||
accessors[TerrainType.SHALLOW_OCEAN.ordinal()] = SHALLOW_OCEAN;
|
||||
accessors[TerrainType.DEEP_OCEAN.ordinal()] = DEEP_OCEAN;
|
||||
accessors[TerrainType.WETLAND.ordinal()] = WETLAND;
|
||||
accessors[TerrainType.RIVER.ordinal()] = RIVER;
|
||||
accessors[TerrainType.LAKE.ordinal()] = LAKE;
|
||||
for (TerrainType type : TerrainType.values()) {
|
||||
if (accessors[type.ordinal()] == null) {
|
||||
accessors[type.ordinal()] = NORMAL;
|
||||
}
|
||||
}
|
||||
return accessors;
|
||||
}
|
||||
|
||||
private static boolean overridesRiver(Biome biome) {
|
||||
return biome.getCategory() == Biome.Category.SWAMP || biome.getCategory() == Biome.Category.JUNGLE;
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.terraforged.biome.provider;
|
||||
|
||||
import com.terraforged.biome.map.BiomeMap;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
public interface BiomeAccessor {
|
||||
|
||||
Biome getBiome(BiomeMap map, Cell cell);
|
||||
}
|
@ -54,26 +54,22 @@ public class BiomeHelper {
|
||||
|
||||
private static final Map<BiomeType, BiomePredicate> PREDICATES = new HashMap<BiomeType, BiomePredicate>() {{
|
||||
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.SAVANNA, BiomePredicate.SAVANNA.or(BiomePredicate.MESA).not(BiomePredicate.DESERT).not(BiomePredicate.STEPPE).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND));
|
||||
put(BiomeType.DESERT, BiomePredicate.DESERT.or(BiomePredicate.MESA).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND));
|
||||
put(BiomeType.TEMPERATE_RAINFOREST, BiomePredicate.TEMPERATE_RAINFOREST.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN));
|
||||
put(BiomeType.TEMPERATE_FOREST, BiomePredicate.TEMPERATE_FOREST.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND));
|
||||
put(BiomeType.GRASSLAND, BiomePredicate.GRASSLAND.not(BiomePredicate.WETLAND).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN));
|
||||
put(BiomeType.COLD_STEPPE, BiomePredicate.COLD_STEPPE.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN));
|
||||
put(BiomeType.STEPPE, BiomePredicate.STEPPE.not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN));
|
||||
put(BiomeType.TAIGA, BiomePredicate.TAIGA.not(BiomePredicate.TUNDRA).not(BiomePredicate.COLD_STEPPE).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN));
|
||||
put(BiomeType.TUNDRA, BiomePredicate.TUNDRA.not(BiomePredicate.TAIGA).not(BiomePredicate.BEACH).not(BiomePredicate.MOUNTAIN));
|
||||
put(BiomeType.ALPINE, BiomePredicate.MOUNTAIN);
|
||||
}};
|
||||
|
||||
public static BiomeMap.Builder getBuilder(List<BiomeData> biomes) {
|
||||
return BiomeMapBuilder.basic(biomes);
|
||||
}
|
||||
|
||||
public static BiomeMap getDefaultBiomeMap() {
|
||||
public static BiomeMap createBiomeMap() {
|
||||
List<BiomeData> biomes = getAllBiomeData();
|
||||
BiomeWeights weights = new BiomeWeights();
|
||||
BiomeMap.Builder builder = getBuilder(biomes);
|
||||
BiomeMap.Builder builder = BiomeMapBuilder.create();
|
||||
for (BiomeData data : biomes) {
|
||||
Biome biome = (Biome) data.reference;
|
||||
if (biome.isMutation() && getId(biome).contains("hills")) {
|
||||
@ -81,8 +77,10 @@ public class BiomeHelper {
|
||||
}
|
||||
|
||||
int weight = weights.getWeight(biome);
|
||||
if (BiomePredicate.COAST.test(data)) {
|
||||
if (BiomePredicate.BEACH.test(data)) {
|
||||
builder.addBeach(biome, weight);
|
||||
} else if (BiomePredicate.COAST.test(data)) {
|
||||
builder.addCoast(biome, weight);
|
||||
} else if (biome.getCategory() == Biome.Category.OCEAN) {
|
||||
builder.addOcean(biome, weight);
|
||||
} else if (BiomePredicate.RIVER.test(data)) {
|
||||
@ -94,16 +92,16 @@ public class BiomeHelper {
|
||||
} else {
|
||||
Collection<BiomeType> types = getTypes(data, biome);
|
||||
for (BiomeType type : types) {
|
||||
builder.addBiome(type, biome, weight);
|
||||
builder.addLand(type, biome, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.addBiome(BiomeType.TEMPERATE_RAINFOREST, Biomes.PLAINS, 10);
|
||||
builder.addBiome(BiomeType.TEMPERATE_FOREST, Biomes.FLOWER_FOREST, 2);
|
||||
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);
|
||||
builder.addLand(BiomeType.TEMPERATE_RAINFOREST, Biomes.PLAINS, 5);
|
||||
builder.addLand(BiomeType.TEMPERATE_FOREST, Biomes.FLOWER_FOREST, 2);
|
||||
builder.addLand(BiomeType.TEMPERATE_FOREST, Biomes.PLAINS, 5);
|
||||
builder.addLand(BiomeType.TUNDRA, ModBiomes.SNOWY_TAIGA_SCRUB, 2);
|
||||
builder.addLand(BiomeType.TAIGA, ModBiomes.TAIGA_SCRUB, 2);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@ -185,6 +183,9 @@ public class BiomeHelper {
|
||||
if (biome.getCategory() == Biome.Category.NETHER) {
|
||||
return true;
|
||||
}
|
||||
if (biome == Biomes.MUSHROOM_FIELD_SHORE) {
|
||||
return true;
|
||||
}
|
||||
return !BiomeDictionary.getTypes(biome).contains(BiomeDictionary.Type.OVERWORLD);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,6 @@ import java.util.Set;
|
||||
public class BiomeProvider extends AbstractBiomeProvider {
|
||||
|
||||
private final BiomeMap biomeMap;
|
||||
private final BiomeAccess biomeAccess;
|
||||
private final TerraContext context;
|
||||
private final WorldLookup worldLookup;
|
||||
private final BiomeModifierManager modifierManager;
|
||||
@ -55,8 +54,7 @@ public class BiomeProvider extends AbstractBiomeProvider {
|
||||
|
||||
public BiomeProvider(TerraContext context) {
|
||||
this.context = context;
|
||||
this.biomeMap = BiomeHelper.getDefaultBiomeMap();
|
||||
this.biomeAccess = new BiomeAccess(context.levels);
|
||||
this.biomeMap = BiomeHelper.createBiomeMap();
|
||||
this.worldLookup = new WorldLookup(context.factory, context);
|
||||
this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy());
|
||||
}
|
||||
@ -143,8 +141,7 @@ public class BiomeProvider extends AbstractBiomeProvider {
|
||||
}
|
||||
|
||||
public Biome getBiome(Cell cell, int x, int z) {
|
||||
BiomeAccessor accessor = biomeAccess.getAccessor(cell);
|
||||
Biome biome = accessor.getBiome(biomeMap, cell);
|
||||
Biome biome = biomeMap.provideBiome(cell, context.levels);
|
||||
if (modifierManager.hasModifiers(cell.terrain)) {
|
||||
return modifierManager.modify(biome, cell, x, z);
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.terraforged.biome.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.world.GeneratorContext;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
||||
public class ForestSurface implements Surface {
|
||||
|
||||
private final Module noise;
|
||||
|
||||
public ForestSurface(GeneratorContext context) {
|
||||
noise = Source.simplex(context.seed.next(), 40, 2).warp(Source.RAND, context.seed.next(), 2, 1, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildSurface(int x, int z, int height, SurfaceContext ctx) {
|
||||
BlockState state = getMaterial(x, z);
|
||||
ctx.buffer.setBlockState(ctx.pos.setPos(x, height, z), state, false);
|
||||
}
|
||||
|
||||
private BlockState getMaterial(int x, int z) {
|
||||
float value = noise.getValue(x, z);
|
||||
if (value > 0.6) {
|
||||
if (value < 0.75) {
|
||||
return Blocks.PODZOL.getDefaultState();
|
||||
}
|
||||
return States.DIRT.get();
|
||||
}
|
||||
return States.GRASS_BLOCK.get();
|
||||
}
|
||||
}
|
@ -5,10 +5,10 @@ import com.terraforged.api.chunk.column.ColumnDecorator;
|
||||
import com.terraforged.api.chunk.surface.SurfaceManager;
|
||||
import com.terraforged.biome.ModBiomes;
|
||||
import com.terraforged.biome.surface.BriceSurface;
|
||||
import com.terraforged.biome.surface.ForestSurface;
|
||||
import com.terraforged.biome.surface.IcebergsSurface;
|
||||
import com.terraforged.biome.surface.SwampSurface;
|
||||
import com.terraforged.chunk.column.BedrockDecorator;
|
||||
import com.terraforged.chunk.column.CoastDecorator;
|
||||
import com.terraforged.chunk.column.ErosionDecorator;
|
||||
import com.terraforged.chunk.column.GeologyDecorator;
|
||||
import com.terraforged.chunk.column.post.LayerDecorator;
|
||||
@ -53,7 +53,6 @@ public class TerraSetupFactory {
|
||||
Log.info(" - Erosion decorator enabled");
|
||||
processors.add(new ErosionDecorator(context));
|
||||
}
|
||||
processors.add(new CoastDecorator(context));
|
||||
processors.add(new BedrockDecorator(context));
|
||||
return processors;
|
||||
}
|
||||
@ -112,9 +111,21 @@ public class TerraSetupFactory {
|
||||
SurfaceManager manager = new SurfaceManager();
|
||||
manager.replace(Biomes.DEEP_FROZEN_OCEAN.delegate.get(), new IcebergsSurface(context, 30, 30));
|
||||
manager.replace(Biomes.FROZEN_OCEAN.delegate.get(), new IcebergsSurface(context, 20, 15));
|
||||
manager.replace(Biomes.SWAMP.delegate.get(), new SwampSurface());
|
||||
manager.replace(ModBiomes.MARSHLAND, new SwampSurface());
|
||||
manager.extend(ModBiomes.BRICE, new BriceSurface(context.seed));
|
||||
manager.append(ModBiomes.BRICE, new BriceSurface(context.seed));
|
||||
manager.replace(
|
||||
new SwampSurface(),
|
||||
Biomes.SWAMP.delegate.get(),
|
||||
ModBiomes.MARSHLAND
|
||||
);
|
||||
manager.append(
|
||||
new ForestSurface(context),
|
||||
Biomes.FOREST,
|
||||
Biomes.BIRCH_FOREST,
|
||||
Biomes.BIRCH_FOREST_HILLS,
|
||||
Biomes.TALL_BIRCH_FOREST,
|
||||
Biomes.DARK_FOREST,
|
||||
Biomes.DARK_FOREST_HILLS
|
||||
);
|
||||
return SetupHooks.setup(manager, context);
|
||||
}
|
||||
|
||||
|
@ -26,56 +26,28 @@
|
||||
package com.terraforged.data;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.terraforged.biome.map.BiomeMap;
|
||||
import com.terraforged.biome.provider.BiomeHelper;
|
||||
import com.terraforged.world.biome.BiomeType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
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")))) {
|
||||
BiomeMap map = BiomeHelper.createBiomeMap();
|
||||
try (Writer writer = new BufferedWriter(new FileWriter(new File(dataDir, "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<Biome> biomes = map.getBiomes(type);
|
||||
JsonObject root = new JsonObject();
|
||||
JsonArray values = new JsonArray();
|
||||
|
||||
root.addProperty("replaceable", false);
|
||||
root.add("values", values);
|
||||
|
||||
biomes.stream()
|
||||
.map(b -> b.getRegistryName() + "")
|
||||
.sorted()
|
||||
.forEach(values::add);
|
||||
|
||||
write(root, writer);
|
||||
});
|
||||
}
|
||||
|
||||
private static ResourceLocation getName(BiomeType type) {
|
||||
return new ResourceLocation("terraforged", type.name().toLowerCase());
|
||||
}
|
||||
|
@ -41,7 +41,12 @@ import net.minecraft.block.MyceliumBlock;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class Materials {
|
||||
@ -103,4 +108,16 @@ public class Materials {
|
||||
return state.getBlockHardness(reader.get(), BlockPos.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends IForgeRegistryEntry<T>> List<T> toList(Collection<T> collection) {
|
||||
List<T> list = new ArrayList<>(collection);
|
||||
list.sort(Materials::compare);
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
public static int compare(IForgeRegistryEntry<?> a, IForgeRegistryEntry<?> b) {
|
||||
String as = a.getRegistryName() + "";
|
||||
String bs = b.getRegistryName() + "";
|
||||
return as.compareTo(bs);
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +48,10 @@ public class GeoGenerator implements StrataGenerator {
|
||||
|
||||
public GeoGenerator(Materials materials) {
|
||||
types.add(Source.PERLIN);
|
||||
rock = new ArrayList<>(materials.stone);
|
||||
soil = new ArrayList<>(materials.dirt);
|
||||
clay = new ArrayList<>(materials.clay);
|
||||
sediment = new ArrayList<>(materials.sediment);
|
||||
rock = Materials.toList(materials.stone);
|
||||
soil = Materials.toList(materials.dirt);
|
||||
clay = Materials.toList(materials.clay);
|
||||
sediment = Materials.toList(materials.sediment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,115 @@
|
||||
{
|
||||
"biomes": [
|
||||
"minecraft:birch*",
|
||||
"minecraft:tall_birch*"
|
||||
],
|
||||
"match": [
|
||||
[
|
||||
"minecraft:birch_log",
|
||||
"minecraft:birch_leaves"
|
||||
],
|
||||
[
|
||||
"terraforged:poisson_surface"
|
||||
]
|
||||
],
|
||||
"after": {
|
||||
"name": "minecraft:decorated",
|
||||
"config": {
|
||||
"feature": {
|
||||
"name": "minecraft:random_selector",
|
||||
"config": {
|
||||
"features": [
|
||||
{
|
||||
"name": "minecraft:jungle_ground_bush",
|
||||
"config": {
|
||||
"trunk_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_log",
|
||||
"Properties": {
|
||||
"axis": "y"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leaves_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:birch_leaves",
|
||||
"Properties": {
|
||||
"distance": "3",
|
||||
"persistent": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorators": [],
|
||||
"base_height": 3
|
||||
},
|
||||
"chance": 0.15
|
||||
},
|
||||
{
|
||||
"name": "minecraft:jungle_ground_bush",
|
||||
"config": {
|
||||
"trunk_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_log",
|
||||
"Properties": {
|
||||
"axis": "y"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leaves_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_leaves",
|
||||
"Properties": {
|
||||
"distance": "3",
|
||||
"persistent": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorators": [],
|
||||
"base_height": 4
|
||||
},
|
||||
"chance": 0.25
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"name": "minecraft:jungle_ground_bush",
|
||||
"config": {
|
||||
"trunk_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_log",
|
||||
"Properties": {
|
||||
"axis": "y"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leaves_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_leaves",
|
||||
"Properties": {
|
||||
"distance": "3",
|
||||
"persistent": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorators": [],
|
||||
"base_height": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorator": {
|
||||
"name": "minecraft:count_extra_heightmap",
|
||||
"config": {
|
||||
"count": 0,
|
||||
"extra_chance": 0.05,
|
||||
"extra_count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
{
|
||||
"biomes": [
|
||||
"minecraft:forest",
|
||||
"minecraft:forest_hills",
|
||||
"minecraft:dark_forest",
|
||||
"minecraft:dark_forest_hills"
|
||||
],
|
||||
"match": [
|
||||
[
|
||||
"minecraft:oak_log",
|
||||
"minecraft:oak_leaves"
|
||||
],
|
||||
[
|
||||
"terraforged:poisson_surface"
|
||||
]
|
||||
],
|
||||
"after": {
|
||||
"name": "minecraft:decorated",
|
||||
"config": {
|
||||
"feature": {
|
||||
"name": "minecraft:random_selector",
|
||||
"config": {
|
||||
"features": [
|
||||
{
|
||||
"name": "minecraft:jungle_ground_bush",
|
||||
"config": {
|
||||
"trunk_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_log",
|
||||
"Properties": {
|
||||
"axis": "y"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leaves_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:birch_leaves",
|
||||
"Properties": {
|
||||
"distance": "3",
|
||||
"persistent": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorators": [],
|
||||
"base_height": 3
|
||||
},
|
||||
"chance": 0.15
|
||||
},
|
||||
{
|
||||
"name": "minecraft:jungle_ground_bush",
|
||||
"config": {
|
||||
"trunk_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_log",
|
||||
"Properties": {
|
||||
"axis": "y"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leaves_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_leaves",
|
||||
"Properties": {
|
||||
"distance": "3",
|
||||
"persistent": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorators": [],
|
||||
"base_height": 4
|
||||
},
|
||||
"chance": 0.25
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"name": "minecraft:jungle_ground_bush",
|
||||
"config": {
|
||||
"trunk_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_log",
|
||||
"Properties": {
|
||||
"axis": "y"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leaves_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:oak_leaves",
|
||||
"Properties": {
|
||||
"distance": "3",
|
||||
"persistent": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorators": [],
|
||||
"base_height": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorator": {
|
||||
"name": "minecraft:count_extra_heightmap",
|
||||
"config": {
|
||||
"count": 1,
|
||||
"extra_chance": 0.05,
|
||||
"extra_count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
{
|
||||
"biomes": [
|
||||
"minecraft:birch*",
|
||||
"minecraft:tall_birch*",
|
||||
"minecraft:forest",
|
||||
"minecraft:forest_hills",
|
||||
"minecraft:dark_forest",
|
||||
"minecraft:dark_forest_hills"
|
||||
],
|
||||
"match": [
|
||||
[
|
||||
"minecraft:decorated",
|
||||
"minecraft:grass"
|
||||
]
|
||||
],
|
||||
"after": {
|
||||
"name": "minecraft:decorated",
|
||||
"config": {
|
||||
"feature": {
|
||||
"name": "minecraft:random_selector",
|
||||
"config": {
|
||||
"features": [
|
||||
{
|
||||
"name": "minecraft:random_patch",
|
||||
"config": {
|
||||
"state_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:fern"
|
||||
}
|
||||
},
|
||||
"block_placer": {
|
||||
"type": "minecraft:simple_block_placer"
|
||||
},
|
||||
"whitelist": [],
|
||||
"blacklist": [],
|
||||
"tries": 20,
|
||||
"xspread": 7,
|
||||
"yspread": 3,
|
||||
"zspread": 7,
|
||||
"can_replace": false,
|
||||
"project": true,
|
||||
"need_water": false
|
||||
},
|
||||
"chance": 0.3
|
||||
},
|
||||
{
|
||||
"name": "minecraft:random_patch",
|
||||
"config": {
|
||||
"state_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:large_fern",
|
||||
"Properties": {
|
||||
"half": "lower"
|
||||
}
|
||||
}
|
||||
},
|
||||
"block_placer": {
|
||||
"type": "minecraft:double_plant_placer"
|
||||
},
|
||||
"whitelist": [],
|
||||
"blacklist": [],
|
||||
"tries": 20,
|
||||
"xspread": 7,
|
||||
"yspread": 3,
|
||||
"zspread": 7,
|
||||
"can_replace": false,
|
||||
"project": false,
|
||||
"need_water": false
|
||||
},
|
||||
"chance": 0.2
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"name": "minecraft:random_patch",
|
||||
"config": {
|
||||
"state_provider": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:fern"
|
||||
}
|
||||
},
|
||||
"block_placer": {
|
||||
"type": "minecraft:simple_block_placer"
|
||||
},
|
||||
"whitelist": [],
|
||||
"blacklist": [],
|
||||
"tries": 10,
|
||||
"xspread": 7,
|
||||
"yspread": 3,
|
||||
"zspread": 7,
|
||||
"can_replace": false,
|
||||
"project": true,
|
||||
"need_water": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorator": {
|
||||
"name": "minecraft:count_extra_heightmap",
|
||||
"config": {
|
||||
"count": 1,
|
||||
"extra_chance": 0.1,
|
||||
"extra_count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"biomes": [
|
||||
"minecraft:birch_forest",
|
||||
"minecraft:birch_forest_hills",
|
||||
"minecraft:birch*",
|
||||
"minecraft:tall_birch*",
|
||||
"minecraft:forest",
|
||||
"minecraft:forest_hills",
|
||||
"minecraft:dark_forest",
|
||||
|
@ -0,0 +1,44 @@
|
||||
{
|
||||
"biomes": [
|
||||
"terraforged:savanna_scrub",
|
||||
"terraforged:shattered_savanna_scrub"
|
||||
],
|
||||
"match": [
|
||||
[
|
||||
"minecraft:dead_bush"
|
||||
]
|
||||
],
|
||||
"before": {
|
||||
"name": "minecraft:decorated",
|
||||
"config": {
|
||||
"feature": {
|
||||
"name": "minecraft:random_selector",
|
||||
"config": {
|
||||
"features": [
|
||||
{
|
||||
"name": "terraforged:template",
|
||||
"config": {
|
||||
"template": "terraforged:acacia_bush"
|
||||
},
|
||||
"chance": 0.1
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"name": "terraforged:template",
|
||||
"config": {
|
||||
"template": "terraforged:acacia_bush"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"decorator": {
|
||||
"name": "minecraft:count_extra_heightmap",
|
||||
"config": {
|
||||
"count": 0,
|
||||
"extra_chance": 0.025,
|
||||
"extra_count": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -42,11 +42,11 @@
|
||||
"decorator": {
|
||||
"name": "terraforged:poisson_surface",
|
||||
"config": {
|
||||
"radius": 9,
|
||||
"biome_fade": 0.25,
|
||||
"radius": 8,
|
||||
"biome_fade": 0.12,
|
||||
"density_noise_scale": 300,
|
||||
"density_noise_min": 0,
|
||||
"density_noise_max": 2
|
||||
"density_noise_min": 0.5,
|
||||
"density_noise_max": 1.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,10 +41,10 @@
|
||||
"decorator": {
|
||||
"name": "terraforged:poisson_surface",
|
||||
"config": {
|
||||
"radius": 9,
|
||||
"biome_fade": 0.2,
|
||||
"radius": 8,
|
||||
"biome_fade": 0.12,
|
||||
"density_noise_scale": 150,
|
||||
"density_noise_min": 0.15,
|
||||
"density_noise_min": 0.5,
|
||||
"density_noise_max": 1.75
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"type": "tree",
|
||||
"name": "terraforged:acacia_bush",
|
||||
"paths": [
|
||||
"terraforged:trees/acacia/bush"
|
||||
],
|
||||
"config": {
|
||||
"extend_base": 2,
|
||||
"check_bounds": false
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user