/* * * 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.mod.material.Materials; import com.terraforged.world.geology.Strata; 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.stone); soil = new ArrayList<>(materials.dirt); clay = new ArrayList<>(materials.clay); sediment = new ArrayList<>(materials.sediment); } @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 -> Materials.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; } } }