Mapping coordinates to Pocket IDs and back
-Changed the Pocket placement algorithm. Instead of following a rectangular spiral path expanding outwards from (0;0), Pockets now get placed in a fan-shaped area expanding from (0;0) to (infinity;infinity). -Changed maximum configurable grid size and defaulted to that -Added a way to retrieve the Pocket ID from a Location -Schematic loading streams are only closed if they were opened to begin with -Added some easier ways of testing if a Dimension is a Pocket dimension
This commit is contained in:
parent
7574e61ede
commit
53568707f0
6 changed files with 134 additions and 41 deletions
|
@ -23,8 +23,8 @@ public class DDConfig {
|
|||
public static final boolean HAVE_CONFIG_DEFAULTS_BEEN_CHECKED_FOR_CORRECTNESS = false; //@todo check this at each non-alpha release. This field does not have a use in the mod itself, but should ensure that the developers of this mod, don't forget to reset the config defaults to the right values before releasing a non-alpha release
|
||||
|
||||
public static File configurationFolder;
|
||||
private static int pocketGridSize = 8;
|
||||
private static int maxPocketSize = 4;
|
||||
private static int pocketGridSize = 32;
|
||||
private static int maxPocketSize = 15;
|
||||
private static int privatePocketSize = 3;
|
||||
private static int publicPocketSize = 2;
|
||||
private static int baseDimID = 684;
|
||||
|
@ -68,17 +68,17 @@ public class DDConfig {
|
|||
//@todo a comment in the config files about how these values only influence new worlds
|
||||
Property prop;
|
||||
pocketGridSize = setConfigIntWithMaxAndMin(config, Configuration.CATEGORY_GENERAL, "pocketGridSize", pocketGridSize,
|
||||
"Sets how many chunks apart all pockets in pocket dimensions should be placed. [min: 4, max: 16, default: 8]", 4, 16);
|
||||
"Sets how many chunks apart all pockets in pocket dimensions should be placed. [min: 4, max: 32, default: 32]", 4, 32);
|
||||
DimDoors.log(DDConfig.class, "pocketGridSize was set to " + pocketGridSize);
|
||||
|
||||
maxPocketSize = setConfigIntWithMaxAndMin(config, Configuration.CATEGORY_GENERAL, "maxPocketSize", maxPocketSize,
|
||||
"Sets how deep and wide any pocket can be. [min: 1, max: pocketGridSize/2, default: 4]", 1, (int) (((double) pocketGridSize / 2) - 0.5));
|
||||
"Sets how deep and wide any pocket can be. [min: 0, max: pocketGridSize/2, default: 4]", 0, (int) (((double) pocketGridSize / 2) - 0.5));
|
||||
|
||||
privatePocketSize = setConfigIntWithMaxAndMin(config, Configuration.CATEGORY_GENERAL, "privatePocketSize", privatePocketSize,
|
||||
"Sets how deep and wide any personal pocket can be. [min: 1, max: maxPocketsSize, default: 3]", 1, maxPocketSize);
|
||||
"Sets how deep and wide any personal pocket can be. [min: 0, max: maxPocketsSize, default: 3]", 0, maxPocketSize);
|
||||
|
||||
publicPocketSize = setConfigIntWithMaxAndMin(config, Configuration.CATEGORY_GENERAL, "publicPocketSize", publicPocketSize,
|
||||
"Sets how deep and wide any public pocket can be. [min: 1, max: maxPocketsSize, default: 2]", 1, maxPocketSize);
|
||||
"Sets how deep and wide any public pocket can be. [min: 0, max: maxPocketsSize, default: 2]", 0, maxPocketSize);
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "dungeonSchematicNames", dungeonSchematicNames,
|
||||
"List of names of Pockets' jSon- and Schematic file names excluding extension. Custom json and schematic files can be dropped in the corresponding folders.");
|
||||
|
@ -109,9 +109,11 @@ public class DDConfig {
|
|||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "dangerousLimboMonolithsDisabled", DangerousLimboMonolithsDisabled,
|
||||
"Is Monoliths Dangerous in Limbo disabled?");
|
||||
DangerousLimboMonolithsDisabled = prop.getBoolean();
|
||||
|
||||
prop = config.get(Configuration.CATEGORY_GENERAL, "dangerousLimboMonolithsDisabled", MonolithTeleportationEnabled,
|
||||
"Is Monolith Teleportation disabled?");
|
||||
MonolithTeleportationEnabled = prop.getBoolean();
|
||||
|
||||
checkAndCorrectDoorRelativeDepths(config);
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import net.minecraft.world.WorldServer;
|
|||
public class Pocket {
|
||||
|
||||
private int ID; //this gets reset every server-load
|
||||
private final int size; //in chunks
|
||||
private final int size; //in chunks 0 -> 1*1 chunk, 1 -> 2*2 chunks
|
||||
private final int depth;
|
||||
private final EnumPocketType typeID; // dungeon, pocket, or personal pocket
|
||||
private final int x; //pocket-relative 0 coordinate, should be at x * PocketRegistry.INSTANCE.gridSize * 16
|
||||
|
@ -78,7 +78,7 @@ public class Pocket {
|
|||
|
||||
public void setID(int newID) {
|
||||
ID = newID;
|
||||
|
||||
|
||||
//propagate this ID to the rifts in this pocket
|
||||
for (int riftID : riftIDs) {
|
||||
Location riftLocation = RiftRegistry.INSTANCE.getRiftLocation(riftID);
|
||||
|
@ -103,9 +103,9 @@ public class Pocket {
|
|||
riftIDs.add(doorID);
|
||||
}
|
||||
Location depthZeroLocation = Location.readFromNBT(pocketNBT.getCompoundTag("depthZeroLocation"));
|
||||
|
||||
|
||||
Pocket pocket = new Pocket(size, depth, typeID, x, z, riftIDs, depthZeroLocation);
|
||||
|
||||
|
||||
pocket.setID(pocketNBT.getInteger("ID")); //basically re-register the pocket
|
||||
NBTTagList playersTagList = (NBTTagList) pocketNBT.getTag("playerUUIDs");
|
||||
for (int i = 0; i < playersTagList.tagCount(); i++) {
|
||||
|
@ -167,15 +167,34 @@ public class Pocket {
|
|||
|
||||
public void validatePlayerEntry(EntityPlayer player) {
|
||||
String playerUUID = player.getCachedUniqueIdString();
|
||||
for (String allowedPlayerUUID : playerUUIDs) {
|
||||
if (allowedPlayerUUID.equals(playerUUID)) {
|
||||
return;
|
||||
}
|
||||
if (!playerUUIDs.contains(playerUUID)) { //the 'contains' method uses the 'equals' method to check, so for Strings, this should work.
|
||||
playerUUIDs.add(playerUUID);
|
||||
}
|
||||
playerUUIDs.add(playerUUID);
|
||||
}
|
||||
|
||||
public boolean isPlayerAllowedInPocket(EntityPlayer player) {
|
||||
String playerUUID = player.getCachedUniqueIdString();
|
||||
return playerUUIDs.contains(playerUUID);
|
||||
}
|
||||
|
||||
public void setDepthZeroLocation(Location teleportTargetLocation) {
|
||||
depthZeroLocation.loadfrom(teleportTargetLocation);
|
||||
}
|
||||
|
||||
boolean isLocationWithinPocketBounds(final Location location, final int gridSize) {
|
||||
int locX = location.getPos().getX();
|
||||
int locZ = location.getPos().getY();
|
||||
//minimum bounds of the pocket
|
||||
int pocX = x * gridSize;
|
||||
int pocZ = z * gridSize;
|
||||
if (pocX <= locX && pocZ <= locZ) {
|
||||
//convert to maximum bounds of the pocket
|
||||
pocX = pocX + (size + 1) * 16;
|
||||
pocZ = pocZ + (size + 1) * 16;
|
||||
if (locX < pocX && locZ < pocZ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
|
||||
|
@ -136,11 +137,11 @@ public class PocketRegistry {
|
|||
nbt.setTag("nextUnusedIDs", nextUnusedIDTagCompound);
|
||||
|
||||
NBTTagCompound privatePocketsTagCompound = new NBTTagCompound();
|
||||
for (String UUID: privatePockets.keySet()) {
|
||||
for (String UUID : privatePockets.keySet()) {
|
||||
privatePocketsTagCompound.setInteger(UUID, privatePockets.get(UUID));
|
||||
}
|
||||
nbt.setTag("privatePockets", privatePocketsTagCompound);
|
||||
|
||||
|
||||
NBTTagCompound pocketsTagCompound = new NBTTagCompound();
|
||||
for (EnumPocketType pocketType : pocketLists.keySet()) {
|
||||
Map<Integer, Pocket> pocketList = pocketLists.get(pocketType);
|
||||
|
@ -197,7 +198,7 @@ public class PocketRegistry {
|
|||
|
||||
return generatePocketAt(typeID, depth, origRiftLocation, pocketTemplate);
|
||||
}
|
||||
|
||||
|
||||
public Pocket generatePocketAt(EnumPocketType typeID, int depth, Location origRiftLocation, PocketTemplate pocketTemplate) {
|
||||
//Getting the physical grid-location and the Overworld coordinates
|
||||
Location shortenedLocation = getGenerationlocation(nextUnusedIDs.get(typeID), typeID);
|
||||
|
@ -221,19 +222,32 @@ public class PocketRegistry {
|
|||
public int getPrivateDimDoorID(String playerUUID) {
|
||||
if (!privatePockets.containsKey(playerUUID)) {
|
||||
//generate a new private pocket
|
||||
int doorID = getEntranceDoorIDOfNewPocket(EnumPocketType.PRIVATE, 0, new Location(0,0,0,0)); //Location doesn't really matter in this case
|
||||
int doorID = getEntranceDoorIDOfNewPocket(EnumPocketType.PRIVATE, 0, new Location(0, 0, 0, 0)); //Location doesn't really matter in this case
|
||||
privatePockets.put(playerUUID, doorID);
|
||||
return doorID;
|
||||
}
|
||||
}
|
||||
return privatePockets.get(playerUUID);
|
||||
}
|
||||
|
||||
private Location getGenerationlocation(int nextUnusedID, EnumPocketType typeID) {
|
||||
int x = getSimpleX(nextUnusedID);
|
||||
private Location getGenerationlocation(final int nextUnusedID, EnumPocketType typeID) {
|
||||
int x;
|
||||
int y = 0;
|
||||
int z = getSimpleZ(nextUnusedID);
|
||||
int z;
|
||||
int dimID = DimDoorDimensions.getPocketDimensionType(typeID).getId();
|
||||
|
||||
if (nextUnusedID == 0) {
|
||||
x = 0;
|
||||
z = 0;
|
||||
} else {
|
||||
int radius = (int) Math.sqrt(nextUnusedID); //casting to int rounds down the double resulting from taking the square root
|
||||
int radiusNumber = nextUnusedID - (radius * radius);
|
||||
double splitter = ((double) radiusNumber) / ((double) radius); //always between 0 and 2
|
||||
DimDoors.log(this.getClass(), "id is " + nextUnusedID);
|
||||
DimDoors.log(this.getClass(), "Radius is " + radius);
|
||||
DimDoors.log(this.getClass(), "Radius number is " + radiusNumber);
|
||||
DimDoors.log(this.getClass(), "Splitter is " + splitter);
|
||||
x = splitter <= 1.0 ? radius : radius - (radiusNumber - radius);
|
||||
z = splitter >= 1.0 ? radius : radiusNumber;
|
||||
}
|
||||
Location location = new Location(dimID, x, y, z);
|
||||
return location;
|
||||
}
|
||||
|
@ -250,6 +264,7 @@ public class PocketRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private int getSimpleX(int ID) {
|
||||
//@todo check for smaller than 0
|
||||
if (ID == 0) {
|
||||
|
@ -300,4 +315,38 @@ public class PocketRegistry {
|
|||
}
|
||||
return group;
|
||||
}
|
||||
*/
|
||||
private int getPocketIDFromCoords(Location location) {
|
||||
final int dimID = location.getDimensionID();
|
||||
if (DimDoorDimensions.isPocketDimensionID(dimID)) {
|
||||
int x = location.getPos().getX();
|
||||
int z = location.getPos().getZ();
|
||||
int shortX = x / (gridSize * 16);
|
||||
int shortZ = z / (gridSize * 16);
|
||||
if (shortX >= shortZ) {
|
||||
return shortX * shortX + shortZ;
|
||||
} else {
|
||||
return (shortZ + 2) * shortZ - shortX;
|
||||
}
|
||||
}
|
||||
return -1; //not in a pocket dimension
|
||||
}
|
||||
|
||||
public boolean isPlayerAllowedToBeHere(final EntityPlayerMP player, final Location location) {
|
||||
if (player.isCreative()) {
|
||||
return true;
|
||||
} else {
|
||||
int pocketID = getPocketIDFromCoords(location);
|
||||
if (pocketID < 0) { //not in a pocket dimension
|
||||
return true;
|
||||
} else {
|
||||
EnumPocketType type = DimDoorDimensions.getPocketType(location.getDimensionID());
|
||||
Pocket pocket = pocketLists.get(type).get(pocketID);
|
||||
if (pocket.isPlayerAllowedInPocket(player) && pocket.isLocationWithinPocketBounds(location, gridSize)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class PocketTemplate { //there is exactly one pocket placer for each diff
|
|||
this.weights = weights; //chance that this Pocket will get generated
|
||||
this.minDepth = minDepth; //pocket will only be generated from this Pocket-depth
|
||||
this.maxDepth = maxDepth; //to this pocket depth
|
||||
this.size = size; //size of content of pocket in chunks (walls are 5 thick, so size 0 will be 6*6 blocks, size 1 will be 22*22 blocks, etc.
|
||||
this.size = size; //size of pocket in chunks (0 -> 1*1 chunk, 1 -> 2*2 chunks etc.)
|
||||
this.schematic = schematic;
|
||||
this.typeID = typeID;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class SchematicHandler {
|
|||
final private Map<String, Map<String, Integer>> dungeonNameMap = new HashMap();
|
||||
//@todo, sort templates by depth over here? that'd mean that that doesn't have to be done on pocket placement each and every time
|
||||
|
||||
PocketTemplate getRandomDungeonPocketTemplate(int depth, int maxPocketSize) {
|
||||
PocketTemplate getRandomDungeonPocketTemplate(int depth, int maxPocketSize) { //@todo maxPocketSize is passed for no reason at all here; pockets exceeding maxPocketSize have not been loaded in the first place...
|
||||
List<PocketTemplate> validTemplates = new ArrayList();
|
||||
int totalWeight = 0;
|
||||
for (PocketTemplate template : dungeonTemplates) {
|
||||
|
@ -168,7 +168,7 @@ public class SchematicHandler {
|
|||
//DimDoors.log(SchematicHandler.class, "Checkpoint 4 reached; " + validTemplates.size() + " templates were loaded");
|
||||
|
||||
String subDirectory = jsonTemplate.get("directory").getAsString(); //get the subfolder in which the schematics are stored
|
||||
|
||||
|
||||
for (PocketTemplate template : validTemplates) { //it's okay to "tap" this for-loop, even if validTemplates is empty.
|
||||
String extendedTemplatelocation = subDirectory.equals("") ? template.getName() : subDirectory + "/" + template.getName(); //transform the filename accordingly
|
||||
|
||||
|
@ -180,19 +180,24 @@ public class SchematicHandler {
|
|||
|
||||
//determine which location to load the schematic file from (and what format)
|
||||
DataInputStream schematicDataStream = null;
|
||||
boolean streamOpened = false;
|
||||
if (schematicStream != null) {
|
||||
schematicDataStream = new DataInputStream(schematicStream);
|
||||
streamOpened = true;
|
||||
} else if (oldVersionSchematicStream != null) {
|
||||
schematicDataStream = new DataInputStream(oldVersionSchematicStream);
|
||||
streamOpened = true;
|
||||
} else if (schematicFile.exists()) {
|
||||
try {
|
||||
schematicDataStream = new DataInputStream(new FileInputStream(schematicFile));
|
||||
streamOpened = true;
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file " + template.getName() + ".schem did not load correctly from config folder.", ex);
|
||||
}
|
||||
} else if (oldVersionSchematicFile.exists()) {
|
||||
try {
|
||||
schematicDataStream = new DataInputStream(new FileInputStream(oldVersionSchematicFile));
|
||||
streamOpened = true;
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file " + template.getName() + ".schematic did not load correctly from config folder.", ex);
|
||||
}
|
||||
|
@ -202,17 +207,19 @@ public class SchematicHandler {
|
|||
|
||||
NBTTagCompound schematicNBT;
|
||||
Schematic schematic = null;
|
||||
try {
|
||||
schematicNBT = CompressedStreamTools.readCompressed(schematicDataStream);
|
||||
schematic = Schematic.loadFromNBT(schematicNBT, template.getName());
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file for " + template.getName() + " could not be read as a valid schematic NBT file.", ex);
|
||||
} finally {
|
||||
if (streamOpened) {
|
||||
try {
|
||||
schematicNBT = CompressedStreamTools.readCompressed(schematicDataStream);
|
||||
schematic = Schematic.loadFromNBT(schematicNBT, template.getName());
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Error occured while closing schematicDataStream", ex);
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file for " + template.getName() + " could not be read as a valid schematic NBT file.", ex);
|
||||
} finally {
|
||||
try {
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Error occured while closing schematicDataStream", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,25 +17,32 @@ import net.minecraftforge.common.DimensionManager;
|
|||
public class DimDoorDimensions {
|
||||
|
||||
public static DimensionType LIMBO;
|
||||
private static Map<EnumPocketType, DimensionType> pocketDimensionTypes = new HashMap<>();
|
||||
public static List<DimensionType> CUSTOM;
|
||||
private static int minPocketDimID;
|
||||
private static int maxPocketDimID;
|
||||
private static final List<EnumPocketType> pocketTypes = new ArrayList<>();
|
||||
private static final Map<EnumPocketType, DimensionType> pocketDimensionTypes = new HashMap<>();
|
||||
private static final List<DimensionType> CUSTOM = new ArrayList<>();
|
||||
|
||||
public static void init() {
|
||||
int dimID = DDConfig.getBaseDimID();
|
||||
LIMBO = DimensionType.register("Limbo", "_limbo", dimID, WorldProviderLimbo.class, false);
|
||||
dimID++;
|
||||
dimID++; //@todo make this a loop over a function
|
||||
minPocketDimID = dimID;
|
||||
pocketTypes.add(EnumPocketType.PRIVATE);
|
||||
pocketDimensionTypes.put(EnumPocketType.PRIVATE, DimensionType.register("Private", "_private", dimID, WorldProviderPersonalPocket.class, false));
|
||||
dimID++;
|
||||
pocketTypes.add(EnumPocketType.PUBLIC);
|
||||
pocketDimensionTypes.put(EnumPocketType.PUBLIC, DimensionType.register("Public", "_public", dimID, WorldProviderPublicPocket.class, false));
|
||||
dimID++;
|
||||
maxPocketDimID = dimID;
|
||||
pocketTypes.add(EnumPocketType.DUNGEON);
|
||||
pocketDimensionTypes.put(EnumPocketType.DUNGEON, DimensionType.register("Dungeon", "_dungeon", dimID, WorldProviderDungeonPocket.class, false));
|
||||
|
||||
registerDimension(LIMBO);
|
||||
for(EnumPocketType pocketType: pocketDimensionTypes.keySet()) {
|
||||
for (EnumPocketType pocketType : pocketDimensionTypes.keySet()) {
|
||||
registerDimension(pocketDimensionTypes.get(pocketType));
|
||||
}
|
||||
|
||||
CUSTOM = new ArrayList<>();
|
||||
for (int i = 0; i < 0; i++) { //@todo: For future use? Like, server owners can add their own set of DimDoors DimensionTypes via the configs? Or is this nonsense?
|
||||
dimID++;
|
||||
DimensionType tempType = DimensionType.register("Name", "_name", dimID, WorldProvider.class, false);
|
||||
|
@ -47,8 +54,17 @@ public class DimDoorDimensions {
|
|||
public static void registerDimension(DimensionType dimension) {
|
||||
DimensionManager.registerDimension(dimension.getId(), dimension);
|
||||
}
|
||||
|
||||
|
||||
public static DimensionType getPocketDimensionType(EnumPocketType pocketType) {
|
||||
return pocketDimensionTypes.get(pocketType);
|
||||
}
|
||||
|
||||
public static boolean isPocketDimensionID(int id) {
|
||||
return id >= minPocketDimID && id <= maxPocketDimID;
|
||||
}
|
||||
|
||||
public static EnumPocketType getPocketType(int dimID) {
|
||||
int index = dimID - minPocketDimID;
|
||||
return pocketTypes.get(index);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue