Added Support for Missing Link Types
Added functions for generating destinations for some link types that we hadn't included yet - player-made exits, trapdoors, and dungeon exits. The player-made and dungeon exits still don't generate anything, but there's a single function where we can write up the code: DDTeleporter.generateSafeExit(). Also added some simple code for listing root dimensions in PocketManager. None of this has been tested yet!
This commit is contained in:
parent
03660699cf
commit
b795c411be
2 changed files with 99 additions and 17 deletions
|
@ -25,6 +25,7 @@ import cpw.mods.fml.common.registry.GameRegistry;
|
||||||
public class DDTeleporter
|
public class DDTeleporter
|
||||||
{
|
{
|
||||||
private static final Random random = new Random();
|
private static final Random random = new Random();
|
||||||
|
private static int END_DIMENSION_ID = 1;
|
||||||
public static int cooldown = 0;
|
public static int cooldown = 0;
|
||||||
|
|
||||||
private DDTeleporter() { }
|
private DDTeleporter() { }
|
||||||
|
@ -342,7 +343,7 @@ public class DDTeleporter
|
||||||
|
|
||||||
if (link.linkType() == LinkTypes.RANDOM)
|
if (link.linkType() == LinkTypes.RANDOM)
|
||||||
{
|
{
|
||||||
Point4D randomDestination = prepareRandomDestination();
|
Point4D randomDestination = getRandomDestination();
|
||||||
if (randomDestination != null)
|
if (randomDestination != null)
|
||||||
{
|
{
|
||||||
entity = teleportEntity(entity, randomDestination);
|
entity = teleportEntity(entity, randomDestination);
|
||||||
|
@ -358,16 +359,16 @@ public class DDTeleporter
|
||||||
|
|
||||||
private static boolean initializeDestination(DimLink link, DDProperties properties)
|
private static boolean initializeDestination(DimLink link, DDProperties properties)
|
||||||
{
|
{
|
||||||
//FIXME: Change this later to support rooms that have been wiped and must be regenerated.
|
// FIXME: Change this later to support rooms that have been wiped and must be regenerated.
|
||||||
//We might need to implement regeneration for REVERSE links as well.
|
// FIXME: Add code for restoring the destination-side door.
|
||||||
|
// We might need to implement regeneration for REVERSE links as well.
|
||||||
|
|
||||||
if (link.hasDestination())
|
if (link.hasDestination())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check the destination type and respond accordingly
|
// Check the destination type and respond accordingly
|
||||||
//FIXME: Add missing link types.
|
|
||||||
//FIXME: Add code for restoring the destination-side door.
|
|
||||||
switch (link.linkType())
|
switch (link.linkType())
|
||||||
{
|
{
|
||||||
case LinkTypes.DUNGEON:
|
case LinkTypes.DUNGEON:
|
||||||
|
@ -375,10 +376,11 @@ public class DDTeleporter
|
||||||
case LinkTypes.POCKET:
|
case LinkTypes.POCKET:
|
||||||
return PocketBuilder.generateNewPocket(link, properties);
|
return PocketBuilder.generateNewPocket(link, properties);
|
||||||
case LinkTypes.SAFE_EXIT:
|
case LinkTypes.SAFE_EXIT:
|
||||||
|
return generateSafeExit(link, properties);
|
||||||
case LinkTypes.DUNGEON_EXIT:
|
case LinkTypes.DUNGEON_EXIT:
|
||||||
return ;
|
return generateDungeonExit(link, properties);
|
||||||
case LinkTypes.UNSAFE_EXIT:
|
case LinkTypes.UNSAFE_EXIT:
|
||||||
return ;
|
return generateUnsafeExit(link);
|
||||||
case LinkTypes.NORMAL:
|
case LinkTypes.NORMAL:
|
||||||
case LinkTypes.REVERSE:
|
case LinkTypes.REVERSE:
|
||||||
case LinkTypes.RANDOM:
|
case LinkTypes.RANDOM:
|
||||||
|
@ -388,7 +390,7 @@ public class DDTeleporter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Point4D prepareRandomDestination()
|
private static Point4D getRandomDestination()
|
||||||
{
|
{
|
||||||
// Our aim is to return a random link's source point
|
// Our aim is to return a random link's source point
|
||||||
// so that a link of type RANDOM can teleport a player there.
|
// so that a link of type RANDOM can teleport a player there.
|
||||||
|
@ -397,10 +399,11 @@ public class DDTeleporter
|
||||||
// 1. Ignore links with their source inside a pocket dimension.
|
// 1. Ignore links with their source inside a pocket dimension.
|
||||||
// 2. Ignore links with link type RANDOM.
|
// 2. Ignore links with link type RANDOM.
|
||||||
|
|
||||||
|
// Iterate over the root dimensions. Pocket dimensions cannot be roots.
|
||||||
|
// Don't just pick a random root and a random link within that root
|
||||||
|
// because we want to have unbiased selection among all links.
|
||||||
ArrayList<Point4D> matches = new ArrayList<Point4D>();
|
ArrayList<Point4D> matches = new ArrayList<Point4D>();
|
||||||
for (NewDimData dimension : PocketManager.getDimensions())
|
for (NewDimData dimension : PocketManager.getRootDimensions())
|
||||||
{
|
|
||||||
if (!dimension.isPocketDimension())
|
|
||||||
{
|
{
|
||||||
for (DimLink link : dimension.getAllLinks())
|
for (DimLink link : dimension.getAllLinks())
|
||||||
{
|
{
|
||||||
|
@ -410,7 +413,6 @@ public class DDTeleporter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Pick a random point, if any is available
|
// Pick a random point, if any is available
|
||||||
if (!matches.isEmpty())
|
if (!matches.isEmpty())
|
||||||
|
@ -422,4 +424,67 @@ public class DDTeleporter
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean generateUnsafeExit(DimLink link)
|
||||||
|
{
|
||||||
|
// An unsafe exit teleports the user to exactly the same coordinates
|
||||||
|
// as the link source, except located at the dimension's root dimension.
|
||||||
|
// This is very risky, as we make no effort to clear an air pocket or
|
||||||
|
// place a platform at the destination. We also don't place a reverse
|
||||||
|
// link at the destination, so it's a one-way trip. Good luck!
|
||||||
|
|
||||||
|
// To avoid loops, don't generate a destination if the player is
|
||||||
|
// already in a non-pocket dimension.
|
||||||
|
|
||||||
|
NewDimData current = PocketManager.getDimensionData(link.source.getDimension());
|
||||||
|
if (current.isPocketDimension())
|
||||||
|
{
|
||||||
|
Point4D source = link.source();
|
||||||
|
current.root().setDestination(link, source.getX(), source.getY(), source.getZ());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean generateSafeExit(DimLink link, DDProperties properties)
|
||||||
|
{
|
||||||
|
NewDimData current = PocketManager.getDimensionData(link.source.getDimension());
|
||||||
|
return generateSafeExit(current.root(), link, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean generateDungeonExit(DimLink link, DDProperties properties)
|
||||||
|
{
|
||||||
|
// A dungeon exit acts the same as a safe exit, but has the chance of
|
||||||
|
// taking the user to any non-pocket dimension, excluding Limbo and The End.
|
||||||
|
|
||||||
|
ArrayList<NewDimData> roots = PocketManager.getRootDimensions();
|
||||||
|
for (int attempts = 0; attempts < 10; attempts++)
|
||||||
|
{
|
||||||
|
NewDimData selection = roots.get( random.nextInt(roots.size()) );
|
||||||
|
if (selection.id() != END_DIMENSION_ID && selection.id() != properties.LimboDimensionID)
|
||||||
|
{
|
||||||
|
return generateSafeExit(selection, link, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean generateSafeExit(NewDimData target, DimLink link, DDProperties properties)
|
||||||
|
{
|
||||||
|
// A safe exit attempts to place a Warp Door in a dimension with
|
||||||
|
// some precautions to protect the player. The X and Z coordinates
|
||||||
|
// are fixed to match the source, but the Y coordinate is chosen by
|
||||||
|
// searching for a safe location to place the door. The direction of
|
||||||
|
// the vertical search is away from the map boundary closest to
|
||||||
|
// the source Y. In other words, if a player is really high up, the
|
||||||
|
// search proceeds down. If a player is near the bottom of the map,
|
||||||
|
// the search proceeds up. If a safe destination cannot be found,
|
||||||
|
// then we return false and the source-side door slams shut.
|
||||||
|
|
||||||
|
// FIXME: Add code here!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -97,6 +98,7 @@ public class PocketManager
|
||||||
private static volatile boolean isSaving = false;
|
private static volatile boolean isSaving = false;
|
||||||
private static final UpdateWatcherProxy<Point4D> linkWatcher = new UpdateWatcherProxy<Point4D>();
|
private static final UpdateWatcherProxy<Point4D> linkWatcher = new UpdateWatcherProxy<Point4D>();
|
||||||
private static final UpdateWatcherProxy<ClientDimData> dimWatcher = new UpdateWatcherProxy<ClientDimData>();
|
private static final UpdateWatcherProxy<ClientDimData> dimWatcher = new UpdateWatcherProxy<ClientDimData>();
|
||||||
|
private static ArrayList<NewDimData> rootDimensions = null;
|
||||||
|
|
||||||
//HashMap that maps all the dimension IDs registered with DimDoors to their DD data.
|
//HashMap that maps all the dimension IDs registered with DimDoors to their DD data.
|
||||||
private static HashMap<Integer, InnerDimData> dimensionData = null;
|
private static HashMap<Integer, InnerDimData> dimensionData = null;
|
||||||
|
@ -123,6 +125,7 @@ public class PocketManager
|
||||||
|
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
dimensionData = new HashMap<Integer, InnerDimData>();
|
dimensionData = new HashMap<Integer, InnerDimData>();
|
||||||
|
rootDimensions = new ArrayList<NewDimData>();
|
||||||
|
|
||||||
//Register Limbo
|
//Register Limbo
|
||||||
DDProperties properties = DDProperties.instance();
|
DDProperties properties = DDProperties.instance();
|
||||||
|
@ -326,6 +329,10 @@ public class PocketManager
|
||||||
|
|
||||||
InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher);
|
InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher);
|
||||||
dimensionData.put(dimensionID, dimension);
|
dimensionData.put(dimensionID, dimension);
|
||||||
|
if (!dimension.isPocketDimension())
|
||||||
|
{
|
||||||
|
rootDimensions.add(dimension);
|
||||||
|
}
|
||||||
dimWatcher.onCreated(new ClientDimData(dimension));
|
dimWatcher.onCreated(new ClientDimData(dimension));
|
||||||
|
|
||||||
return dimension;
|
return dimension;
|
||||||
|
@ -336,6 +343,9 @@ public class PocketManager
|
||||||
// No need to raise events here since this code should only run on the client side
|
// No need to raise events here since this code should only run on the client side
|
||||||
// getDimensionData() always handles root dimensions properly, even if the weren't defined before
|
// getDimensionData() always handles root dimensions properly, even if the weren't defined before
|
||||||
|
|
||||||
|
// SenseiKiwi: I'm a little worried about how getDimensionData will raise
|
||||||
|
// an event when it creates any root dimensions... Needs checking later.
|
||||||
|
|
||||||
InnerDimData root = (InnerDimData) getDimensionData(rootID);
|
InnerDimData root = (InnerDimData) getDimensionData(rootID);
|
||||||
InnerDimData dimension;
|
InnerDimData dimension;
|
||||||
|
|
||||||
|
@ -381,6 +391,12 @@ public class PocketManager
|
||||||
return dimensionData.values();
|
return dimensionData.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static ArrayList<NewDimData> getRootDimensions()
|
||||||
|
{
|
||||||
|
return (ArrayList<NewDimData>) rootDimensions.clone();
|
||||||
|
}
|
||||||
|
|
||||||
public static void unload()
|
public static void unload()
|
||||||
{
|
{
|
||||||
if (!isLoaded)
|
if (!isLoaded)
|
||||||
|
@ -391,6 +407,7 @@ public class PocketManager
|
||||||
save();
|
save();
|
||||||
unregisterPockets();
|
unregisterPockets();
|
||||||
dimensionData = null;
|
dimensionData = null;
|
||||||
|
rootDimensions = null;
|
||||||
isLoaded = false;
|
isLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue