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
|
||||
{
|
||||
private static final Random random = new Random();
|
||||
private static int END_DIMENSION_ID = 1;
|
||||
public static int cooldown = 0;
|
||||
|
||||
private DDTeleporter() { }
|
||||
|
@ -342,7 +343,7 @@ public class DDTeleporter
|
|||
|
||||
if (link.linkType() == LinkTypes.RANDOM)
|
||||
{
|
||||
Point4D randomDestination = prepareRandomDestination();
|
||||
Point4D randomDestination = getRandomDestination();
|
||||
if (randomDestination != null)
|
||||
{
|
||||
entity = teleportEntity(entity, randomDestination);
|
||||
|
@ -358,16 +359,16 @@ public class DDTeleporter
|
|||
|
||||
private static boolean initializeDestination(DimLink link, DDProperties properties)
|
||||
{
|
||||
//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: Change this later to support rooms that have been wiped and must be regenerated.
|
||||
// FIXME: Add code for restoring the destination-side door.
|
||||
// We might need to implement regeneration for REVERSE links as well.
|
||||
|
||||
if (link.hasDestination())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//Check the destination type and respond accordingly
|
||||
//FIXME: Add missing link types.
|
||||
//FIXME: Add code for restoring the destination-side door.
|
||||
// Check the destination type and respond accordingly
|
||||
switch (link.linkType())
|
||||
{
|
||||
case LinkTypes.DUNGEON:
|
||||
|
@ -375,10 +376,11 @@ public class DDTeleporter
|
|||
case LinkTypes.POCKET:
|
||||
return PocketBuilder.generateNewPocket(link, properties);
|
||||
case LinkTypes.SAFE_EXIT:
|
||||
return generateSafeExit(link, properties);
|
||||
case LinkTypes.DUNGEON_EXIT:
|
||||
return ;
|
||||
return generateDungeonExit(link, properties);
|
||||
case LinkTypes.UNSAFE_EXIT:
|
||||
return ;
|
||||
return generateUnsafeExit(link);
|
||||
case LinkTypes.NORMAL:
|
||||
case LinkTypes.REVERSE:
|
||||
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
|
||||
// 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.
|
||||
// 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>();
|
||||
for (NewDimData dimension : PocketManager.getDimensions())
|
||||
{
|
||||
if (!dimension.isPocketDimension())
|
||||
for (NewDimData dimension : PocketManager.getRootDimensions())
|
||||
{
|
||||
for (DimLink link : dimension.getAllLinks())
|
||||
{
|
||||
|
@ -410,7 +413,6 @@ public class DDTeleporter
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pick a random point, if any is available
|
||||
if (!matches.isEmpty())
|
||||
|
@ -422,4 +424,67 @@ public class DDTeleporter
|
|||
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.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
@ -97,6 +98,7 @@ public class PocketManager
|
|||
private static volatile boolean isSaving = false;
|
||||
private static final UpdateWatcherProxy<Point4D> linkWatcher = new UpdateWatcherProxy<Point4D>();
|
||||
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.
|
||||
private static HashMap<Integer, InnerDimData> dimensionData = null;
|
||||
|
@ -123,6 +125,7 @@ public class PocketManager
|
|||
|
||||
isLoading = true;
|
||||
dimensionData = new HashMap<Integer, InnerDimData>();
|
||||
rootDimensions = new ArrayList<NewDimData>();
|
||||
|
||||
//Register Limbo
|
||||
DDProperties properties = DDProperties.instance();
|
||||
|
@ -326,6 +329,10 @@ public class PocketManager
|
|||
|
||||
InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher);
|
||||
dimensionData.put(dimensionID, dimension);
|
||||
if (!dimension.isPocketDimension())
|
||||
{
|
||||
rootDimensions.add(dimension);
|
||||
}
|
||||
dimWatcher.onCreated(new ClientDimData(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
|
||||
// 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 dimension;
|
||||
|
||||
|
@ -381,6 +391,12 @@ public class PocketManager
|
|||
return dimensionData.values();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArrayList<NewDimData> getRootDimensions()
|
||||
{
|
||||
return (ArrayList<NewDimData>) rootDimensions.clone();
|
||||
}
|
||||
|
||||
public static void unload()
|
||||
{
|
||||
if (!isLoaded)
|
||||
|
@ -391,6 +407,7 @@ public class PocketManager
|
|||
save();
|
||||
unregisterPockets();
|
||||
dimensionData = null;
|
||||
rootDimensions = null;
|
||||
isLoaded = false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue