initial rewrite of pocket placement
instead of each pocket having an assigned template, the pockets now generate/ place themselves allows for pockets with custom generators instead of schematics
This commit is contained in:
parent
edfc9d7b63
commit
34137d12b7
9 changed files with 363 additions and 116 deletions
|
@ -12,6 +12,7 @@ import org.dimdev.dimdoors.item.ModItems;
|
||||||
import org.dimdev.dimdoors.particle.ModParticleTypes;
|
import org.dimdev.dimdoors.particle.ModParticleTypes;
|
||||||
import org.dimdev.dimdoors.pockets.SchematicHandler;
|
import org.dimdev.dimdoors.pockets.SchematicHandler;
|
||||||
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
|
||||||
|
import org.dimdev.dimdoors.pockets.VirtualPocket;
|
||||||
import org.dimdev.dimdoors.rift.targets.Targets;
|
import org.dimdev.dimdoors.rift.targets.Targets;
|
||||||
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
import org.dimdev.dimdoors.rift.targets.VirtualTarget;
|
||||||
import org.dimdev.dimdoors.sound.ModSoundEvents;
|
import org.dimdev.dimdoors.sound.ModSoundEvents;
|
||||||
|
@ -79,6 +80,8 @@ public class DimensionalDoorsInitializer implements ModInitializer {
|
||||||
Targets.registerDefaultTargets();
|
Targets.registerDefaultTargets();
|
||||||
VirtualTarget.VirtualTargetType.register();
|
VirtualTarget.VirtualTargetType.register();
|
||||||
|
|
||||||
|
VirtualPocket.VirtualPocketType.register();
|
||||||
|
|
||||||
SchematicV2Handler.getInstance().load();
|
SchematicV2Handler.getInstance().load();
|
||||||
SchematicHandler.INSTANCE.loadSchematics();
|
SchematicHandler.INSTANCE.loadSchematics();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,50 +27,25 @@ public final class PocketGenerator {
|
||||||
return pocket;
|
return pocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Pocket prepareAndPlaceV2Pocket(ServerWorld world, PocketTemplateV2 pocketTemplate, VirtualLocation virtualLocation, boolean setup) {
|
|
||||||
LOGGER.info("Generating pocket from template " + pocketTemplate.getId() + " at virtual location " + virtualLocation);
|
|
||||||
|
|
||||||
Pocket pocket = DimensionalRegistry.getPocketDirectory(world.getRegistryKey()).newPocket();
|
|
||||||
pocketTemplate.place(pocket);
|
|
||||||
pocket.virtualLocation = virtualLocation;
|
|
||||||
return pocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Pocket generatePocketFromTemplate(ServerWorld world, PocketTemplate pocketTemplate, VirtualLocation virtualLocation, boolean setup) {
|
public static Pocket generatePocketFromTemplate(ServerWorld world, PocketTemplate pocketTemplate, VirtualLocation virtualLocation, boolean setup) {
|
||||||
Pocket pocket = prepareAndPlacePocket(world, pocketTemplate, virtualLocation, setup);
|
Pocket pocket = prepareAndPlacePocket(world, pocketTemplate, virtualLocation, setup);
|
||||||
if (setup) pocketTemplate.setup(pocket, null, null);
|
if (setup) pocketTemplate.setup(pocket, null, null);
|
||||||
return pocket;
|
return pocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pocket generateV2PocketFromTemplate(ServerWorld world, PocketTemplateV2 pocketTemplate, VirtualLocation virtualLocation, boolean setup) {
|
|
||||||
Pocket pocket = prepareAndPlaceV2Pocket(world, pocketTemplate, virtualLocation, setup);
|
|
||||||
if (setup) {
|
|
||||||
pocketTemplate.setup(pocket, null, null);
|
|
||||||
}
|
|
||||||
return pocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Pocket generatePocketFromTemplate(ServerWorld world, PocketTemplate pocketTemplate, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
public static Pocket generatePocketFromTemplate(ServerWorld world, PocketTemplate pocketTemplate, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||||
Pocket pocket = prepareAndPlacePocket(world, pocketTemplate, virtualLocation, true);
|
Pocket pocket = prepareAndPlacePocket(world, pocketTemplate, virtualLocation, true);
|
||||||
pocketTemplate.setup(pocket, linkTo, linkProperties);
|
pocketTemplate.setup(pocket, linkTo, linkProperties);
|
||||||
return pocket;
|
return pocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pocket generateV2PocketFromTemplate(ServerWorld world, PocketTemplateV2 pocketTemplate, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
|
||||||
Pocket pocket = prepareAndPlaceV2Pocket(world, pocketTemplate, virtualLocation, true);
|
|
||||||
pocketTemplate.setup(pocket, linkTo, linkProperties);
|
|
||||||
return pocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Pocket generatePrivatePocket(VirtualLocation virtualLocation) {
|
public static Pocket generatePrivatePocket(VirtualLocation virtualLocation) {
|
||||||
PocketTemplate pocketTemplate = SchematicHandler.INSTANCE.getPersonalPocketTemplate();
|
PocketTemplate pocketTemplate = SchematicHandler.INSTANCE.getPersonalPocketTemplate();
|
||||||
return generatePocketFromTemplate(DimensionalDoorsInitializer.getWorld(ModDimensions.PERSONAL), pocketTemplate, virtualLocation, true);
|
return generatePocketFromTemplate(DimensionalDoorsInitializer.getWorld(ModDimensions.PERSONAL), pocketTemplate, virtualLocation, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pocket generatePrivatePocketV2(VirtualLocation virtualLocation) {
|
public static Pocket generatePrivatePocketV2(VirtualLocation virtualLocation) {
|
||||||
PocketTemplateV2 pocketTemplate = SchematicV2Handler.getInstance().getRandomPrivatePocket();
|
return generateRandomPocketFromGroupV2(DimensionalDoorsInitializer.getWorld(ModDimensions.PUBLIC), "private", virtualLocation, null, null);
|
||||||
return generateV2PocketFromTemplate(DimensionalDoorsInitializer.getWorld(ModDimensions.PERSONAL), pocketTemplate, virtualLocation, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: size of public pockets should increase with depth
|
// TODO: size of public pockets should increase with depth
|
||||||
|
@ -80,10 +55,17 @@ public final class PocketGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pocket generatePublicPocketV2(VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
public static Pocket generatePublicPocketV2(VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||||
PocketTemplateV2 pocketTemplate = SchematicV2Handler.getInstance().getRandomPublicPocket();
|
return generateRandomPocketFromGroupV2(DimensionalDoorsInitializer.getWorld(ModDimensions.PUBLIC), "public", virtualLocation, linkTo, linkProperties);
|
||||||
return generateV2PocketFromTemplate(DimensionalDoorsInitializer.getWorld(ModDimensions.PUBLIC), pocketTemplate, virtualLocation, linkTo, linkProperties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Pocket generateRandomPocketFromGroupV2(ServerWorld world, String group, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||||
|
return generatePocketV2(world, SchematicV2Handler.getInstance().getRandomPocketFromGroup(group), virtualLocation, linkTo, linkProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pocket generatePocketV2(ServerWorld world, VirtualPocket virtualPocket, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||||
|
return virtualPocket.prepareAndPlacePocket(world, virtualLocation, linkTo, linkProperties);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a dungeon pockets at a certain depth.
|
* Create a dungeon pockets at a certain depth.
|
||||||
*
|
*
|
||||||
|
|
|
@ -6,15 +6,15 @@ import java.util.Objects;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
public final class PocketType {
|
public final class PocketGroup {
|
||||||
public static final Codec<PocketType> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
public static final Codec<PocketGroup> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
Codec.STRING.fieldOf("group").forGetter(PocketType::getGroup),
|
Codec.STRING.fieldOf("group").forGetter(PocketGroup::getGroup),
|
||||||
PocketEntry.CODEC.listOf().fieldOf("pockets").forGetter(PocketType::getEntries)
|
VirtualPocket.CODEC.listOf().fieldOf("pockets").forGetter(PocketGroup::getEntries)
|
||||||
).apply(instance, PocketType::new));
|
).apply(instance, PocketGroup::new));
|
||||||
private final String group;
|
private final String group;
|
||||||
private final List<PocketEntry> entries;
|
private final List<VirtualPocket> entries;
|
||||||
|
|
||||||
public PocketType(String group, List<PocketEntry> entries) {
|
public PocketGroup(String group, List<VirtualPocket> entries) {
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.entries = entries;
|
this.entries = entries;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ public final class PocketType {
|
||||||
return this.group;
|
return this.group;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PocketEntry> getEntries() {
|
public List<VirtualPocket> getEntries() {
|
||||||
return this.entries;
|
return this.entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public final class PocketType {
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (super.equals(o)) return true;
|
if (super.equals(o)) return true;
|
||||||
if (o == null || this.getClass() != o.getClass()) return false;
|
if (o == null || this.getClass() != o.getClass()) return false;
|
||||||
PocketType that = (PocketType) o;
|
PocketGroup that = (PocketGroup) o;
|
||||||
return Objects.equals(this.group, that.group) &&
|
return Objects.equals(this.group, that.group) &&
|
||||||
Objects.equals(this.entries, that.entries);
|
Objects.equals(this.entries, that.entries);
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ public final class PocketType {
|
||||||
return Objects.hash(this.group, this.entries);
|
return Objects.hash(this.group, this.entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public static final class PocketEntry {
|
public static final class PocketEntry {
|
||||||
public static final Codec<PocketEntry> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
public static final Codec<PocketEntry> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
Codec.INT.fieldOf("size").forGetter(PocketEntry::getSize),
|
Codec.INT.fieldOf("size").forGetter(PocketEntry::getSize),
|
||||||
|
@ -101,4 +102,5 @@ public final class PocketType {
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
|
@ -6,22 +6,17 @@ import java.net.URISyntaxException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.*;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dimdev.dimdoors.util.WeightedSet;
|
||||||
import org.dimdev.dimdoors.util.schematic.v2.Schematic;
|
import org.dimdev.dimdoors.util.schematic.v2.Schematic;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
@ -31,9 +26,9 @@ public class SchematicV2Handler {
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create();
|
private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create();
|
||||||
private static final SchematicV2Handler INSTANCE = new SchematicV2Handler();
|
private static final SchematicV2Handler INSTANCE = new SchematicV2Handler();
|
||||||
private final List<PocketTemplateV2> templates = Lists.newArrayList();
|
private final Map<Identifier, PocketTemplateV2> templates = Maps.newHashMap();
|
||||||
private final Multimap<String, PocketTemplateV2> templateMap = HashMultimap.create();
|
private final Map<String, WeightedSet<VirtualPocket>> templateMap = Maps.newHashMap(); //TODO: un-ugly-fy
|
||||||
private final List<PocketType> pocketTypes = Lists.newArrayList();
|
private final List<PocketGroup> pocketTypes = Lists.newArrayList();
|
||||||
private static final Random RANDOM = new Random(new Random().nextLong());
|
private static final Random RANDOM = new Random(new Random().nextLong());
|
||||||
private boolean loaded = false;
|
private boolean loaded = false;
|
||||||
|
|
||||||
|
@ -58,7 +53,7 @@ public class SchematicV2Handler {
|
||||||
result.add(line);
|
result.add(line);
|
||||||
}
|
}
|
||||||
JsonObject json = GSON.fromJson(String.join("", result), JsonObject.class);
|
JsonObject json = GSON.fromJson(String.join("", result), JsonObject.class);
|
||||||
PocketType type = PocketType.CODEC.decode(JsonOps.INSTANCE, json).getOrThrow(false, System.err::println).getFirst();
|
PocketGroup type = PocketGroup.CODEC.decode(JsonOps.INSTANCE, json).getOrThrow(false, System.err::println).getFirst();
|
||||||
this.pocketTypes.add(type);
|
this.pocketTypes.add(type);
|
||||||
this.loadResourceSchematics(type);
|
this.loadResourceSchematics(type);
|
||||||
} catch (IOException | URISyntaxException e) {
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
@ -69,40 +64,51 @@ public class SchematicV2Handler {
|
||||||
LOGGER.info("Loaded schematics in {} seconds", System.currentTimeMillis() - startTime);
|
LOGGER.info("Loaded schematics in {} seconds", System.currentTimeMillis() - startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadResourceSchematics(PocketType type) throws URISyntaxException, IOException {
|
/*
|
||||||
|
TODO: Change, is currently ugly.
|
||||||
|
Maybe request schematic from within VirtualSchematicPocket#init() and add default void init() to VirtualPocket?
|
||||||
|
*/
|
||||||
|
private void loadResourceSchematics(PocketGroup type) throws URISyntaxException, IOException {
|
||||||
String group = type.getGroup();
|
String group = type.getGroup();
|
||||||
|
WeightedSet<VirtualPocket> weightedPockets = new WeightedSet<>();
|
||||||
|
templateMap.put(group, weightedPockets);
|
||||||
Path basePath = Paths.get(SchematicV2Handler.class.getResource(String.format("/data/dimdoors/pockets/schematic/v2/%s/", group)).toURI());
|
Path basePath = Paths.get(SchematicV2Handler.class.getResource(String.format("/data/dimdoors/pockets/schematic/v2/%s/", group)).toURI());
|
||||||
for (PocketType.PocketEntry entry : type.getEntries()) {
|
for (VirtualPocket virtualPocket : type.getEntries()) {
|
||||||
Path schemPath = basePath.resolve(entry.getName() + ".schem");
|
weightedPockets.add(virtualPocket, virtualPocket.getWeight());
|
||||||
CompoundTag schemTag = NbtIo.readCompressed(Files.newInputStream(schemPath));
|
if (virtualPocket instanceof VirtualSchematicPocket) {
|
||||||
Schematic schematic = Schematic.fromTag(schemTag);
|
VirtualSchematicPocket schemPocket = (VirtualSchematicPocket) virtualPocket;
|
||||||
for (int i = 0; i < entry.getWeight(); i++) {
|
Path schemPath = basePath.resolve(schemPocket.getName() + ".schem");
|
||||||
this.templateMap.put(group, new PocketTemplateV2(schematic, group, entry.getSize(), entry.getName(), entry.getWeight()));
|
CompoundTag schemTag = NbtIo.readCompressed(Files.newInputStream(schemPath));
|
||||||
}
|
Schematic schematic = Schematic.fromTag(schemTag);
|
||||||
|
PocketTemplateV2 template = new PocketTemplateV2(schematic, group, schemPocket.getSize(), schemPocket.getName(), schemPocket.getWeight());
|
||||||
|
Identifier templateID = new Identifier("dimdoors", schemPocket.getName());
|
||||||
|
templates.put(templateID, template);
|
||||||
|
schemPocket.setTemplateID(templateID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketTemplateV2 getRandomPublicPocket() {
|
public VirtualPocket getRandomPublicPocket() {
|
||||||
Collection<PocketTemplateV2> publicPockets = this.templateMap.get("public");
|
return getRandomPocketFromGroup("public");
|
||||||
int index = RANDOM.nextInt(publicPockets.size());
|
|
||||||
return Lists.newArrayList(publicPockets).get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PocketTemplateV2 getRandomPrivatePocket() {
|
public VirtualPocket getRandomPrivatePocket() {
|
||||||
Collection<PocketTemplateV2> publicPockets = this.templateMap.get("private");
|
return getRandomPocketFromGroup("private");
|
||||||
int index = RANDOM.nextInt(publicPockets.size());
|
|
||||||
return Lists.newArrayList(publicPockets).get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VirtualPocket getRandomPocketFromGroup(String group) {
|
||||||
|
return templateMap.get(group).getRandomWeighted();
|
||||||
|
}
|
||||||
|
|
||||||
public static SchematicV2Handler getInstance() {
|
public static SchematicV2Handler getInstance() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PocketTemplateV2> getTemplates() {
|
public Map<Identifier, PocketTemplateV2> getTemplates() {
|
||||||
return this.templates;
|
return this.templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PocketType> getPocketTypes() {
|
public List<PocketGroup> getPocketTypes() {
|
||||||
return this.pocketTypes;
|
return this.pocketTypes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
52
src/main/java/org/dimdev/dimdoors/pockets/VirtualPocket.java
Normal file
52
src/main/java/org/dimdev/dimdoors/pockets/VirtualPocket.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package org.dimdev.dimdoors.pockets;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.mojang.serialization.*;
|
||||||
|
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
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.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 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
|
||||||
|
public <T> DataResult<Pair<VirtualPocket, T>> decode(DynamicOps<T> dynamicOps, T input) {
|
||||||
|
Identifier id = Identifier.CODEC.decode(dynamicOps, dynamicOps.get(input, "virtual_type").getOrThrow(false, System.err::println)).getOrThrow(false, System.err::println).getFirst();
|
||||||
|
return REGISTRY.get(id).getCodec().decode(dynamicOps, dynamicOps.get(input, "properties").getOrThrow(false, System.err::println)).map(pair -> pair.mapFirst(virtualPocket -> (VirtualPocket) virtualPocket)); // TODO: can you use forField() here?
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> DataResult<T> encode(VirtualPocket input, DynamicOps<T> ops, T prefix) {
|
||||||
|
return null; // TODO: write encode function
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public abstract Pocket prepareAndPlacePocket(ServerWorld world, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties);
|
||||||
|
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);
|
||||||
|
|
||||||
|
Codec<T> getCodec();
|
||||||
|
|
||||||
|
static void register() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends VirtualPocket> VirtualPocketType<T> register(String id, Codec<T> codec) {
|
||||||
|
return Registry.register(REGISTRY, id, () -> codec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package org.dimdev.dimdoors.pockets;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
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.world.pocket.Pocket;
|
||||||
|
import org.dimdev.dimdoors.world.pocket.VirtualLocation;
|
||||||
|
|
||||||
|
public class VirtualSchematicPocket extends VirtualPocket{
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
|
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)
|
||||||
|
).apply(instance, VirtualSchematicPocket::new));
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
private final String name;
|
||||||
|
private Identifier templateID;
|
||||||
|
private final int weight;
|
||||||
|
|
||||||
|
VirtualSchematicPocket(int size, String name, int weight) {
|
||||||
|
this.size = size;
|
||||||
|
this.name = name;
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier getTemplateID() {
|
||||||
|
return templateID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTemplateID(Identifier templateID) {
|
||||||
|
this.templateID = templateID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWeight() {
|
||||||
|
return this.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pocket prepareAndPlacePocket(ServerWorld world, VirtualLocation virtualLocation, VirtualTarget linkTo, LinkProperties linkProperties) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
Pocket pocket = DimensionalRegistry.getPocketDirectory(world.getRegistryKey()).newPocket();
|
||||||
|
template.place(pocket);
|
||||||
|
template.setup(pocket, linkTo, linkProperties);
|
||||||
|
pocket.virtualLocation = virtualLocation;
|
||||||
|
return pocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PocketEntry{" +
|
||||||
|
"size=" + this.size +
|
||||||
|
", name='" + this.name + '\'' +
|
||||||
|
", weight=" + this.weight +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VirtualPocketType<? extends VirtualPocket> getType() {
|
||||||
|
return VirtualPocketType.SCHEMATIC;
|
||||||
|
}
|
||||||
|
}
|
69
src/main/java/org/dimdev/dimdoors/util/WeightedSet.java
Normal file
69
src/main/java/org/dimdev/dimdoors/util/WeightedSet.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,44 +2,68 @@
|
||||||
"group": "private",
|
"group": "private",
|
||||||
"pockets": [
|
"pockets": [
|
||||||
{
|
{
|
||||||
"id": "private_pocket_0",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 0,
|
"properties": {
|
||||||
"weight": 20
|
"id": "private_pocket_0",
|
||||||
|
"size": 0,
|
||||||
|
"weight": 20
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "private_pocket_1",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 1,
|
"properties": {
|
||||||
"weight": 17
|
"id": "private_pocket_1",
|
||||||
|
"size": 1,
|
||||||
|
"weight": 17
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "private_pocket_2",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 2,
|
"properties": {
|
||||||
"weight": 14
|
"id": "private_pocket_2",
|
||||||
|
"size": 2,
|
||||||
|
"weight": 14
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "private_pocket_3",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 3,
|
"properties": {
|
||||||
"weight": 11
|
"id": "private_pocket_3",
|
||||||
|
"size": 3,
|
||||||
|
"weight": 11
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "private_pocket_4",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 4,
|
"properties": {
|
||||||
"weight": 8
|
"id": "private_pocket_4",
|
||||||
|
"size": 4,
|
||||||
|
"weight": 8
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "private_pocket_5",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 5,
|
"properties": {
|
||||||
"weight": 5
|
"id": "private_pocket_5",
|
||||||
|
"size": 5,
|
||||||
|
"weight": 5
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "private_pocket_6",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 6,
|
"properties": {
|
||||||
"weight": 3
|
"id": "private_pocket_6",
|
||||||
|
"size": 6,
|
||||||
|
"weight": 3
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "private_pocket_7",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 7,
|
"properties": {
|
||||||
"weight": 1
|
"id": "private_pocket_7",
|
||||||
|
"size": 7,
|
||||||
|
"weight": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,44 +2,68 @@
|
||||||
"group": "public",
|
"group": "public",
|
||||||
"pockets": [
|
"pockets": [
|
||||||
{
|
{
|
||||||
"id": "public_pocket_0",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 0,
|
"properties": {
|
||||||
"weight": 20
|
"id": "public_pocket_0",
|
||||||
|
"size": 0,
|
||||||
|
"weight": 20
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "public_pocket_1",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 1,
|
"properties": {
|
||||||
"weight": 17
|
"id": "public_pocket_1",
|
||||||
|
"size": 1,
|
||||||
|
"weight": 17
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "public_pocket_2",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 2,
|
"properties": {
|
||||||
"weight": 14
|
"id": "public_pocket_2",
|
||||||
|
"size": 2,
|
||||||
|
"weight": 14
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "public_pocket_3",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 3,
|
"properties": {
|
||||||
"weight": 11
|
"id": "public_pocket_3",
|
||||||
|
"size": 3,
|
||||||
|
"weight": 11
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "public_pocket_4",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 4,
|
"properties": {
|
||||||
"weight": 8
|
"id": "public_pocket_4",
|
||||||
|
"size": 4,
|
||||||
|
"weight": 8
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "public_pocket_5",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 5,
|
"properties": {
|
||||||
"weight": 5
|
"id": "public_pocket_5",
|
||||||
|
"size": 5,
|
||||||
|
"weight": 5
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "public_pocket_6",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 6,
|
"properties": {
|
||||||
"weight": 3
|
"id": "public_pocket_6",
|
||||||
|
"size": 6,
|
||||||
|
"weight": 3
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "public_pocket_7",
|
"virtual_type": "dimdoors:schematic",
|
||||||
"size": 7,
|
"properties": {
|
||||||
"weight": 1
|
"id": "public_pocket_7",
|
||||||
|
"size": 7,
|
||||||
|
"weight": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue