THE UPDATE
Merging months of dev work into master. The update is playable, but untested.
This commit is contained in:
@@ -20,40 +20,24 @@ import java.util.regex.Pattern;
|
||||
import net.minecraft.util.WeightedRandom;
|
||||
import net.minecraft.world.World;
|
||||
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||
import StevenDimDoors.mod_pocketDim.DimData;
|
||||
import StevenDimDoors.mod_pocketDim.DungeonGenerator;
|
||||
import StevenDimDoors.mod_pocketDim.LinkData;
|
||||
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
||||
import StevenDimDoors.mod_pocketDim.core.DimLink;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonSchematic;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfig;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfigReader;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType;
|
||||
import StevenDimDoors.mod_pocketDim.items.itemDimDoor;
|
||||
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
|
||||
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
|
||||
import StevenDimDoors.mod_pocketDim.util.FileFilters;
|
||||
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
||||
|
||||
public class DungeonHelper
|
||||
{
|
||||
//TODO: File-handling functionality should be spun off to a helper class later
|
||||
private static class DirectoryFilter implements FileFilter
|
||||
{
|
||||
@Override
|
||||
public boolean accept(File file)
|
||||
{
|
||||
return file.isDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
private static class SchematicFileFilter implements FileFilter
|
||||
{
|
||||
@Override
|
||||
public boolean accept(File file)
|
||||
{
|
||||
return file.isFile() && file.getName().endsWith(SCHEMATIC_FILE_EXTENSION);
|
||||
}
|
||||
}
|
||||
|
||||
private static DungeonHelper instance = null;
|
||||
private static DDProperties properties = null;
|
||||
|
||||
@@ -62,8 +46,6 @@ public class DungeonHelper
|
||||
|
||||
public static final String SCHEMATIC_FILE_EXTENSION = ".schematic";
|
||||
|
||||
private static final String DEFAULT_UP_SCHEMATIC_PATH = "/schematics/core/simpleStairsUp.schematic";
|
||||
private static final String DEFAULT_DOWN_SCHEMATIC_PATH = "/schematics/core/simpleStairsDown.schematic";
|
||||
private static final String DEFAULT_ERROR_SCHEMATIC_PATH = "/schematics/core/somethingBroke.schematic";
|
||||
private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/mods/DimDoors/text/How_to_add_dungeons.txt";
|
||||
private static final String RUINS_PACK_PATH = "/schematics/ruins";
|
||||
@@ -86,16 +68,14 @@ public class DungeonHelper
|
||||
public static final short MAX_DUNGEON_HEIGHT = MAX_DUNGEON_WIDTH;
|
||||
public static final short MAX_DUNGEON_LENGTH = MAX_DUNGEON_WIDTH;
|
||||
|
||||
private ArrayList<DungeonGenerator> untaggedDungeons = new ArrayList<DungeonGenerator>();
|
||||
private ArrayList<DungeonGenerator> registeredDungeons = new ArrayList<DungeonGenerator>();
|
||||
private ArrayList<DungeonData> untaggedDungeons = new ArrayList<DungeonData>();
|
||||
private ArrayList<DungeonData> registeredDungeons = new ArrayList<DungeonData>();
|
||||
|
||||
private DungeonPack RuinsPack;
|
||||
private HashMap<String, DungeonPack> dungeonPackMapping = new HashMap<String, DungeonPack>();
|
||||
private ArrayList<DungeonPack> dungeonPackList = new ArrayList<DungeonPack>();
|
||||
|
||||
private DungeonGenerator defaultUp;
|
||||
private DungeonGenerator defaultDown;
|
||||
private DungeonGenerator defaultError;
|
||||
private DungeonData defaultError;
|
||||
|
||||
private DungeonHelper()
|
||||
{
|
||||
@@ -227,47 +207,34 @@ public class DungeonHelper
|
||||
}
|
||||
}
|
||||
|
||||
public List<DungeonGenerator> getRegisteredDungeons()
|
||||
public List<DungeonData> getRegisteredDungeons()
|
||||
{
|
||||
return Collections.unmodifiableList(this.registeredDungeons);
|
||||
}
|
||||
|
||||
public List<DungeonGenerator> getUntaggedDungeons()
|
||||
public List<DungeonData> getUntaggedDungeons()
|
||||
{
|
||||
return Collections.unmodifiableList(this.untaggedDungeons);
|
||||
}
|
||||
|
||||
public DungeonGenerator getDefaultErrorDungeon()
|
||||
public DungeonData getDefaultErrorDungeon()
|
||||
{
|
||||
return defaultError;
|
||||
}
|
||||
|
||||
public DungeonGenerator getDefaultUpDungeon()
|
||||
{
|
||||
return defaultUp;
|
||||
}
|
||||
|
||||
public DungeonGenerator getDefaultDownDungeon()
|
||||
{
|
||||
return defaultDown;
|
||||
}
|
||||
|
||||
public DungeonPack getDungeonPack(String name)
|
||||
{
|
||||
//TODO: This function might be obsolete after the new save format is implemented.
|
||||
return dungeonPackMapping.get(name.toUpperCase());
|
||||
}
|
||||
|
||||
public DungeonPack getDimDungeonPack(int dimensionID)
|
||||
private DungeonPack getDimDungeonPack(NewDimData data)
|
||||
{
|
||||
//FIXME: This function is a workaround to our current dungeon data limitations. Modify later.
|
||||
//The upcoming save format change and code overhaul will make this obsolete.
|
||||
|
||||
DungeonPack pack;
|
||||
DungeonGenerator generator = dimHelper.dimList.get(dimensionID).dungeonGenerator;
|
||||
if (generator != null)
|
||||
DungeonData dungeon = data.dungeon();
|
||||
if (dungeon != null)
|
||||
{
|
||||
pack = generator.getDungeonType().Owner;
|
||||
pack = dungeon.dungeonType().Owner;
|
||||
|
||||
//Make sure the pack isn't null. This can happen for dungeons with the special UNKNOWN type.
|
||||
if (pack == null)
|
||||
@@ -277,7 +244,7 @@ public class DungeonHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dimensionID == NETHER_DIMENSION_ID)
|
||||
if (data.id() == NETHER_DIMENSION_ID)
|
||||
{
|
||||
//TODO: Change this to the nether-side pack later ^_^
|
||||
pack = RuinsPack;
|
||||
@@ -290,21 +257,20 @@ public class DungeonHelper
|
||||
return pack;
|
||||
}
|
||||
|
||||
public LinkData createCustomDungeonDoor(World world, int x, int y, int z)
|
||||
public DimLink createCustomDungeonDoor(World world, int x, int y, int z)
|
||||
{
|
||||
//Create a link above the specified position. Link to a new pocket dimension.
|
||||
LinkData link = new LinkData(world.provider.dimensionId, 0, x, y + 1, z, x, y + 1, z, true, 3);
|
||||
link = dimHelper.instance.createPocket(link, true, false);
|
||||
NewDimData dimension = PocketManager.getDimensionData(world);
|
||||
DimLink link = dimension.createLink(x, y + 1, z, LinkTypes.POCKET,3);
|
||||
|
||||
//Place a Warp Door linked to that pocket
|
||||
itemDimDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.ExitDoor);
|
||||
ItemDimensionalDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.warpDoor);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
public boolean validateDungeonType(String type, DungeonPack pack)
|
||||
{
|
||||
//Check if the dungeon type is valid
|
||||
return pack.isKnownType(type);
|
||||
}
|
||||
|
||||
@@ -370,10 +336,10 @@ public class DungeonHelper
|
||||
int weight = (dungeonData.length == 4) ? Integer.parseInt(dungeonData[3]) : DEFAULT_DUNGEON_WEIGHT;
|
||||
|
||||
//Add this custom dungeon to the list corresponding to its type
|
||||
DungeonGenerator generator = new DungeonGenerator(weight, path, isOpen, dungeonType);
|
||||
DungeonData dungeon = new DungeonData(path, isInternal, dungeonType, isOpen, weight);
|
||||
|
||||
pack.addDungeon(generator);
|
||||
registeredDungeons.add(generator);
|
||||
pack.addDungeon(dungeon);
|
||||
registeredDungeons.add(dungeon);
|
||||
if (verbose)
|
||||
{
|
||||
System.out.println("Registered dungeon: " + name);
|
||||
@@ -385,7 +351,7 @@ public class DungeonHelper
|
||||
{
|
||||
System.out.println("The following dungeon name is invalid for its given pack. It will not be generated naturally: " + schematicPath);
|
||||
}
|
||||
untaggedDungeons.add(new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, path, true, DungeonType.UNKNOWN_TYPE));
|
||||
untaggedDungeons.add(new DungeonData(path, isInternal, DungeonType.UNKNOWN_TYPE, true, DEFAULT_DUNGEON_WEIGHT));
|
||||
System.out.println("Registered untagged dungeon: " + name);
|
||||
}
|
||||
}
|
||||
@@ -403,7 +369,7 @@ public class DungeonHelper
|
||||
File[] packFiles;
|
||||
ArrayList<String> packFilePaths;
|
||||
File directory = new File(path);
|
||||
SchematicFileFilter schematicFileFilter = new SchematicFileFilter();
|
||||
FileFilter schematicFileFilter = new FileFilters.FileExtensionFilter(SCHEMATIC_FILE_EXTENSION);
|
||||
|
||||
//Check that the Ruins pack has been loaded
|
||||
if (RuinsPack == null)
|
||||
@@ -427,7 +393,7 @@ public class DungeonHelper
|
||||
schematics = null; //Release memory
|
||||
|
||||
//Load the custom dungeon packs
|
||||
packDirectories = directory.listFiles(new DirectoryFilter());
|
||||
packDirectories = directory.listFiles(new FileFilters.DirectoryFilter());
|
||||
if (packDirectories != null)
|
||||
{
|
||||
//Loop through each directory, which is assumed to be a dungeon pack
|
||||
@@ -462,9 +428,7 @@ public class DungeonHelper
|
||||
{
|
||||
//Register the core schematics
|
||||
//These are used for debugging and in case of unusual errors while loading dungeons
|
||||
defaultUp = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_UP_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE);
|
||||
defaultDown = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_DOWN_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE);
|
||||
defaultError = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_ERROR_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE);
|
||||
defaultError = new DungeonData(DEFAULT_ERROR_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE, true, DEFAULT_DUNGEON_WEIGHT);
|
||||
|
||||
//Open the list of dungeons packaged with our mod and register their schematics
|
||||
registerBundledPack(BUNDLED_RUINS_LIST_PATH, RUINS_PACK_PATH, "Ruins", reader);
|
||||
@@ -530,9 +494,10 @@ public class DungeonHelper
|
||||
}
|
||||
}
|
||||
|
||||
public void generateDungeonLink(LinkData inbound, DungeonPack pack, Random random)
|
||||
public DungeonData selectDungeon(NewDimData dimension, Random random)
|
||||
{
|
||||
DungeonGenerator selection;
|
||||
DungeonPack pack = getDimDungeonPack(dimension);
|
||||
DungeonData selection;
|
||||
DungeonPackConfig config;
|
||||
DungeonPack selectedPack;
|
||||
|
||||
@@ -546,13 +511,13 @@ public class DungeonHelper
|
||||
{
|
||||
//Calculate the chance of switching to a different pack type
|
||||
int packSwitchChance;
|
||||
if (dimHelper.dimList.get(inbound.locDimID).depth == 0)
|
||||
if (dimension.depth() == 1)
|
||||
{
|
||||
packSwitchChance = START_PACK_SWITCH_CHANCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
packSwitchChance = MIN_PACK_SWITCH_CHANCE + (getPackDepth(inbound, pack) - 1) * PACK_SWITCH_CHANCE_PER_LEVEL;
|
||||
packSwitchChance = MIN_PACK_SWITCH_CHANCE + dimension.parent().packDepth() * PACK_SWITCH_CHANCE_PER_LEVEL;
|
||||
}
|
||||
|
||||
//Decide randomly whether to switch packs or not
|
||||
@@ -564,7 +529,7 @@ public class DungeonHelper
|
||||
}
|
||||
|
||||
//Pick the next dungeon
|
||||
selection = selectedPack.getNextDungeon(inbound, random);
|
||||
selection = selectedPack.getNextDungeon(dimension, random);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -580,7 +545,7 @@ public class DungeonHelper
|
||||
selection = defaultError;
|
||||
}
|
||||
}
|
||||
dimHelper.instance.getDimData(inbound.destDimID).dungeonGenerator = selection;
|
||||
return selection;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -621,16 +586,16 @@ public class DungeonHelper
|
||||
return sortedNames;
|
||||
}
|
||||
|
||||
private static ArrayList<String> parseDungeonNames(ArrayList<DungeonGenerator> dungeons)
|
||||
private static ArrayList<String> parseDungeonNames(ArrayList<DungeonData> dungeons)
|
||||
{
|
||||
String name;
|
||||
File schematic;
|
||||
ArrayList<String> names = new ArrayList<String>(dungeons.size());
|
||||
|
||||
for (DungeonGenerator dungeon : dungeons)
|
||||
for (DungeonData dungeon : dungeons)
|
||||
{
|
||||
//Retrieve the file name and strip off the file extension
|
||||
schematic = new File(dungeon.schematicPath);
|
||||
schematic = new File(dungeon.schematicPath());
|
||||
name = schematic.getName();
|
||||
name = name.substring(0, name.length() - SCHEMATIC_FILE_EXTENSION.length());
|
||||
names.add(name);
|
||||
@@ -638,102 +603,48 @@ public class DungeonHelper
|
||||
return names;
|
||||
}
|
||||
|
||||
public static ArrayList<DungeonGenerator> getDungeonChainHistory(DimData dimData, DungeonPack pack, int maxSize)
|
||||
public static ArrayList<DungeonData> getDungeonChainHistory(NewDimData dimension, DungeonPack pack, int maxSize)
|
||||
{
|
||||
//TODO: I've improved this code for the time being. However, searching across links is a flawed approach. A player could
|
||||
//manipulate the output of this function by setting up links to mislead our algorithm or by removing links.
|
||||
//Dimensions MUST have built-in records of their parent dimensions in the future. ~SenseiKiwi
|
||||
|
||||
ArrayList<DungeonGenerator> history = new ArrayList<DungeonGenerator>();
|
||||
DimData tailDim = dimData;
|
||||
boolean found = true;
|
||||
|
||||
if (dimData.dungeonGenerator == null || dimData.dungeonGenerator.getDungeonType().Owner != pack || maxSize < 1)
|
||||
if (dimension == null)
|
||||
{
|
||||
//The initial dimension is already outside our pack. Return an empty list.
|
||||
return history;
|
||||
throw new IllegalArgumentException("dimension cannot be null.");
|
||||
}
|
||||
history.add(dimData.dungeonGenerator);
|
||||
|
||||
for (int count = 1; count < maxSize && found; count++)
|
||||
int count = 0;
|
||||
NewDimData tail = dimension;
|
||||
DungeonData dungeon = tail.dungeon();
|
||||
ArrayList<DungeonData> history = new ArrayList<DungeonData>();
|
||||
|
||||
while (count < maxSize && dungeon != null && dungeon.dungeonType().Owner == pack)
|
||||
{
|
||||
found = false;
|
||||
for (LinkData link : tailDim.getLinksInDim())
|
||||
{
|
||||
DimData neighbor = dimHelper.instance.getDimData(link.destDimID);
|
||||
if (neighbor.depth == tailDim.depth - 1 && neighbor.dungeonGenerator != null &&
|
||||
neighbor.dungeonGenerator.getDungeonType().Owner == pack)
|
||||
{
|
||||
tailDim = neighbor;
|
||||
history.add(tailDim.dungeonGenerator);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
history.add(dungeon);
|
||||
tail = tail.parent();
|
||||
dungeon = tail.dungeon();
|
||||
count++;
|
||||
}
|
||||
return history;
|
||||
}
|
||||
|
||||
private static int getPackDepth(LinkData inbound, DungeonPack pack)
|
||||
public static ArrayList<DungeonData> getFlatDungeonTree(NewDimData dimension, int maxSize)
|
||||
{
|
||||
//TODO: I've improved this code for the time being. However, searching across links is a flawed approach. A player could
|
||||
//manipulate the output of this function by setting up links to mislead our algorithm or by removing links.
|
||||
//Dimensions MUST have built-in records of their parent dimensions in the future. ~SenseiKiwi
|
||||
//Dimensions should also just keep track of pack depth internally.
|
||||
NewDimData root = dimension;
|
||||
ArrayList<DungeonData> dungeons = new ArrayList<DungeonData>();
|
||||
Queue<NewDimData> pendingDimensions = new LinkedList<NewDimData>();
|
||||
|
||||
int packDepth = 1;
|
||||
DimData tailDim = dimHelper.dimList.get(inbound.destDimID);
|
||||
boolean found;
|
||||
|
||||
do
|
||||
{
|
||||
found = false;
|
||||
for (LinkData link : tailDim.getLinksInDim())
|
||||
{
|
||||
DimData neighbor = dimHelper.instance.getDimData(link.destDimID);
|
||||
if (neighbor.depth == tailDim.depth - 1 && neighbor.dungeonGenerator != null &&
|
||||
neighbor.dungeonGenerator.getDungeonType().Owner == pack)
|
||||
{
|
||||
tailDim = neighbor;
|
||||
found = true;
|
||||
packDepth++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (found);
|
||||
|
||||
return packDepth;
|
||||
}
|
||||
|
||||
public static ArrayList<DungeonGenerator> getFlatDungeonTree(DimData dimData, int maxSize)
|
||||
{
|
||||
//TODO: I've improved this code for the time being. However, searching across links is a flawed approach. A player could
|
||||
//manipulate the output of this function by setting up links to mislead our algorithm or by removing links.
|
||||
//Dimensions MUST have built-in records of their parent dimensions in the future. ~SenseiKiwi
|
||||
|
||||
dimHelper helper = dimHelper.instance;
|
||||
ArrayList<DungeonGenerator> dungeons = new ArrayList<DungeonGenerator>();
|
||||
DimData root = helper.getDimData(helper.getLinkDataFromCoords(dimData.exitDimLink.destXCoord, dimData.exitDimLink.destYCoord, dimData.exitDimLink.destZCoord, dimData.exitDimLink.destDimID).destDimID);
|
||||
HashSet<DimData> checked = new HashSet<DimData>();
|
||||
Queue<DimData> pendingDimensions = new LinkedList<DimData>();
|
||||
|
||||
if (root.dungeonGenerator == null)
|
||||
if (root.dungeon() == null)
|
||||
{
|
||||
return dungeons;
|
||||
}
|
||||
pendingDimensions.add(root);
|
||||
checked.add(root);
|
||||
|
||||
while (dungeons.size() < maxSize && !pendingDimensions.isEmpty())
|
||||
{
|
||||
DimData current = pendingDimensions.remove();
|
||||
for (LinkData link : current.getLinksInDim())
|
||||
NewDimData current = pendingDimensions.remove();
|
||||
for (NewDimData child : current.children())
|
||||
{
|
||||
DimData child = helper.getDimData(link.destDimID);
|
||||
if (child.depth == current.depth + 1 && child.dungeonGenerator != null && checked.add(child))
|
||||
if (child.dungeon() != null)
|
||||
{
|
||||
dungeons.add(child.dungeonGenerator);
|
||||
dungeons.add(child.dungeon());
|
||||
pendingDimensions.add(child);
|
||||
}
|
||||
if (dungeons.size() == maxSize)
|
||||
|
||||
Reference in New Issue
Block a user