rewrote weighted pocket system. Pockets now get supplied additional information to calculate their weight
This commit is contained in:
parent
4269ed289e
commit
0af4b02a56
9 changed files with 126 additions and 95 deletions
|
@ -8,6 +8,7 @@ import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
|||
import org.dimdev.dimdoors.ModConfig;
|
||||
import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
|
@ -59,11 +60,12 @@ public final class PocketGenerator {
|
|||
}
|
||||
|
||||
public static Pocket generateRandomPocketFromGroupV2(ServerWorld world, String group, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
return generatePocketV2(world, SchematicV2Handler.getInstance().getRandomPocketFromGroup(group), virtualLocation, linkTo, linkProperties);
|
||||
PocketGenerationParameters parameters = new PocketGenerationParameters(world, group, virtualLocation, linkTo, linkProperties);
|
||||
return generatePocketV2(SchematicV2Handler.getInstance().getRandomPocketFromGroup(group, parameters), parameters);
|
||||
}
|
||||
|
||||
public static Pocket generatePocketV2(ServerWorld world, VirtualPocket virtualPocket, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
return virtualPocket.prepareAndPlacePocket(world, virtualLocation, linkTo, linkProperties);
|
||||
public static Pocket generatePocketV2(VirtualPocket virtualPocket, PocketGenerationParameters parameters) {
|
||||
return virtualPocket.prepareAndPlacePocket(parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,7 @@ public class PocketTemplateV2 {
|
|||
private final int size;
|
||||
private final String id;
|
||||
|
||||
public PocketTemplateV2(Schematic schematic, String group, int size, String id, float weight) {
|
||||
public PocketTemplateV2(Schematic schematic, String group, int size, String id) {
|
||||
this.schematic = schematic;
|
||||
this.group = group;
|
||||
this.size = size;
|
||||
|
|
|
@ -16,7 +16,8 @@ import com.mojang.serialization.JsonOps;
|
|||
import net.minecraft.util.Identifier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.util.WeightedSet;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.WeightedList;
|
||||
import org.dimdev.dimdoors.util.schematic.v2.Schematic;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -27,7 +28,7 @@ public class SchematicV2Handler {
|
|||
private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create();
|
||||
private static final SchematicV2Handler INSTANCE = new SchematicV2Handler();
|
||||
private final Map<Identifier, PocketTemplateV2> templates = Maps.newHashMap();
|
||||
private final Map<String, WeightedSet<VirtualPocket>> templateMap = Maps.newHashMap(); //TODO: un-ugly-fy
|
||||
private final Map<String, WeightedList<VirtualPocket, PocketGenerationParameters>> templateMap = Maps.newHashMap(); //TODO: un-ugly-fy
|
||||
private final List<PocketGroup> pocketTypes = Lists.newArrayList();
|
||||
private static final Random RANDOM = new Random(new Random().nextLong());
|
||||
private boolean loaded = false;
|
||||
|
@ -70,17 +71,17 @@ public class SchematicV2Handler {
|
|||
*/
|
||||
private void loadResourceSchematics(PocketGroup type) throws URISyntaxException, IOException {
|
||||
String group = type.getGroup();
|
||||
WeightedSet<VirtualPocket> weightedPockets = new WeightedSet<>();
|
||||
WeightedList<VirtualPocket, PocketGenerationParameters> weightedPockets = new WeightedList<>();
|
||||
templateMap.put(group, weightedPockets);
|
||||
Path basePath = Paths.get(SchematicV2Handler.class.getResource(String.format("/data/dimdoors/pockets/schematic/v2/%s/", group)).toURI());
|
||||
for (VirtualPocket virtualPocket : type.getEntries()) {
|
||||
weightedPockets.add(virtualPocket, virtualPocket.getWeight());
|
||||
weightedPockets.add(virtualPocket);
|
||||
if (virtualPocket instanceof VirtualSchematicPocket) {
|
||||
VirtualSchematicPocket schemPocket = (VirtualSchematicPocket) virtualPocket;
|
||||
Path schemPath = basePath.resolve(schemPocket.getName() + ".schem");
|
||||
CompoundTag schemTag = NbtIo.readCompressed(Files.newInputStream(schemPath));
|
||||
Schematic schematic = Schematic.fromTag(schemTag);
|
||||
PocketTemplateV2 template = new PocketTemplateV2(schematic, group, schemPocket.getSize(), schemPocket.getName(), schemPocket.getWeight());
|
||||
PocketTemplateV2 template = new PocketTemplateV2(schematic, group, schemPocket.getSize(), schemPocket.getName());
|
||||
Identifier templateID = new Identifier("dimdoors", schemPocket.getName());
|
||||
templates.put(templateID, template);
|
||||
schemPocket.setTemplateID(templateID);
|
||||
|
@ -88,16 +89,16 @@ public class SchematicV2Handler {
|
|||
}
|
||||
}
|
||||
|
||||
public VirtualPocket getRandomPublicPocket() {
|
||||
return getRandomPocketFromGroup("public");
|
||||
public VirtualPocket getRandomPublicPocket(PocketGenerationParameters parameters) {
|
||||
return getRandomPocketFromGroup("public", parameters);
|
||||
}
|
||||
|
||||
public VirtualPocket getRandomPrivatePocket() {
|
||||
return getRandomPocketFromGroup("private");
|
||||
public VirtualPocket getRandomPrivatePocket(PocketGenerationParameters parameters) {
|
||||
return getRandomPocketFromGroup("private", parameters);
|
||||
}
|
||||
|
||||
public VirtualPocket getRandomPocketFromGroup(String group) {
|
||||
return templateMap.get(group).getRandomWeighted();
|
||||
public VirtualPocket getRandomPocketFromGroup(String group, PocketGenerationParameters parameters) {
|
||||
return templateMap.get(group).getRandomWeighted(parameters);
|
||||
}
|
||||
|
||||
public static SchematicV2Handler getInstance() {
|
||||
|
|
|
@ -10,11 +10,17 @@ import net.minecraft.util.registry.RegistryKey;
|
|||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.util.Weighted;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
// maybe PocketEntry is a better name? Only realised after I named this that the previous PocketEntry would be redundant.
|
||||
public abstract class VirtualPocket {
|
||||
public abstract class VirtualPocket implements Weighted<PocketGenerationParameters> {
|
||||
public static final Registry<VirtualPocketType<? extends VirtualPocket>> REGISTRY = FabricRegistryBuilder.from(new SimpleRegistry<VirtualPocketType<? extends VirtualPocket>>(RegistryKey.ofRegistry(new Identifier("dimdoors", "virtual_pocket_type")), Lifecycle.stable())).buildAndRegister();
|
||||
public static final Codec<VirtualPocket> CODEC = new Codec<VirtualPocket>() {
|
||||
@Override
|
||||
|
@ -30,12 +36,10 @@ public abstract class VirtualPocket {
|
|||
};
|
||||
|
||||
|
||||
public abstract Pocket prepareAndPlacePocket(ServerWorld world, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties);
|
||||
public abstract Pocket prepareAndPlacePocket(PocketGenerationParameters parameters);
|
||||
public abstract String toString();
|
||||
// TODO: are equals() and hashCode() necessary?
|
||||
public abstract VirtualPocketType<? extends VirtualPocket> getType();
|
||||
public abstract int getWeight();
|
||||
|
||||
|
||||
public interface VirtualPocketType<T extends VirtualPocket> {
|
||||
VirtualPocketType<VirtualSchematicPocket> SCHEMATIC = register("dimdoors:schematic", VirtualSchematicPocket.CODEC);
|
||||
|
|
|
@ -8,7 +8,8 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.util.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.util.PocketGenerationParameters;
|
||||
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
|
||||
import org.dimdev.dimdoors.world.pocket.Pocket;
|
||||
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||
|
||||
|
@ -18,7 +19,7 @@ public class VirtualSchematicPocket extends VirtualPocket{
|
|||
public static final Codec<VirtualSchematicPocket> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.INT.fieldOf("size").forGetter(VirtualSchematicPocket::getSize),
|
||||
Codec.STRING.fieldOf("id").forGetter(VirtualSchematicPocket::getName),
|
||||
Codec.INT.optionalFieldOf("weight", 5).forGetter(VirtualSchematicPocket::getWeight)
|
||||
Codec.INT.optionalFieldOf("weight", 5).forGetter(virtualSchematicPocket -> virtualSchematicPocket.getWeight(null))
|
||||
).apply(instance, VirtualSchematicPocket::new));
|
||||
|
||||
private final int size;
|
||||
|
@ -49,15 +50,17 @@ public class VirtualSchematicPocket extends VirtualPocket{
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getWeight() {
|
||||
public int getWeight(PocketGenerationParameters parameters){
|
||||
return this.weight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Pocket prepareAndPlacePocket(ServerWorld world, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters) {
|
||||
ServerWorld world = parameters.getWorld();
|
||||
VirtualLocation virtualLocation = parameters.getVirtualLocation();
|
||||
VirtualTarget linkTo = parameters.getLinkTo();
|
||||
LinkProperties linkProperties = parameters.getLinkProperties();
|
||||
|
||||
PocketTemplateV2 template = SchematicV2Handler.getInstance().getTemplates().get(templateID);
|
||||
if (template == null) throw new RuntimeException("Pocket template of id " + templateID + " not found!");
|
||||
LOGGER.info("Generating pocket from template " + template.getId() + " at virtual location " + virtualLocation);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import org.dimdev.dimdoors.rift.registry.LinkProperties;
|
||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||
|
||||
public class PocketGenerationParameters {
|
||||
private final ServerWorld world;
|
||||
private final String group;
|
||||
private final VirtualLocation virtualLocation;
|
||||
private final VirtualTarget linkTo;
|
||||
private final LinkProperties linkProperties;
|
||||
|
||||
public PocketGenerationParameters(ServerWorld world, String group, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||
this.world = world;
|
||||
this.group = group;
|
||||
this.virtualLocation = virtualLocation;
|
||||
this.linkTo = linkTo;
|
||||
this.linkProperties = linkProperties;
|
||||
}
|
||||
|
||||
public ServerWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public VirtualLocation getVirtualLocation() {
|
||||
return virtualLocation;
|
||||
}
|
||||
|
||||
public VirtualTarget getLinkTo() {
|
||||
return linkTo;
|
||||
}
|
||||
|
||||
public LinkProperties getLinkProperties() {
|
||||
return linkProperties;
|
||||
}
|
||||
}
|
9
src/main/java/org/dimdev/dimdoors/util/Weighted.java
Normal file
9
src/main/java/org/dimdev/dimdoors/util/Weighted.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
public interface Weighted<P> {
|
||||
/*
|
||||
Should always return the same number if the same parameters are provided.
|
||||
returned number should always be >= 0
|
||||
*/
|
||||
int getWeight(P parameters);
|
||||
}
|
39
src/main/java/org/dimdev/dimdoors/util/WeightedList.java
Normal file
39
src/main/java/org/dimdev/dimdoors/util/WeightedList.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class WeightedList<T extends Weighted<P>, P> {
|
||||
private final List<T> list;
|
||||
private final Random random = new Random();
|
||||
|
||||
public WeightedList() {
|
||||
this.list = Lists.newArrayList();
|
||||
}
|
||||
|
||||
public T getRandomWeighted(P parameters) {
|
||||
int totalWeight = list.stream().mapToInt(weighted -> weighted.getWeight(parameters)).sum();
|
||||
int cursor = random.nextInt(totalWeight);
|
||||
for (T weighted : list) {
|
||||
cursor -= weighted.getWeight(parameters);
|
||||
if (cursor <= 0) {
|
||||
return weighted; // should never return an entry with weight 0, unless there are only weight 0 entries
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean add(T t) {
|
||||
return list.add(t);
|
||||
}
|
||||
|
||||
public boolean remove(T t){
|
||||
return list.remove(t);
|
||||
}
|
||||
|
||||
// TODO: make weightedList implement List instead
|
||||
public List<T> getList() {
|
||||
return list;
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package org.dimdev.dimdoors.util;
|
||||
|
||||
import net.minecraft.util.Pair;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WeightedSet<T> {
|
||||
private final TreeSet<Pair<T, Integer>> set;
|
||||
private final int defaultWeight;
|
||||
private int totalWeight = 0;
|
||||
private boolean dirty = false;
|
||||
private final Random random = new Random();
|
||||
|
||||
public WeightedSet() {
|
||||
this(1);
|
||||
}
|
||||
|
||||
//TODO: ensure default Weight is >= 0?
|
||||
public WeightedSet(int defaultWeight) {
|
||||
this.set = new TreeSet<>((pair1, pair2) -> pair2.getRight().compareTo(pair1.getRight()));
|
||||
this.defaultWeight = defaultWeight;
|
||||
}
|
||||
|
||||
private void markDirty() {
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
private void updateTotalWeight() {
|
||||
if (dirty) totalWeight = set.stream().mapToInt(Pair::getRight).sum();
|
||||
}
|
||||
|
||||
public T getRandomWeighted() {
|
||||
updateTotalWeight();
|
||||
int cursor = random.nextInt(totalWeight);
|
||||
for (Pair<T, Integer> pair : set) {
|
||||
cursor -= pair.getRight();
|
||||
if (cursor <= 0) {
|
||||
return pair.getLeft(); // should never return an entry with weight 0, unless there are only weight 0 entries
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(); // either the list is empty, or it somehow
|
||||
}
|
||||
|
||||
// TODO: ensure weight is >= 0? How about a negativeWeightException?
|
||||
public boolean add(T t, Integer weight) {
|
||||
if (set.add(new Pair<>(t, weight))) {
|
||||
markDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean add(T t) {
|
||||
return add(t, defaultWeight);
|
||||
}
|
||||
|
||||
public boolean remove(T t){
|
||||
if (set.remove(set.stream().filter(pair -> pair.getLeft().equals(t)).findFirst().orElse(null))) {
|
||||
markDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<T> getObjectList() {
|
||||
return set.stream().map(Pair::getLeft).collect(Collectors.toList());
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue