Partial Dungeon Pack and Configurable Dungeon Chain Implementation #67
@@ -43,12 +43,15 @@ public class SchematicLoader
|
|||||||
if (dimList.get(destDimID).dungeonGenerator == null)
|
if (dimList.get(destDimID).dungeonGenerator == null)
|
||||||
{
|
{
|
||||||
//The following initialization code is based on code from ChunkProviderGenerate.
|
//The following initialization code is based on code from ChunkProviderGenerate.
|
||||||
//It makes our generation depend on the world seed.
|
//It makes our generation depend on the world seed. We have an additional seed here
|
||||||
|
//to prevent correlations between the selected dungeons and the locations of gateways.
|
||||||
|
//TODO: We should centralize RNG initialization and world-seed modifiers for each specific application.
|
||||||
|
|
||||||
Random random = new Random(world.getSeed());
|
final long localSeed = world.getSeed() ^ 0x2F50DB9B4A8057E4L;
|
||||||
long factorA = random.nextLong() / 2L * 2L + 1L;
|
final Random random = new Random();
|
||||||
long factorB = random.nextLong() / 2L * 2L + 1L;
|
final long factorA = random.nextLong() / 2L * 2L + 1L;
|
||||||
random.setSeed((link.destXCoord >> 4) * factorA + (link.destZCoord >> 4) * factorB ^ world.getSeed());
|
final long factorB = random.nextLong() / 2L * 2L + 1L;
|
||||||
|
random.setSeed((link.destXCoord >> 4) * factorA + (link.destZCoord >> 4) * factorB ^ localSeed);
|
||||||
|
|
||||||
dungeonHelper.generateDungeonLink(link, dungeonHelper.RuinsPack, random);
|
dungeonHelper.generateDungeonLink(link, dungeonHelper.RuinsPack, random);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ public class DungeonChainRule
|
|||||||
ArrayList<String> conditionNames = source.getCondition();
|
ArrayList<String> conditionNames = source.getCondition();
|
||||||
ArrayList<WeightedContainer<String>> productNames = source.getProducts();
|
ArrayList<WeightedContainer<String>> productNames = source.getProducts();
|
||||||
|
|
||||||
|
//Obtain the IDs of dungeon types in reverse order. Reverse order makes comparing against chain histories easy.
|
||||||
condition = new int[conditionNames.size()];
|
condition = new int[conditionNames.size()];
|
||||||
for (int k = 0; k < condition.length; k++)
|
for (int src = 0, dst = condition.length - 1; src < condition.length; src++, dst--)
|
||||||
{
|
{
|
||||||
condition[k] = nameToTypeMapping.get(conditionNames.get(k)).ID;
|
condition[dst] = nameToTypeMapping.get(conditionNames.get(src)).ID;
|
||||||
}
|
}
|
||||||
products = new ArrayList<WeightedContainer<DungeonType>>();
|
products = new ArrayList<WeightedContainer<DungeonType>>(productNames.size());
|
||||||
for (WeightedContainer<String> product : productNames)
|
for (WeightedContainer<String> product : productNames)
|
||||||
{
|
{
|
||||||
products.add(new WeightedContainer<DungeonType>(nameToTypeMapping.get(product.getData()), product.itemWeight ));
|
products.add(new WeightedContainer<DungeonType>(nameToTypeMapping.get(product.getData()), product.itemWeight ));
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ public class DungeonPack
|
|||||||
//List which dungeons are allowed
|
//List which dungeons are allowed
|
||||||
ArrayList<DungeonGenerator> candidates;
|
ArrayList<DungeonGenerator> candidates;
|
||||||
ArrayList<DungeonGenerator> group = groupedDungeons.get(nextType.ID);
|
ArrayList<DungeonGenerator> group = groupedDungeons.get(nextType.ID);
|
||||||
if (excludedDungeons != null)
|
if (excludedDungeons != null && !excludedDungeons.isEmpty())
|
||||||
{
|
{
|
||||||
candidates = new ArrayList<DungeonGenerator>(group.size());
|
candidates = new ArrayList<DungeonGenerator>(group.size());
|
||||||
for (DungeonGenerator dungeon : group)
|
for (DungeonGenerator dungeon : group)
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -423,32 +425,72 @@ public class DungeonHelper
|
|||||||
//manipulate the output of this function by setting up links to mislead our algorithm or by removing links.
|
//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 MUST have built-in records of their parent dimensions in the future. ~SenseiKiwi
|
||||||
|
|
||||||
dimHelper helper = dimHelper.instance;
|
|
||||||
ArrayList<DungeonGenerator> history = new ArrayList<DungeonGenerator>();
|
ArrayList<DungeonGenerator> history = new ArrayList<DungeonGenerator>();
|
||||||
DimData tailDim = helper.getDimData(helper.getLinkDataFromCoords(dimData.exitDimLink.destXCoord, dimData.exitDimLink.destYCoord, dimData.exitDimLink.destZCoord, dimData.exitDimLink.destDimID).destDimID);
|
DimData tailDim = dimData;
|
||||||
|
boolean found = true;
|
||||||
|
|
||||||
for (int count = 0; count < maxSize; count++)
|
if (dimData.dungeonGenerator == null || dimData.dungeonGenerator.getDungeonType().Owner != pack || maxSize < 1)
|
||||||
{
|
{
|
||||||
if (tailDim.dungeonGenerator == null || tailDim.dungeonGenerator.getDungeonType().Owner != pack)
|
//The initial dimension is already outside our pack. Return an empty list.
|
||||||
{
|
return history;
|
||||||
//We've reached a dimension that doesn't belong to our pack. Stop the search here.
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
history.add(dimData.dungeonGenerator);
|
||||||
|
|
||||||
history.add(tailDim.dungeonGenerator);
|
for (int count = 1; count < maxSize && found; count++)
|
||||||
if (count + 1 < maxSize)
|
|
||||||
{
|
{
|
||||||
|
found = false;
|
||||||
for (LinkData link : tailDim.getLinksInDim())
|
for (LinkData link : tailDim.getLinksInDim())
|
||||||
{
|
{
|
||||||
DimData nextDim = dimHelper.instance.getDimData(link.destDimID);
|
DimData neighbor = dimHelper.instance.getDimData(link.destDimID);
|
||||||
if (helper.getDimDepth(link.destDimID) == tailDim.depth + 1)
|
if (neighbor.depth == tailDim.depth - 1 && neighbor.dungeonGenerator != null &&
|
||||||
|
neighbor.dungeonGenerator.getDungeonType().Owner == pack)
|
||||||
{
|
{
|
||||||
tailDim = nextDim;
|
tailDim = neighbor;
|
||||||
|
history.add(tailDim.dungeonGenerator);
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return dungeons;
|
||||||
|
}
|
||||||
|
pendingDimensions.add(root);
|
||||||
|
checked.add(root);
|
||||||
|
|
||||||
|
while (dungeons.size() < maxSize && !pendingDimensions.isEmpty())
|
||||||
|
{
|
||||||
|
DimData current = pendingDimensions.remove();
|
||||||
|
for (LinkData link : current.getLinksInDim())
|
||||||
|
{
|
||||||
|
DimData child = helper.getDimData(link.destDimID);
|
||||||
|
if (child.depth == current.depth + 1 && child.dungeonGenerator != null && checked.add(child))
|
||||||
|
{
|
||||||
|
dungeons.add(child.dungeonGenerator);
|
||||||
|
pendingDimensions.add(child);
|
||||||
|
}
|
||||||
|
if (dungeons.size() == maxSize)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dungeons;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package StevenDimDoors.mod_pocketDim.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public abstract class BaseConfigurationProcessor<T>
|
||||||
|
{
|
||||||
|
public BaseConfigurationProcessor() { }
|
||||||
|
|
||||||
|
public boolean canRead()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canWrite()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T readFromFile(String path) throws FileNotFoundException, ConfigurationProcessingException
|
||||||
|
{
|
||||||
|
return readFromFile(new File(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T readFromFile(File file) throws FileNotFoundException, ConfigurationProcessingException
|
||||||
|
{
|
||||||
|
return readFromStream(new FileInputStream(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T readFromResource(String resourcePath) throws ConfigurationProcessingException
|
||||||
|
{
|
||||||
|
return readFromStream(this.getClass().getResourceAsStream(resourcePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract T readFromStream(InputStream inputStream) throws ConfigurationProcessingException;
|
||||||
|
|
||||||
|
public void writeToFile(File file, T data) throws FileNotFoundException, ConfigurationProcessingException
|
||||||
|
{
|
||||||
|
writeToStream(new FileOutputStream(file), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToFile(String path, T data) throws FileNotFoundException, ConfigurationProcessingException
|
||||||
|
{
|
||||||
|
writeToFile(new File(path), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void writeToStream(OutputStream outputStream, T data) throws ConfigurationProcessingException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package StevenDimDoors.mod_pocketDim.util;
|
||||||
|
|
||||||
|
public class ConfigurationProcessingException extends Exception
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -4525298050874891911L;
|
||||||
|
|
||||||
|
public ConfigurationProcessingException()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationProcessingException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigurationProcessingException(String message, Throwable cause)
|
||||||
|
{
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
schematics/ruins/rules.txt
Normal file
33
schematics/ruins/rules.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
Version 1
|
||||||
|
Types:
|
||||||
|
Hub
|
||||||
|
Trap
|
||||||
|
SimpleHall
|
||||||
|
ComplexHall
|
||||||
|
Exit
|
||||||
|
DeadEnd
|
||||||
|
Maze
|
||||||
|
|
||||||
|
Settings:
|
||||||
|
AllowRepetitionsInBranch = false
|
||||||
|
AllowPackChangeOut = true
|
||||||
|
AllowPackChangeIn = true
|
||||||
|
PackWeight = 100
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
Exit -> DeadEnd Exit
|
||||||
|
|
||||||
|
DeadEnd -> DeadEnd Exit
|
||||||
|
|
||||||
|
? ? ? ? ? ? ? ? -> Trap#20 SimpleHall#40 ComplexHall#10 Exit#20 DeadEnd#10
|
||||||
|
|
||||||
|
? ? ? ? -> Trap#18 SimpleHall#40 ComplexHall#10 Exit#18 DeadEnd#10 Hub#4
|
||||||
|
|
||||||
|
? ? ? -> ComplexHall Hub Trap SimpleHall Maze
|
||||||
|
|
||||||
|
? ? -> ComplexHall Hub Trap SimpleHall Maze
|
||||||
|
|
||||||
|
? -> ComplexHall#40 Hub#30 Trap#10 SimpleHall#10 Maze#10
|
||||||
|
|
||||||
|
-> ComplexHall#40 Hub#30 Trap#10 SimpleHall#10 Maze#10
|
||||||
Reference in New Issue
Block a user