Merge pull request #198 from toolbox4minecraft/adjustments-to-world-filters

Adjustments to world filters
master
Stefan Dollase 2016-07-03 22:17:01 +02:00 committed by GitHub
commit 4aca8d777f
10 changed files with 87 additions and 130 deletions

View File

@ -1,10 +1,13 @@
package amidst.mojangapi.file.json.filter;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import amidst.documentation.GsonConstructor;
import amidst.documentation.Immutable;
import amidst.mojangapi.world.biome.Biome;
import amidst.mojangapi.world.filter.WorldFilter_Biome;
@Immutable
@ -19,10 +22,24 @@ public class WorldFilterJson_Biome {
public void validate(List<String> notifications) {
if (biomes.isEmpty()) {
notifications.add("No biomes for filter");
} else {
for (String name : biomes) {
if (Biome.exists(name)) {
notifications.add("invalid biome name: '" + name + "'");
}
}
}
}
public WorldFilter_Biome createBiomeFilter() {
return new WorldFilter_Biome(distance, biomes);
return new WorldFilter_Biome(distance, createValidBiomeIndexes());
}
private Set<Short> createValidBiomeIndexes() {
Set<Short> result = new HashSet<>();
for (String name : biomes) {
result.add((short) Biome.getByName(name).getIndex());
}
return result;
}
}

View File

@ -5,6 +5,7 @@ import java.util.List;
import amidst.documentation.GsonConstructor;
import amidst.documentation.Immutable;
import amidst.mojangapi.world.filter.WorldFilter_Structure;
import amidst.mojangapi.world.icon.type.DefaultWorldIconTypes;
@Immutable
public class WorldFilterJson_Structure {
@ -17,10 +18,15 @@ public class WorldFilterJson_Structure {
}
public void validate(List<String> notifications) {
// noop
if (!DefaultWorldIconTypes.exists(structure)) {
notifications.add("invalid structure: '" + structure + "'");
}
if (minimum <= 0) {
notifications.add("invalid minimum: " + minimum);
}
}
public WorldFilter_Structure createStructureFilter() {
return new WorldFilter_Structure(distance, structure, minimum);
return new WorldFilter_Structure(distance, DefaultWorldIconTypes.getByName(structure), minimum);
}
}

View File

@ -1,13 +1,13 @@
package amidst.mojangapi.world.filter;
import amidst.documentation.Immutable;
import amidst.fragment.Fragment;
import amidst.mojangapi.world.World;
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
import amidst.mojangapi.world.coordinates.Resolution;
@Immutable
public abstract class WorldFilter {
private short[][] evaluatedRegion = null;
protected final long worldFilterSize;
protected final long quarterFilterSize;
protected final CoordinatesInWorld corner;
@ -30,18 +30,5 @@ public abstract class WorldFilter {
}
}
public final boolean isValid(World world) {
return isValid(world, getUpdatedRegion(world));
}
protected abstract boolean isValid(World world, short[][] region);
private short[][] getUpdatedRegion(World world) {
if (this.evaluatedRegion == null) {
this.evaluatedRegion = new short[(int) this.quarterFilterSize * 2][(int) this.quarterFilterSize * 2];
}
world.getBiomeDataOracle().populateArray(corner, evaluatedRegion, true);
return evaluatedRegion;
}
public abstract boolean isValid(World world);
}

View File

