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:
CreepyCre 2021-01-26 13:42:45 +01:00
parent edfc9d7b63
commit 34137d12b7
9 changed files with 363 additions and 116 deletions

View file

@ -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();
} }

View file

@ -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.
* *

View file

@ -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 {
'}'; '}';
} }
} }
*/
} }

View file

@ -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;
} }
} }

View 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);
}
}
}

View file

@ -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;
}
}

View 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());
}
}

View file

@ -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
}
} }
] ]
} }

View file

@ -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
}
} }
] ]
} }