mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-19 07:11:14 +00:00
compile structure addon
This commit is contained in:
+77
-4
@@ -12,10 +12,29 @@ import java.util.function.Consumer;
|
|||||||
/**
|
/**
|
||||||
* Runnable that locates a biome asynchronously
|
* Runnable that locates a biome asynchronously
|
||||||
*/
|
*/
|
||||||
public class AsyncBiomeFinder extends AsyncFeatureFinder<TerraBiome> {
|
public class AsyncBiomeFinder implements Runnable {
|
||||||
|
|
||||||
|
protected final BiomeProvider provider;
|
||||||
|
protected final TerraBiome target;
|
||||||
|
protected final int startRadius;
|
||||||
|
protected final int maxRadius;
|
||||||
|
protected final int centerX;
|
||||||
|
protected final int centerZ;
|
||||||
|
protected final World world;
|
||||||
|
private final Consumer<Vector3> callback;
|
||||||
|
protected int searchSize = 1;
|
||||||
|
protected final TerraPlugin main;
|
||||||
|
|
||||||
public AsyncBiomeFinder(BiomeProvider provider, TerraBiome target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
public AsyncBiomeFinder(BiomeProvider provider, TerraBiome target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
||||||
super(provider, target, origin, world, startRadius, maxRadius, callback, main);
|
this.provider = provider;
|
||||||
|
this.target = target;
|
||||||
|
this.main = main;
|
||||||
|
this.startRadius = startRadius;
|
||||||
|
this.maxRadius = maxRadius;
|
||||||
|
this.centerX = origin.getBlockX();
|
||||||
|
this.centerZ = origin.getBlockZ();
|
||||||
|
this.world = world;
|
||||||
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,14 +44,68 @@ public class AsyncBiomeFinder extends AsyncFeatureFinder<TerraBiome> {
|
|||||||
* @param z Z coordinate
|
* @param z Z coordinate
|
||||||
* @return TerraBiome at coordinates
|
* @return TerraBiome at coordinates
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public boolean isValid(int x, int z, TerraBiome target) {
|
public boolean isValid(int x, int z, TerraBiome target) {
|
||||||
int res = main.getTerraConfig().getBiomeSearchResolution();
|
int res = main.getTerraConfig().getBiomeSearchResolution();
|
||||||
return getProvider().getBiome(x * res, z * res).equals(target);
|
return getProvider().getBiome(x * res, z * res).equals(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector3 finalizeVector(Vector3 orig) {
|
public Vector3 finalizeVector(Vector3 orig) {
|
||||||
return orig.multiply(main.getTerraConfig().getBiomeSearchResolution());
|
return orig.multiply(main.getTerraConfig().getBiomeSearchResolution());
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int x = centerX;
|
||||||
|
int z = centerZ;
|
||||||
|
|
||||||
|
x /= searchSize;
|
||||||
|
z /= searchSize;
|
||||||
|
|
||||||
|
int run = 1;
|
||||||
|
boolean toggle = true;
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
|
main:
|
||||||
|
for(int i = startRadius; i < maxRadius; i++) {
|
||||||
|
for(int j = 0; j < run; j++) {
|
||||||
|
if(isValid(x, z, target)) {
|
||||||
|
found = true;
|
||||||
|
break main;
|
||||||
|
}
|
||||||
|
if(toggle) x += 1;
|
||||||
|
else x -= 1;
|
||||||
|
}
|
||||||
|
for(int j = 0; j < run; j++) {
|
||||||
|
if(isValid(x, z, target)) {
|
||||||
|
found = true;
|
||||||
|
break main;
|
||||||
|
}
|
||||||
|
if(toggle) z += 1;
|
||||||
|
else z -= 1;
|
||||||
|
}
|
||||||
|
run++;
|
||||||
|
toggle = !toggle;
|
||||||
|
}
|
||||||
|
Vector3 finalSpawn = found ? finalizeVector(new Vector3(x, 0, z)) : null;
|
||||||
|
callback.accept(finalSpawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerraBiome getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public World getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeProvider getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSearchSize() {
|
||||||
|
return searchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchSize(int searchSize) {
|
||||||
|
this.searchSize = searchSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-96
@@ -1,96 +0,0 @@
|
|||||||
package com.dfsek.terra.addons.biome.command.biome;
|
|
||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
|
||||||
import com.dfsek.terra.api.world.World;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public abstract class AsyncFeatureFinder<T> implements Runnable {
|
|
||||||
protected final BiomeProvider provider;
|
|
||||||
protected final T target;
|
|
||||||
protected final int startRadius;
|
|
||||||
protected final int maxRadius;
|
|
||||||
protected final int centerX;
|
|
||||||
protected final int centerZ;
|
|
||||||
protected final World world;
|
|
||||||
private final Consumer<Vector3> callback;
|
|
||||||
protected int searchSize = 1;
|
|
||||||
protected final TerraPlugin main;
|
|
||||||
|
|
||||||
public AsyncFeatureFinder(BiomeProvider provider, T target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
|
||||||
this.provider = provider;
|
|
||||||
this.target = target;
|
|
||||||
this.main = main;
|
|
||||||
this.startRadius = startRadius;
|
|
||||||
this.maxRadius = maxRadius;
|
|
||||||
this.centerX = origin.getBlockX();
|
|
||||||
this.centerZ = origin.getBlockZ();
|
|
||||||
this.world = world;
|
|
||||||
this.callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int x = centerX;
|
|
||||||
int z = centerZ;
|
|
||||||
|
|
||||||
x /= searchSize;
|
|
||||||
z /= searchSize;
|
|
||||||
|
|
||||||
int run = 1;
|
|
||||||
boolean toggle = true;
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
main:
|
|
||||||
for(int i = startRadius; i < maxRadius; i++) {
|
|
||||||
for(int j = 0; j < run; j++) {
|
|
||||||
if(isValid(x, z, target)) {
|
|
||||||
found = true;
|
|
||||||
break main;
|
|
||||||
}
|
|
||||||
if(toggle) x += 1;
|
|
||||||
else x -= 1;
|
|
||||||
}
|
|
||||||
for(int j = 0; j < run; j++) {
|
|
||||||
if(isValid(x, z, target)) {
|
|
||||||
found = true;
|
|
||||||
break main;
|
|
||||||
}
|
|
||||||
if(toggle) z += 1;
|
|
||||||
else z -= 1;
|
|
||||||
}
|
|
||||||
run++;
|
|
||||||
toggle = !toggle;
|
|
||||||
}
|
|
||||||
Vector3 finalSpawn = found ? finalizeVector(new Vector3(x, 0, z)) : null;
|
|
||||||
callback.accept(finalSpawn);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract Vector3 finalizeVector(Vector3 orig);
|
|
||||||
|
|
||||||
public abstract boolean isValid(int x, int z, T target);
|
|
||||||
|
|
||||||
public T getTarget() {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public World getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BiomeProvider getProvider() {
|
|
||||||
return provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSearchSize() {
|
|
||||||
return searchSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSearchSize(int searchSize) {
|
|
||||||
this.searchSize = searchSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+84
-15
@@ -2,34 +2,103 @@ package com.dfsek.terra.addons.structure.command;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.TerraPlugin;
|
import com.dfsek.terra.api.TerraPlugin;
|
||||||
import com.dfsek.terra.api.structure.ConfiguredStructure;
|
import com.dfsek.terra.api.structure.ConfiguredStructure;
|
||||||
import com.dfsek.terra.api.structure.rotation.Rotation;
|
|
||||||
import com.dfsek.terra.api.util.PopulationUtil;
|
|
||||||
import com.dfsek.terra.api.vector.Vector3;
|
import com.dfsek.terra.api.vector.Vector3;
|
||||||
import com.dfsek.terra.api.world.World;
|
import com.dfsek.terra.api.world.World;
|
||||||
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
|
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
import net.jafama.FastMath;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class AsyncStructureFinder extends AsyncFeatureFinder<ConfiguredStructure> {
|
public class AsyncStructureFinder implements Runnable {
|
||||||
|
protected final BiomeProvider provider;
|
||||||
|
protected final ConfiguredStructure target;
|
||||||
|
protected final int startRadius;
|
||||||
|
protected final int maxRadius;
|
||||||
|
protected final int centerX;
|
||||||
|
protected final int centerZ;
|
||||||
|
protected final World world;
|
||||||
|
private final Consumer<Vector3> callback;
|
||||||
|
protected int searchSize = 1;
|
||||||
|
protected final TerraPlugin main;
|
||||||
public AsyncStructureFinder(BiomeProvider provider, ConfiguredStructure target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
public AsyncStructureFinder(BiomeProvider provider, ConfiguredStructure target, @NotNull Vector3 origin, World world, int startRadius, int maxRadius, Consumer<Vector3> callback, TerraPlugin main) {
|
||||||
super(provider, target, origin, world, startRadius, maxRadius, callback, main);
|
//setSearchSize(target.getSpawn().getWidth() + 2 * target.getSpawn().getSeparation());
|
||||||
setSearchSize(target.getSpawn().getWidth() + 2 * target.getSpawn().getSeparation());
|
this.provider = provider;
|
||||||
|
this.target = target;
|
||||||
|
this.main = main;
|
||||||
|
this.startRadius = startRadius;
|
||||||
|
this.maxRadius = maxRadius;
|
||||||
|
this.centerX = origin.getBlockX();
|
||||||
|
this.centerZ = origin.getBlockZ();
|
||||||
|
this.world = world;
|
||||||
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector3 finalizeVector(Vector3 orig) {
|
public Vector3 finalizeVector(Vector3 orig) {
|
||||||
return target.getSpawn().getChunkSpawn(orig.getBlockX(), orig.getBlockZ(), world.getSeed());
|
return orig;//target.getSpawn().getChunkSpawn(orig.getBlockX(), orig.getBlockZ(), world.getSeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid(int x, int z, ConfiguredStructure target) {
|
||||||
|
//Vector3 spawn = target.getSpawn().getChunkSpawn(x, z, world.getSeed());
|
||||||
|
//if(!((UserDefinedBiome) provider.getBiome(spawn)).getConfig().getStructures().contains(target)) return false;
|
||||||
|
//Random random = new Random(PopulationUtil.getCarverChunkSeed(FastMath.floorDiv(spawn.getBlockX(), 16), FastMath.floorDiv(spawn.getBlockZ(), 16), world.getSeed()));
|
||||||
|
//return target.getStructure().get(random).test(spawn.setY(target.getSpawnStart().get(random)), world, random, Rotation.fromDegrees(90 * random.nextInt(4)));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(int x, int z, ConfiguredStructure target) {
|
public void run() {
|
||||||
Vector3 spawn = target.getSpawn().getChunkSpawn(x, z, world.getSeed());
|
int x = centerX;
|
||||||
if(!((UserDefinedBiome) provider.getBiome(spawn)).getConfig().getStructures().contains(target)) return false;
|
int z = centerZ;
|
||||||
Random random = new Random(PopulationUtil.getCarverChunkSeed(FastMath.floorDiv(spawn.getBlockX(), 16), FastMath.floorDiv(spawn.getBlockZ(), 16), world.getSeed()));
|
|
||||||
return target.getStructure().get(random).test(spawn.setY(target.getSpawnStart().get(random)), world, random, Rotation.fromDegrees(90 * random.nextInt(4)));
|
x /= searchSize;
|
||||||
|
z /= searchSize;
|
||||||
|
|
||||||
|
int run = 1;
|
||||||
|
boolean toggle = true;
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
|
main:
|
||||||
|
for(int i = startRadius; i < maxRadius; i++) {
|
||||||
|
for(int j = 0; j < run; j++) {
|
||||||
|
if(isValid(x, z, target)) {
|
||||||
|
found = true;
|
||||||
|
break main;
|
||||||
|
}
|
||||||
|
if(toggle) x += 1;
|
||||||
|
else x -= 1;
|
||||||
|
}
|
||||||
|
for(int j = 0; j < run; j++) {
|
||||||
|
if(isValid(x, z, target)) {
|
||||||
|
found = true;
|
||||||
|
break main;
|
||||||
|
}
|
||||||
|
if(toggle) z += 1;
|
||||||
|
else z -= 1;
|
||||||
|
}
|
||||||
|
run++;
|
||||||
|
toggle = !toggle;
|
||||||
|
}
|
||||||
|
Vector3 finalSpawn = found ? finalizeVector(new Vector3(x, 0, z)) : null;
|
||||||
|
callback.accept(finalSpawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfiguredStructure getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public World getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeProvider getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSearchSize() {
|
||||||
|
return searchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchSize(int searchSize) {
|
||||||
|
this.searchSize = searchSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ public class Pool {
|
|||||||
* @param pool The JSON Object to instantiate from.
|
* @param pool The JSON Object to instantiate from.
|
||||||
*/
|
*/
|
||||||
public Pool(JSONObject pool, TerraPlugin main) {
|
public Pool(JSONObject pool, TerraPlugin main) {
|
||||||
entries = new ProbabilityCollectionImpl<>();
|
entries = new ProbabilityCollection<>();
|
||||||
Object amount = pool.get("rolls");
|
Object amount = pool.get("rolls");
|
||||||
if(amount instanceof Long) {
|
if(amount instanceof Long) {
|
||||||
max = FastMath.toIntExact((Long) amount);
|
max = FastMath.toIntExact((Long) amount);
|
||||||
|
|||||||
+193
-9
@@ -1,26 +1,210 @@
|
|||||||
package com.dfsek.terra.api.util.collection;
|
package com.dfsek.terra.api.util.collection;
|
||||||
|
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface ProbabilityCollection<E> extends Collection<E> {
|
public class ProbabilityCollection<E> implements Collection<E> {
|
||||||
ProbabilityCollection<E> add(E item, int probability);
|
protected final Map<E, MutableInteger> cont = new HashMap<>();
|
||||||
|
private Object[] array = new Object[0];
|
||||||
|
private int size;
|
||||||
|
|
||||||
E get(Random r);
|
public ProbabilityCollection<E> add(E item, int probability) {
|
||||||
|
if(!cont.containsKey(item)) size++;
|
||||||
|
cont.computeIfAbsent(item, i -> new MutableInteger(0)).increment();
|
||||||
|
int oldLength = array.length;
|
||||||
|
Object[] newArray = new Object[array.length + probability];
|
||||||
|
System.arraycopy(array, 0, newArray, 0, array.length); // Expand array.
|
||||||
|
array = newArray;
|
||||||
|
for(int i = oldLength; i < array.length; i++) array[i] = item;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
E get(NoiseSampler n, double x, double y, double z);
|
@SuppressWarnings("unchecked")
|
||||||
|
public E get(Random r) {
|
||||||
|
if(array.length == 0) return null;
|
||||||
|
return (E) array[r.nextInt(array.length)];
|
||||||
|
}
|
||||||
|
|
||||||
E get(NoiseSampler n, double x, double z);
|
@SuppressWarnings("unchecked")
|
||||||
|
public E get(NoiseSampler n, double x, double y, double z) {
|
||||||
|
if(array.length == 0) return null;
|
||||||
|
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, y, z), array.length)];
|
||||||
|
}
|
||||||
|
|
||||||
<T> ProbabilityCollection<T> map(Function<E, T> mapper, boolean carryNull);
|
@SuppressWarnings("unchecked")
|
||||||
|
public E get(NoiseSampler n, double x, double z) {
|
||||||
|
if(array.length == 0) return null;
|
||||||
|
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, z), array.length)];
|
||||||
|
}
|
||||||
|
|
||||||
int getTotalProbability();
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> ProbabilityCollection<T> map(Function<E, T> mapper, boolean carryNull) {
|
||||||
|
ProbabilityCollection<T> newCollection = new ProbabilityCollection<>();
|
||||||
|
newCollection.array = new Object[array.length];
|
||||||
|
|
||||||
int getProbability(E item);
|
for(int i = 0; i < array.length; i++) {
|
||||||
|
if(carryNull && array[i] == null) continue;
|
||||||
|
newCollection.array[i] = mapper.apply((E) array[i]);
|
||||||
|
}
|
||||||
|
return newCollection;
|
||||||
|
}
|
||||||
|
|
||||||
Set<E> getContents();
|
public int getTotalProbability() {
|
||||||
|
return array.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getProbability(E item) {
|
||||||
|
MutableInteger integer = cont.get(item);
|
||||||
|
return integer == null ? 0 : integer.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder("[");
|
||||||
|
|
||||||
|
cont.forEach((item, prob) -> builder.append(item).append(": ").append(prob).append(", "));
|
||||||
|
|
||||||
|
return builder.append("]").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return array.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return cont.containsKey(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return cont.keySet().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Object @NotNull [] toArray() {
|
||||||
|
return cont.keySet().toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SuspiciousToArrayCall")
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public <T> T @NotNull [] toArray(@NotNull T[] a) {
|
||||||
|
return cont.keySet().toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an item with probability of 1.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean add(E e) {
|
||||||
|
add(e, 1);
|
||||||
|
return true; // Since this adds the item with a probability, the collection will always have changed.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
throw new UnsupportedOperationException("Cannot remove item from ProbabilityCollection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(@NotNull Collection<?> c) {
|
||||||
|
return cont.keySet().containsAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(@NotNull Collection<? extends E> c) {
|
||||||
|
c.forEach(this::add);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(@NotNull Collection<?> c) {
|
||||||
|
throw new UnsupportedOperationException("Cannot remove item from ProbabilityCollection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(@NotNull Collection<?> c) {
|
||||||
|
throw new UnsupportedOperationException("Cannot remove item from ProbabilityCollection!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
cont.clear();
|
||||||
|
array = new Object[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<E> getContents() {
|
||||||
|
return new HashSet<>(cont.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Singleton<T> extends ProbabilityCollection<T> {
|
||||||
|
private final T single;
|
||||||
|
|
||||||
|
public Singleton(T single) {
|
||||||
|
this.single = single;
|
||||||
|
cont.put(single, new MutableInteger(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProbabilityCollection<T> add(T item, int probability) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T1> ProbabilityCollection<T1> map(Function<T, T1> mapper, boolean carryNull) {
|
||||||
|
if(carryNull && single == null) return new Singleton<>(null);
|
||||||
|
return new Singleton<>(mapper.apply(single));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get(Random r) {
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get(NoiseSampler n, double x, double y, double z) {
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get(NoiseSampler n, double x, double z) {
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTotalProbability() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<T> getContents() {
|
||||||
|
return Collections.singleton(single);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-216
@@ -1,216 +0,0 @@
|
|||||||
package com.dfsek.terra.api.util.collections;
|
|
||||||
|
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
|
||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
|
||||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public class ProbabilityCollectionImpl<E> implements ProbabilityCollection<E> {
|
|
||||||
protected final Map<E, MutableInteger> cont = new HashMap<>();
|
|
||||||
private Object[] array = new Object[0];
|
|
||||||
private int size;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProbabilityCollection<E> add(E item, int probability) {
|
|
||||||
if(!cont.containsKey(item)) size++;
|
|
||||||
cont.computeIfAbsent(item, i -> new MutableInteger(0)).increment();
|
|
||||||
int oldLength = array.length;
|
|
||||||
Object[] newArray = new Object[array.length + probability];
|
|
||||||
System.arraycopy(array, 0, newArray, 0, array.length); // Expand array.
|
|
||||||
array = newArray;
|
|
||||||
for(int i = oldLength; i < array.length; i++) array[i] = item;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E get(Random r) {
|
|
||||||
if(array.length == 0) return null;
|
|
||||||
return (E) array[r.nextInt(array.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E get(NoiseSampler n, double x, double y, double z) {
|
|
||||||
if(array.length == 0) return null;
|
|
||||||
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, y, z), array.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public E get(NoiseSampler n, double x, double z) {
|
|
||||||
if(array.length == 0) return null;
|
|
||||||
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, z), array.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> ProbabilityCollection<T> map(Function<E, T> mapper, boolean carryNull) {
|
|
||||||
ProbabilityCollectionImpl<T> newCollection = new ProbabilityCollectionImpl<>();
|
|
||||||
newCollection.array = new Object[array.length];
|
|
||||||
|
|
||||||
for(int i = 0; i < array.length; i++) {
|
|
||||||
if(carryNull && array[i] == null) continue;
|
|
||||||
newCollection.array[i] = mapper.apply((E) array[i]);
|
|
||||||
}
|
|
||||||
return newCollection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTotalProbability() {
|
|
||||||
return array.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getProbability(E item) {
|
|
||||||
MutableInteger integer = cont.get(item);
|
|
||||||
return integer == null ? 0 : integer.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder builder = new StringBuilder("[");
|
|
||||||
|
|
||||||
cont.forEach((item, prob) -> builder.append(item).append(": ").append(prob).append(", "));
|
|
||||||
|
|
||||||
return builder.append("]").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return array.length == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(Object o) {
|
|
||||||
return cont.containsKey(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Iterator<E> iterator() {
|
|
||||||
return cont.keySet().iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Object[] toArray() {
|
|
||||||
return cont.keySet().toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("SuspiciousToArrayCall")
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public <T> T[] toArray(@NotNull T[] a) {
|
|
||||||
return cont.keySet().toArray(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item with probability of 1.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean add(E e) {
|
|
||||||
add(e, 1);
|
|
||||||
return true; // Since this adds the item with a probability, the collection will always have changed.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean remove(Object o) {
|
|
||||||
throw new UnsupportedOperationException("Cannot remove item from ProbabilityCollection!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsAll(@NotNull Collection<?> c) {
|
|
||||||
return cont.keySet().containsAll(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addAll(@NotNull Collection<? extends E> c) {
|
|
||||||
c.forEach(this::add);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeAll(@NotNull Collection<?> c) {
|
|
||||||
throw new UnsupportedOperationException("Cannot remove item from ProbabilityCollection!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean retainAll(@NotNull Collection<?> c) {
|
|
||||||
throw new UnsupportedOperationException("Cannot remove item from ProbabilityCollection!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
cont.clear();
|
|
||||||
array = new Object[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<E> getContents() {
|
|
||||||
return new HashSet<>(cont.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Singleton<T> extends ProbabilityCollectionImpl<T> {
|
|
||||||
private final T single;
|
|
||||||
|
|
||||||
public Singleton(T single) {
|
|
||||||
this.single = single;
|
|
||||||
cont.put(single, new MutableInteger(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProbabilityCollectionImpl<T> add(T item, int probability) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T1> ProbabilityCollectionImpl<T1> map(Function<T, T1> mapper, boolean carryNull) {
|
|
||||||
if(carryNull && single == null) return new Singleton<>(null);
|
|
||||||
return new Singleton<>(mapper.apply(single));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T get(Random r) {
|
|
||||||
return single;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T get(NoiseSampler n, double x, double y, double z) {
|
|
||||||
return single;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T get(NoiseSampler n, double x, double z) {
|
|
||||||
return single;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTotalProbability() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<T> getContents() {
|
|
||||||
return Collections.singleton(single);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-3
@@ -4,7 +4,6 @@ import com.dfsek.tectonic.exception.LoadException;
|
|||||||
import com.dfsek.tectonic.loading.ConfigLoader;
|
import com.dfsek.tectonic.loading.ConfigLoader;
|
||||||
import com.dfsek.tectonic.loading.TypeLoader;
|
import com.dfsek.tectonic.loading.TypeLoader;
|
||||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
import com.dfsek.terra.api.util.collections.ProbabilityCollectionImpl;
|
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
@@ -15,7 +14,7 @@ import java.util.Map;
|
|||||||
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
|
public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollection<Object>> {
|
||||||
@Override
|
@Override
|
||||||
public ProbabilityCollection<Object> load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
public ProbabilityCollection<Object> load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
|
||||||
ProbabilityCollection<Object> collection = new ProbabilityCollectionImpl<>();
|
ProbabilityCollection<Object> collection = new ProbabilityCollection<>();
|
||||||
|
|
||||||
if(type instanceof ParameterizedType) {
|
if(type instanceof ParameterizedType) {
|
||||||
ParameterizedType pType = (ParameterizedType) type;
|
ParameterizedType pType = (ParameterizedType) type;
|
||||||
@@ -35,7 +34,7 @@ public class ProbabilityCollectionLoader implements TypeLoader<ProbabilityCollec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(o instanceof String) {
|
} else if(o instanceof String) {
|
||||||
return new ProbabilityCollectionImpl.Singleton<>(configLoader.loadType(generic, o));
|
return new ProbabilityCollection.Singleton<>(configLoader.loadType(generic, o));
|
||||||
} else {
|
} else {
|
||||||
throw new LoadException("Malformed Probability Collection: " + o);
|
throw new LoadException("Malformed Probability Collection: " + o);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package noise;
|
|||||||
import com.dfsek.tectonic.annotations.Default;
|
import com.dfsek.tectonic.annotations.Default;
|
||||||
import com.dfsek.tectonic.annotations.Value;
|
import com.dfsek.tectonic.annotations.Value;
|
||||||
import com.dfsek.tectonic.config.ConfigTemplate;
|
import com.dfsek.tectonic.config.ConfigTemplate;
|
||||||
import com.dfsek.terra.api.util.collections.ProbabilityCollectionImpl;
|
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||||
|
|
||||||
public class ColorConfigTemplate implements ConfigTemplate {
|
public class ColorConfigTemplate implements ConfigTemplate {
|
||||||
@Value("colors")
|
@Value("colors")
|
||||||
private ProbabilityCollectionImpl<Integer> colors;
|
private ProbabilityCollection<Integer> colors;
|
||||||
|
|
||||||
@Value("enable")
|
@Value("enable")
|
||||||
@Default
|
@Default
|
||||||
@@ -17,7 +17,7 @@ public class ColorConfigTemplate implements ConfigTemplate {
|
|||||||
return enable;
|
return enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProbabilityCollectionImpl<Integer> getColors() {
|
public ProbabilityCollection<Integer> getColors() {
|
||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user