@ -1,52 +1,31 @@
package amidst.mojangapi.world.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import amidst.documentation.NotThreadSafe;
import amidst.mojangapi.world.World;
import amidst.mojangapi.world.biome.Biome;
@NotThreadSafe
public class WorldFilter_Biome extends WorldFilter {
private final List<Biome> biomes;
private final Set<Short> validBiomeIndexes;
private short[][] region;
public WorldFilter_Biome(long worldFilterSize, List<String> biomeNames) {
public WorldFilter_Biome(long worldFilterSize, Set<Short> validBiomeIndexes) {
super(worldFilterSize);
List<Biome> biomes = new ArrayList<>();
for (String name : biomeNames) {
Biome biome = Biome.getByName(name);
if (biome == null) {
List<String> possibleNames = new ArrayList<String>();
for (Biome possibleBiome : Biome.allBiomes()) {
possibleNames.add(possibleBiome.getName());
}
throw new IllegalArgumentException("Biome name '" + name + "' should be one of: "
+ String.join(", ", possibleNames));
}
biomes.add(biome);
}
this.biomes = biomes;
this.validBiomeIndexes = validBiomeIndexes;
this.region = new short[(int) this.quarterFilterSize * 2][(int) this.quarterFilterSize * 2];
}
@Override
protected boolean isValid(World world, short[][] region) {
public boolean isValid(World world) {
world.getBiomeDataOracle().populateArray(corner, region, true);
for (short[] row : region) {
for (short entry : row) {
if (isValidBiome(entry)) {
if (validBiomeIndexes.contains(entry)) {
return true;
}
}
}
return false;
}
private boolean isValidBiome(short biomeIndex) {
for (Biome biome : biomes) {
if (biomeIndex == biome.getIndex()) {
return true;
}
}
return false;
}
}

View File

@ -2,8 +2,10 @@ package amidst.mojangapi.world.filter;
import java.util.List;
import amidst.documentation.Immutable;
import amidst.mojangapi.world.World;
@Immutable
public class WorldFilter_MatchAll extends WorldFilter {
private final List<WorldFilter> filters;
@ -13,7 +15,7 @@ public class WorldFilter_MatchAll extends WorldFilter {
}
@Override
protected boolean isValid(World world, short[][] region) {
public boolean isValid(World world) {
for (WorldFilter filter : filters) {
if (!filter.isValid(world)) {
return false;

View File

@ -1,42 +1,40 @@
package amidst.mojangapi.world.filter;
import amidst.documentation.Immutable;
import amidst.mojangapi.world.World;
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
import amidst.mojangapi.world.icon.WorldIcon;
import amidst.mojangapi.world.icon.producer.NameFilteredWorldIconCollector;
import amidst.mojangapi.world.icon.producer.WorldIconCollector;
import amidst.mojangapi.world.icon.producer.WorldIconProducer;
import amidst.mojangapi.world.icon.type.DefaultWorldIconTypes;
@Immutable
public class WorldFilter_Structure extends WorldFilter {
final int count;
final DefaultWorldIconTypes structure;
private final DefaultWorldIconTypes structure;
private final int count;
public WorldFilter_Structure(long worldFilterSize, String structureName, int count) {
public WorldFilter_Structure(long worldFilterSize, DefaultWorldIconTypes structure, int count) {
super(worldFilterSize);
this.structure = DefaultWorldIconTypes.getByName(structureName);
this.structure = structure;
this.count = count;
}
@SuppressWarnings("unchecked")
@Override
protected boolean isValid(World world, short[][] region) {
public boolean isValid(World world) {
WorldIconCollector structureCollector = getCollector();
@SuppressWarnings("rawtypes")
WorldIconProducer structureProducer = getProducer(world);
for (long x = 0; x < 2 * worldFilterSize; x += 512) {
for (long y = 0; y < 2 * worldFilterSize; y += 512) {
CoordinatesInWorld subCorner = CoordinatesInWorld.from(x, y).add(corner);
structureProducer.produce(subCorner, structureCollector, null);
}
}
procudeAndCollect(getProducer(world), structureCollector);
return structureCollector.get().size() > count;
}
@SuppressWarnings("rawtypes")
private WorldIconProducer getProducer(World world) {
private void procudeAndCollect(WorldIconProducer<Void> structureProducer, WorldIconCollector structureCollector) {
for (long x = 0; x < 2 * worldFilterSize; x += 512) {
for (long y = 0; y < 2 * worldFilterSize; y += 512) {
structureProducer.produce(CoordinatesInWorld.from(x, y).add(corner), structureCollector, null);
}
}
}
private WorldIconProducer<Void> getProducer(World world) {
switch (structure) {
case JUNGLE:
case DESERT:
@ -62,7 +60,7 @@ public class WorldFilter_Structure extends WorldFilter {
case DESERT:
case IGLOO:
case WITCH:
return new TypedWorldIconCollector(structure);
return new NameFilteredWorldIconCollector(structure.getName());
case STRONGHOLD:
case VILLAGE:
case OCEAN_MONUMENT:
@ -72,19 +70,4 @@ public class WorldFilter_Structure extends WorldFilter {
throw new IllegalArgumentException("Unsupported structure type: " + structure.getName());
}
}
private static class TypedWorldIconCollector extends WorldIconCollector {
final DefaultWorldIconTypes acceptedStructure;
TypedWorldIconCollector(DefaultWorldIconTypes acceptedStructure) {
this.acceptedStructure = acceptedStructure;
}
@Override
public void accept(WorldIcon worldIcon) {
if (worldIcon.getName().equals(acceptedStructure.getName())) {
super.accept(worldIcon);
}
}
}
}

View File

@ -0,0 +1,20 @@
package amidst.mojangapi.world.icon.producer;
import amidst.documentation.NotThreadSafe;
import amidst.mojangapi.world.icon.WorldIcon;
@NotThreadSafe
public class NameFilteredWorldIconCollector extends WorldIconCollector {
private final String name;
public NameFilteredWorldIconCollector(String name) {
this.name = name;
}
@Override
public void accept(WorldIcon worldIcon) {
if (worldIcon.getName().equals(name)) {
super.accept(worldIcon);
}
}
}

View File

@ -45,6 +45,10 @@ public enum DefaultWorldIconTypes {
return typeMap.get(name);
}
public static boolean exists(String name) {
return typeMap.containsKey(name);
}
private static String getFilename(String name) {
return "/amidst/gui/main/icon/" + name + ".png";
}

View File

@ -1,41 +0,0 @@
package amidst.mojangapi.mocking;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
import amidst.documentation.NotThreadSafe;
import amidst.mojangapi.world.icon.WorldIcon;
@NotThreadSafe
public class NameFilteredWorldIconCollector implements Consumer<WorldIcon> {
private List<WorldIcon> worldIcons;
private final String name;
public NameFilteredWorldIconCollector(String name) {
this.name = name;
}
@Override
public void accept(WorldIcon worldIcon) {
if (worldIcon.getName().equals(name)) {
initListIfNecessary();
worldIcons.add(worldIcon);
}
}
private void initListIfNecessary() {
if (worldIcons == null) {
worldIcons = new LinkedList<WorldIcon>();
}
}
public List<WorldIcon> get() {
if (worldIcons == null) {
return Collections.emptyList();
} else {
return worldIcons;
}
}
}

View File

@ -9,10 +9,10 @@ import amidst.documentation.GsonConstructor;
import amidst.documentation.Immutable;
import amidst.logging.Log;
import amidst.mojangapi.mocking.FragmentCornerWalker;
import amidst.mojangapi.mocking.NameFilteredWorldIconCollector;
import amidst.mojangapi.world.World;
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
import amidst.mojangapi.world.icon.WorldIcon;
import amidst.mojangapi.world.icon.producer.NameFilteredWorldIconCollector;
import amidst.mojangapi.world.icon.producer.WorldIconProducer;
@Immutable