13 Commits

Author SHA1 Message Date
StevenRS11
f2c585b568 Fixed door render 2014-05-05 13:55:17 -04:00
StevenRS11
363feac783 Merge pull request #155 from SenseiKiwi/mazes
Mazes
2014-04-15 07:46:00 -04:00
SenseiKiwi
fa629db4fe Progress on Maze Generation
* Implemented link creation based on link plans
* Improvised an implementation of door placement in DefaultDoorDecorator
for testing purposes. I'll provide a better version later.

Known issues:
1. Doors with one-way links to other rooms will generate a return door
at the destination. The return door doesn't actually lead back, it leads
to a new pocket. Need to disable pair generation for doors in mazes.
2. Consider weighing sections by the door capacity to avoid putting a
lot of doors into a small section. Also double-check that room selection
within sections is unbiased.
2014-04-15 07:40:44 -04:00
SenseiKiwi
77abcbb148 Progress on Maze Generation
* Increased the chance of decorating unprotected rooms from 1/4 to 1/3.
* Made minor optimizations to the box building function.
* Added some important arguments to BaseDecorator.decorate(). Also
updated all decorators as a result of this change.
* Implemented TorchDecorator so that mazes have light sources in them.
2014-04-15 05:14:38 -04:00
SenseiKiwi
f867f16d1d Fixed Maze Bug
Fixed a minor bug that affected maze decorators.
2014-04-15 01:46:39 -04:00
SenseiKiwi
bce329c8fb Added Maze Decorators
Added Decorators for use in mazes. I've added several decorators but all
of them are stubs for now.
2014-04-15 01:35:14 -04:00
SenseiKiwi
81b48158bd Progress on Maze Generation
* Finished implementing link planning for mazes. Doors aren't placed yet
because that's up to Decorators and those haven't been implemented yet.
* Added bounding walls to mazes.
* Added decay effects to mazes.
2014-04-14 22:24:59 -04:00
SenseiKiwi
906faf44eb Tweaked Maze Section Generation
Tweaked maze section generation to use a random MAX_DISTANCE for
including rooms in a section. Also changed the code to perform room
removals as sections are processed rather than deferring them to the
end. Deferring removals would cause the algorithm to detect holes from
rooms that were going to be removed. This made section generation much
stricter than necessary.
2014-04-13 16:17:42 -04:00
SenseiKiwi
53b5591149 Partial Implementation of Doors in Mazes
Made progress on implementing the placement of doors in mazes. Still
incomplete.
2014-04-11 19:28:05 -04:00
SenseiKiwi
f92020323f Partial Implementation of Doors in Mazes
Started implementing the placement of Dimensional Doors in mazes.
Currently, a design is guaranteed to have enough space for some doors.
MazeDesigner still needs more code to plan out which rooms will have
doors and where those doors will lead.
2014-04-08 06:40:45 -04:00
SenseiKiwi
935070e436 Minor Change
Minor correction to a comment in DirectedGraph
2014-04-08 06:34:45 -04:00
SenseiKiwi
5210de2e71 Hacked PocketBuilder to Generate Mazes
Made a minor change to PocketBuilder so that mazes generate instead of
regular pocket dimensions. I'm only doing this to test dungeon
generation - it'll get switched back once mazes are ready.
2014-04-07 09:39:10 -04:00
SenseiKiwi
d5e5e12cf9 Refactored Maze Generation to use RoomData
Rewrote portions of our maze generation code to use RoomData. This
provides an object that unifies all room data instead of having it
spread across various data structures and linked loosely by hash maps.
We'll need this to implement the remaining generation features.
2014-04-07 09:25:20 -04:00
160 changed files with 4027 additions and 5688 deletions

View File

@@ -13,15 +13,14 @@ buildscript {
apply plugin: 'forge'
version = "2.2.4-" + System.getenv("BUILD_NUMBER")
group = "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
version = "2.2.3-" + System.getenv("BUILD_NUMBER")
group= "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "DimensionalDoors"
minecraft {
version = "1.6.4-9.11.1.964"
replaceIn "mod_pocketDim.java"
replace "@VERSION@", project.version
}
targetCompatibility = '1.6'
@@ -29,15 +28,15 @@ sourceCompatibility = '1.6'
processResources
{
// Replace stuff $version and $mcversion in mcmod.info
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// Replace version and mcversion
// replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
}
// Copy everything else
// copy everything else, thats not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}

View File

@@ -165,8 +165,8 @@ public class DirectedGraph<U, V>
{
Edge<U, V> innerEdge = (Edge<U, V>) edge;
// Check that this node actually belongs to this graph instance.
// Accepting foreign nodes could corrupt the graph's internal state.
// Check that this edge actually belongs to this graph instance.
// Accepting foreign edges could corrupt the graph's internal state.
if (innerEdge.graphEntry.owner() != edges)
{
throw new IllegalArgumentException("The specified edge does not belong to this graph.");

View File

@@ -0,0 +1,120 @@
package StevenDimDoors.experimental;
import StevenDimDoors.mod_pocketDim.Point3D;
public class LinkPlan
{
private RoomData source;
private RoomData destination;
private Point3D sourcePoint;
private Point3D destinationPoint;
private final boolean entrance;
private final boolean internal;
private LinkPlan(RoomData source, boolean entrance, boolean internal)
{
if (source == null)
{
throw new IllegalArgumentException("source cannot be null.");
}
this.source = source;
this.destination = null;
this.sourcePoint = null;
this.destinationPoint = null;
this.entrance = entrance;
this.internal = internal;
}
public static LinkPlan createInternalLink(RoomData source)
{
LinkPlan plan = new LinkPlan(source, false, true);
source.getOutboundLinks().add(plan);
return plan;
}
public static LinkPlan createEntranceLink(RoomData source)
{
LinkPlan plan = new LinkPlan(source, true, false);
source.getOutboundLinks().add(plan);
return plan;
}
public static LinkPlan createDungeonLink(RoomData source)
{
LinkPlan plan = new LinkPlan(source, false, false);
source.getOutboundLinks().add(plan);
return plan;
}
public RoomData source()
{
return this.source;
}
public RoomData destination()
{
return this.destination;
}
public boolean isEntrance()
{
return entrance;
}
public boolean isInternal()
{
return internal;
}
public void remove()
{
if (source != null)
{
source.getOutboundLinks().remove(this);
source = null;
}
if (destination != null)
{
destination.getInboundLinks().remove(this);
destination = null;
}
}
public void setDestination(RoomData destination)
{
if (!internal)
{
throw new IllegalStateException("LinkPlan.setDestination() is only applicable to internal links.");
}
if (this.destination != null)
{
throw new IllegalStateException("destination can only be set once.");
}
if (destination == null)
{
throw new IllegalArgumentException("destination cannot be null.");
}
this.destination = destination;
destination.getInboundLinks().add(this);
}
public Point3D sourcePoint()
{
return this.sourcePoint;
}
public Point3D destinationPoint()
{
return this.destinationPoint;
}
public void setSourcePoint(Point3D value)
{
this.sourcePoint = value;
}
public void setDestinationPoint(Point3D value)
{
this.destinationPoint = value;
}
}

View File

@@ -1,63 +1,215 @@
package StevenDimDoors.experimental;
import java.util.ArrayList;
import java.util.Random;
import java.util.Stack;
import net.minecraft.block.Block;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import StevenDimDoors.experimental.decorators.BaseDecorator;
import StevenDimDoors.experimental.decorators.DecoratorFinder;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
public class MazeBuilder
{
private static final int POCKET_WALL_GAP = 4;
private static final int DECORATION_CHANCE = 1;
private static final int MAX_DECORATION_CHANCE = 3;
private MazeBuilder() { }
public static void generate(World world, int x, int y, int z, Random random)
public static void generate(World world, int x, int y, int z, Random random, DDProperties properties)
{
// ISSUE FOR LATER: The room needs to be shifted so as to be centered on its entrance
MazeDesign design = MazeDesigner.generate(random);
Point3D offset = new Point3D(x - design.width() / 2, y - design.height() - 1, z - design.length() / 2);
SphereDecayOperation decay = new SphereDecayOperation(random, 0, 0, Block.stoneBrick.blockID, 2);
buildRooms(design.getRoomGraph(), world, offset);
carveDoorways(design.getRoomGraph(), world, offset, decay, random);
//placeDoors(design, world, offset);
buildRooms(design.getLayout(), world, offset);
carveDoorways(design.getLayout(), world, offset, decay, random);
applyRandomDestruction(design, world, offset, decay, random);
decorateRooms(design.getLayout(), world, offset, random, properties);
buildPocketWalls(design, world, offset, properties);
}
private static void applyRandomDestruction(MazeDesign design, World world,
Point3D offset, SphereDecayOperation decay, Random random)
{
//final int DECAY_BOX_SIZE = 8
final int DECAY_BOX_SIZE = 7;
final int DECAY_OPERATIONS = 5 + random.nextInt(5);
final int DECAY_ATTEMPTS = 20;
int x, y, z;
int successes = 0;
int attempts = 0;
PartitionNode root = design.getRootPartition();
for (; successes < DECAY_OPERATIONS && attempts < DECAY_ATTEMPTS; attempts++)
{
// Select the coordinates at which to apply the decay operation
x = random.nextInt(design.width()) - DECAY_BOX_SIZE / 2;
y = random.nextInt(design.height()) - DECAY_BOX_SIZE / 2;
z = random.nextInt(design.length()) - DECAY_BOX_SIZE / 2;
// Check that the decay operation would not impact any protected areas
// and mark the affected areas as decayed
if (markDecayArea(x, y, z, DECAY_BOX_SIZE, root))
{
// Apply decay
decay.apply(world, offset.getX() + x, offset.getY() + y, offset.getZ() + z,
DECAY_BOX_SIZE, DECAY_BOX_SIZE, DECAY_BOX_SIZE);
successes++;
}
}
}
private static void buildRooms(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world, Point3D offset)
private static boolean markDecayArea(int x, int y, int z, int DECAY_BOX_SIZE, PartitionNode<RoomData> root)
{
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
// Check if a given PartitionNode intersects the decay area. If it's a leaf, then check
// if it's protected or not. Otherwise, check its children. The specific area is valid
// if and only if there are no protected rooms and at least one (unprotected) room in it.
// Also list the unprotected rooms to mark them if the decay operation will proceed.
RoomData room;
PartitionNode<RoomData> partition;
ArrayList<RoomData> targets = new ArrayList<RoomData>();
Stack<PartitionNode<RoomData>> nodes = new Stack<PartitionNode<RoomData>>();
BoundingBox decayBounds = new BoundingBox(x, y, z, DECAY_BOX_SIZE, DECAY_BOX_SIZE, DECAY_BOX_SIZE);
// Use depth-first search to explore all intersecting partitions
nodes.push(root);
while (!nodes.isEmpty())
{
PartitionNode room = node.data();
partition = nodes.pop();
if (decayBounds.intersects(partition))
{
if (partition.isLeaf())
{
room = partition.getData();
if (room.isProtected())
return false;
targets.add(room);
}
else
{
if (partition.leftChild() != null)
nodes.push(partition.leftChild());
if (partition.rightChild() != null)
nodes.push(partition.rightChild());
}
}
}
// If execution has reached this point, then there were no protected rooms.
// Mark all intersecting rooms as decayed.
for (RoomData target : targets)
{
target.setDecayed(true);
}
return !targets.isEmpty();
}
private static void buildRooms(DirectedGraph<RoomData, DoorwayData> layout, World world, Point3D offset)
{
for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{
PartitionNode room = node.data().getPartitionNode();
buildBox(world, offset, room.minCorner(), room.maxCorner(), Block.stoneBrick.blockID, 0);
}
}
private static void carveDoorways(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world,
private static void decorateRooms(DirectedGraph<RoomData, DoorwayData> layout,
World world, Point3D offset, Random random, DDProperties properties)
{
RoomData room;
BaseDecorator decorator;
PartitionNode<RoomData> partition;
ArrayList<LinkPlan> links = new ArrayList<LinkPlan>();
// Iterate over all rooms and apply decorators
for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{
room = node.data();
partition = room.getPartitionNode();
links.addAll(room.getOutboundLinks());
// Protected rooms must be decorated because they have links.
// Otherwise, choose randomly whether to decorate.
if (room.isProtected() || random.nextInt(MAX_DECORATION_CHANCE) < DECORATION_CHANCE)
{
decorator = DecoratorFinder.find(room, random);
if (decorator != null)
{
decorator.decorate(room, world, offset, random, properties);
}
}
}
// Iterate over all link plans and place links in the world
NewDimData dimension = PocketManager.getDimensionData(world);
for (LinkPlan plan : links)
{
createLinkFromPlan(plan, dimension, world);
}
}
private static void createLinkFromPlan(LinkPlan plan, NewDimData dimension, World world)
{
// TODO: Support entrances! Right now we'll treat them as dungeon doors for testing
DimLink link;
Point3D source;
Point3D destination;
int orientation;
source = plan.sourcePoint();
orientation = world.getBlockMetadata(source.getX(), source.getY(), source.getZ()) & 3;
// Check the link type and set the destination accordingly
if (plan.isInternal())
{
// Create a link between sections
destination = plan.destinationPoint();
link = dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.DUNGEON, orientation);
dimension.setDestination(link, destination.getX(), destination.getY(), destination.getZ());
}
else
{
// Create a dungeon link
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.DUNGEON, orientation);
}
}
private static void carveDoorways(DirectedGraph<RoomData, DoorwayData> layout, World world,
Point3D offset, SphereDecayOperation decay, Random random)
{
char axis;
Point3D lower;
DoorwayData doorway;
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{
for (IEdge<PartitionNode, DoorwayData> passage : node.outbound())
for (IEdge<RoomData, DoorwayData> passage : node.outbound())
{
// Carve out the passage
doorway = passage.data();
axis = doorway.axis();
lower = doorway.minCorner();
carveDoorway(world, axis, offset.getX() + lower.getX(), offset.getY() + lower.getY(),
offset.getZ() + lower.getZ(), doorway.width(), doorway.height(), doorway.length(),
decay, random);
// If this is a vertical passage, then mark the upper room as decayed
if (axis == DoorwayData.Y_AXIS)
{
passage.tail().data().setDecayed(true);
}
}
}
}
@@ -68,6 +220,8 @@ public class MazeBuilder
final int MIN_DOUBLE_DOOR_SPAN = 10;
int gap;
int rx;
int rz;
switch (axis)
{
case DoorwayData.X_AXIS:
@@ -132,9 +286,10 @@ public class MazeBuilder
{
gap = 6;
}
decay.apply(world,
x + random.nextInt(width - gap - 1) + 1, y - 1,
z + random.nextInt(length - gap - 1) + 1, gap, 4, gap);
rx = x + random.nextInt(width - gap - 1) + 1;
rz = z + random.nextInt(length - gap - 1) + 1;
carveHole(world, rx + gap / 2, y, rz + gap / 2);
decay.apply(world, rx, y - 1, rz, gap, 4, gap);
}
else
{
@@ -166,6 +321,18 @@ public class MazeBuilder
setBlockDirectly(world, x, y + 1, z, 0, 0);
}
private static void buildPocketWalls(MazeDesign design, World world, Point3D offset, DDProperties properties)
{
// Build the inner Fabric of Reality box
Point3D minCorner = new Point3D(-POCKET_WALL_GAP - 1, -POCKET_WALL_GAP - 1, -POCKET_WALL_GAP - 1);
Point3D maxCorner = new Point3D(design.width() + POCKET_WALL_GAP, design.height() + POCKET_WALL_GAP, design.length() + POCKET_WALL_GAP);
buildBox(world, offset, minCorner, maxCorner, properties.FabricBlockID, 0);
// Build the outer Eternal Fabric box
minCorner.add(-1, -1, -1);
maxCorner.add(1, 1, 1);
buildBox(world, offset, minCorner, maxCorner, properties.PermaFabricBlockID, 0);
}
private static void buildBox(World world, Point3D offset, Point3D minCorner, Point3D maxCorner, int blockID, int metadata)
{
@@ -189,15 +356,15 @@ public class MazeBuilder
}
for (x = minX; x <= maxX; x++)
{
for (y = minY; y <= maxY; y++)
for (y = minY + 1; y < maxY; y++)
{
setBlockDirectly(world, x, y, minZ, blockID, metadata);
setBlockDirectly(world, x, y, maxZ, blockID, metadata);
}
}
for (z = minZ; z <= maxZ; z++)
for (z = minZ + 1; z < maxZ; z++)
{
for (y = minY; y <= maxY; y++)
for (y = minY + 1; y < maxY; y++)
{
setBlockDirectly(world, minX, y, z, blockID, metadata);
setBlockDirectly(world, maxX, y, z, blockID, metadata);

View File

@@ -4,37 +4,23 @@ import java.util.ArrayList;
public class MazeDesign
{
private PartitionNode root;
private DirectedGraph<PartitionNode, DoorwayData> rooms;
private ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores;
private ArrayList<BoundingBox> protectedAreas;
private PartitionNode<RoomData> root;
private DirectedGraph<RoomData, DoorwayData> layout;
public MazeDesign(PartitionNode root, DirectedGraph<PartitionNode, DoorwayData> rooms,
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores)
public MazeDesign(PartitionNode<RoomData> root, DirectedGraph<RoomData, DoorwayData> layout)
{
this.root = root;
this.rooms = rooms;
this.cores = cores;
this.layout = layout;
}
public PartitionNode getRootPartition()
public PartitionNode<RoomData> getRootPartition()
{
return root;
}
public DirectedGraph<PartitionNode, DoorwayData> getRoomGraph()
public DirectedGraph<RoomData, DoorwayData> getLayout()
{
return rooms;
}
public ArrayList<IGraphNode<PartitionNode, DoorwayData>> getCoreNodes()
{
return cores;
}
public ArrayList<BoundingBox> getProtectedAreas()
{
return protectedAreas;
return layout;
}
public int width()

View File

@@ -1,8 +1,9 @@
package StevenDimDoors.experimental;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
@@ -25,54 +26,46 @@ public class MazeDesigner
public static MazeDesign generate(Random random)
{
// Construct a random binary space partitioning of our maze volume
PartitionNode root = partitionRooms(MAZE_WIDTH, MAZE_HEIGHT, MAZE_LENGTH, SPLIT_COUNT, random);
PartitionNode<RoomData> root = partitionRooms(MAZE_WIDTH, MAZE_HEIGHT, MAZE_LENGTH, SPLIT_COUNT, random);
// List all the leaf nodes of the partition tree, which denote individual rooms
ArrayList<PartitionNode> partitions = new ArrayList<PartitionNode>(1 << SPLIT_COUNT);
listRoomPartitions(root, partitions);
// Attach rooms to all the leaf nodes of the partition tree
ArrayList<RoomData> rooms = new ArrayList<RoomData>(1 << SPLIT_COUNT);
attachRooms(root, rooms);
// Shuffle the list of rooms so that they're not listed in any ordered way in the room graph
// This is the only convenient way of randomizing the maze sections generated later
Collections.shuffle(rooms, random);
// Construct an adjacency graph of the rooms we've carved out. Two rooms are
// considered adjacent if and only if a doorway could connect them. Their
// common boundary must be large enough for a doorway.
DirectedGraph<PartitionNode, DoorwayData> rooms = createRoomGraph(root, partitions, random);
DirectedGraph<RoomData, DoorwayData> layout = createRoomGraph(root, rooms, random);
// Cut out random subgraphs from the adjacency graph
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = createMazeSections(rooms, random);
ArrayList<RoomData> cores = createMazeSections(layout, random);
// Remove unnecessary passages through floors/ceilings and some from the walls
for (IGraphNode<PartitionNode, DoorwayData> core : cores)
for (RoomData core : cores)
{
pruneDoorways(core, rooms, random);
pruneDoorways(core.getLayoutNode(), layout, random);
}
return new MazeDesign(root, rooms, cores);
// Set up the placement of dimensional doors within the maze
createMazeLinks(layout, cores, random);
return new MazeDesign(root, layout);
}
private static void listRoomPartitions(PartitionNode node, ArrayList<PartitionNode> partitions)
private static void attachRooms(PartitionNode<RoomData> node, ArrayList<RoomData> partitions)
{
if (node.isLeaf())
{
partitions.add(node);
partitions.add(new RoomData(node));
}
else
{
listRoomPartitions(node.leftChild(), partitions);
listRoomPartitions(node.rightChild(), partitions);
}
}
private static void removeRoomPartitions(PartitionNode node)
{
// Remove a node and any of its ancestors that become leaf nodes
PartitionNode parent;
PartitionNode current;
current = node;
while (current != null && current.isLeaf())
{
parent = current.parent();
current.remove();
current = parent;
attachRooms(node.leftChild(), partitions);
attachRooms(node.rightChild(), partitions);
}
}
@@ -140,35 +133,25 @@ public class MazeDesigner
}
}
private static DirectedGraph<PartitionNode, DoorwayData> createRoomGraph(PartitionNode root, ArrayList<PartitionNode> partitions, Random random)
private static DirectedGraph<RoomData, DoorwayData> createRoomGraph(PartitionNode<RoomData> root, ArrayList<RoomData> rooms, Random random)
{
DirectedGraph<PartitionNode, DoorwayData> roomGraph = new DirectedGraph<PartitionNode, DoorwayData>();
HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>> roomsToGraph = new HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>>(2 * partitions.size());
// Shuffle the list of rooms so that they're not listed in any ordered way in the room graph
// This is the only convenient way of randomizing the maze sections generated later
Collections.shuffle(partitions, random);
DirectedGraph<RoomData, DoorwayData> layout = new DirectedGraph<RoomData, DoorwayData>();
// Add all rooms to a graph
// Also add them to a map so we can associate rooms with their graph nodes
// The map is needed for linking graph nodes based on adjacent partitions
for (PartitionNode partition : partitions)
for (RoomData room : rooms)
{
roomsToGraph.put(partition, roomGraph.addNode(partition));
room.addToLayout(layout);
}
// Add edges for each room
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{
findDoorways(node, root, roomsToGraph, roomGraph);
findDoorways(node.data(), root, layout);
}
return roomGraph;
return layout;
}
private static void findDoorways(IGraphNode<PartitionNode, DoorwayData> roomNode, PartitionNode root,
HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>> roomsToGraph,
DirectedGraph<PartitionNode, DoorwayData> roomGraph)
private static void findDoorways(RoomData room, PartitionNode<RoomData> root,
DirectedGraph<RoomData, DoorwayData> layout)
{
// This function finds rooms adjacent to a specified room that could be connected
// to it through a doorway. Edges are added to the room graph to denote rooms that
@@ -186,7 +169,7 @@ public class MazeDesigner
// there will always be a way to walk from any room to any other room.
boolean[][] detected;
PartitionNode adjacent;
PartitionNode<RoomData> adjacent;
int a, b, c;
int p, q, r;
@@ -195,11 +178,10 @@ public class MazeDesigner
Point3D otherMin;
Point3D otherMax;
DoorwayData doorway;
IGraphNode<PartitionNode, DoorwayData> adjacentNode;
PartitionNode room = roomNode.data();
Point3D minCorner = room.minCorner();
Point3D maxCorner = room.maxCorner();
PartitionNode partition = room.getPartitionNode();
Point3D minCorner = partition.minCorner();
Point3D maxCorner = partition.maxCorner();
int minX = minCorner.getX();
int minY = minCorner.getY();
@@ -209,9 +191,9 @@ public class MazeDesigner
int maxY = maxCorner.getY();
int maxZ = maxCorner.getZ();
int width = room.width();
int height = room.height();
int length = room.length();
int width = partition.width();
int height = partition.height();
int length = partition.length();
if (maxZ < root.maxCorner().getZ())
{
@@ -247,8 +229,7 @@ public class MazeDesigner
otherMin = new Point3D(minXI, minYI, maxZ);
otherMax = new Point3D(maxXI, maxYI, maxZ + 1);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Z_AXIS);
adjacentNode = roomsToGraph.get(adjacent);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
}
}
else
@@ -295,8 +276,7 @@ public class MazeDesigner
otherMin = new Point3D(maxX, minYI, minZI);
otherMax = new Point3D(maxX + 1, maxYI, maxZI);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.X_AXIS);
adjacentNode = roomsToGraph.get(adjacent);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
}
}
else
@@ -343,8 +323,7 @@ public class MazeDesigner
otherMin = new Point3D(minXI, maxY, minZI);
otherMax = new Point3D(maxXI, maxY + 1, maxZI);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Y_AXIS);
adjacentNode = roomsToGraph.get(adjacent);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
}
}
else
@@ -359,108 +338,130 @@ public class MazeDesigner
//Done!
}
private static ArrayList<IGraphNode<PartitionNode, DoorwayData>> createMazeSections(DirectedGraph<PartitionNode, DoorwayData> roomGraph, Random random)
private static ArrayList<RoomData> createMazeSections(DirectedGraph<RoomData, DoorwayData> layout, Random random)
{
// The randomness of the sections generated here hinges on
// the nodes in the graph being in a random order. We assume
// that was handled in a previous step!
final int MAX_DISTANCE = 2;
// We split the maze into sections by choosing core rooms and removing
// rooms that are a certain number of doorways away. However, for a section
// to be valid, it must also have enough space for at least two doors in
// rooms without floor holes. If a section can't fit two doors, more
// neighboring rooms are added until the necessary space is found or the
// search space is exhausted.
final int MAX_DISTANCE = 2 + random.nextInt(2);
final int MIN_SECTION_ROOMS = 5;
final int MIN_SECTION_CAPACITY = 2;
int distance;
IGraphNode<PartitionNode, DoorwayData> current;
IGraphNode<PartitionNode, DoorwayData> neighbor;
int capacity;
RoomData room;
RoomData neighbor;
boolean hasHoles;
IGraphNode<RoomData, DoorwayData> roomNode;
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> removals = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> section = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>();
ArrayList<RoomData> cores = new ArrayList<RoomData>();
ArrayList<RoomData> section = new ArrayList<RoomData>();
ArrayList<IGraphNode<RoomData, DoorwayData>> nodes = new ArrayList<IGraphNode<RoomData, DoorwayData>>(layout.nodeCount());
Queue<IGraphNode<PartitionNode, DoorwayData>> ordering = new LinkedList<IGraphNode<PartitionNode, DoorwayData>>();
HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer> distances = new HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer>();
Queue<RoomData> ordering = new LinkedList<RoomData>();
// List all graph nodes so that we can iterate over this list instead
// of using the graph's iterator. That avoids the risk of breaking
// the graph's iterator during removals.
for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{
nodes.add(node);
}
// Repeatedly generate sections until all nodes have been visited
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
for (IGraphNode<RoomData, DoorwayData> node : nodes)
{
// If this node hasn't been visited, then use it as the core of a new section
// Otherwise, ignore it, since it was already processed
if (!distances.containsKey(node))
// If this room hasn't been visited (distance = -1), then use it as the core of a new section
// Otherwise, ignore it, since it was already processed. Also make sure to check that room
// isn't null, which happens if the room was removed previously.
room = node.data();
if (room != null && room.getDistance() < 0)
{
// Perform a breadth-first search to tag surrounding nodes with distances
distances.put(node, 0);
ordering.add(node);
ordering.add(room);
room.setDistance(0);
section.clear();
capacity = 0;
while (!ordering.isEmpty())
while (room != null && (room.getDistance() <= MAX_DISTANCE || capacity < 2))
{
current = ordering.remove();
distance = distances.get(current) + 1;
ordering.remove();
section.add(room);
roomNode = room.getLayoutNode();
distance = room.getDistance() + 1;
hasHoles = false;
if (distance <= MAX_DISTANCE + 1)
// Visit neighboring rooms and assign them distances,
// if they don't have a proper distance assigned already.
// Also check for floor holes.
for (IEdge<RoomData, DoorwayData> edge : roomNode.inbound())
{
section.add(current);
// Visit neighboring nodes and assign them distances, if they don't
// have a distance assigned already
for (IEdge<PartitionNode, DoorwayData> edge : current.inbound())
neighbor = edge.head().data();
if (neighbor.getDistance() < 0)
{
neighbor = edge.head();
if (!distances.containsKey(neighbor))
{
distances.put(neighbor, distance);
ordering.add(neighbor);
}
neighbor.setDistance(distance);
ordering.add(neighbor);
}
for (IEdge<PartitionNode, DoorwayData> edge : current.outbound())
if (edge.data().axis() == DoorwayData.Y_AXIS)
{
neighbor = edge.tail();
if (!distances.containsKey(neighbor))
{
distances.put(neighbor, distance);
ordering.add(neighbor);
}
hasHoles = true;
}
}
else
for (IEdge<RoomData, DoorwayData> edge : roomNode.outbound())
{
removals.add(current);
break;
neighbor = edge.tail().data();
if (neighbor.getDistance() < 0)
{
neighbor.setDistance(distance);
ordering.add(neighbor);
}
}
// Count this room's door capacity if it has no floor holes
if (!hasHoles)
{
capacity += room.estimateDoorCapacity();
}
room = ordering.peek();
}
// List nodes that have a distance of exactly MAX_DISTANCE + 1
// Those are precisely the nodes that remain in the queue
// We can't remove them immediately because that could break
// the iterator for the graph.
// The remaining rooms in the ordering are those that are at the
// frontier of structure. They must be removed to create a gap
// between this section and other sections.
while (!ordering.isEmpty())
{
removals.add(ordering.remove());
ordering.remove().remove();
}
// Check if this section contains enough rooms
if (section.size() >= MIN_SECTION_ROOMS)
// Check if this section contains enough rooms and capacity for doors
if (section.size() >= MIN_SECTION_ROOMS && capacity >= MIN_SECTION_CAPACITY)
{
cores.add(node);
cores.add(node.data());
}
else
{
removals.addAll(section);
// Discard the whole section
for (RoomData target : section)
{
target.remove();
}
}
}
}
// Remove all the nodes that were listed for removal
// Also remove unused partitions from the partition tree
for (IGraphNode<PartitionNode, DoorwayData> node : removals)
{
removeRoomPartitions(node.data());
roomGraph.removeNode(node);
}
return cores;
}
private static void pruneDoorways(IGraphNode<PartitionNode, DoorwayData> core,
DirectedGraph<PartitionNode, DoorwayData> rooms, Random random)
private static void pruneDoorways(IGraphNode<RoomData, DoorwayData> core,
DirectedGraph<RoomData, DoorwayData> layout, Random random)
{
// We receive a node for one of the rooms in a section of the maze
// and we need to remove as many floor doorways as possible while
@@ -478,12 +479,12 @@ public class MazeDesigner
// idea applies for the other doorways, plus some randomness.
// First, list all nodes in the subgraph
IGraphNode<PartitionNode, DoorwayData> current;
IGraphNode<PartitionNode, DoorwayData> neighbor;
IGraphNode<RoomData, DoorwayData> current;
IGraphNode<RoomData, DoorwayData> neighbor;
Stack<IGraphNode<PartitionNode, DoorwayData>> ordering = new Stack<IGraphNode<PartitionNode, DoorwayData>>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> subgraph = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>(64);
DisjointSet<IGraphNode<PartitionNode, DoorwayData>> components = new DisjointSet<IGraphNode<PartitionNode, DoorwayData>>(128);
Stack<IGraphNode<RoomData, DoorwayData>> ordering = new Stack<IGraphNode<RoomData, DoorwayData>>();
ArrayList<IGraphNode<RoomData, DoorwayData>> subgraph = new ArrayList<IGraphNode<RoomData, DoorwayData>>(64);
DisjointSet<IGraphNode<RoomData, DoorwayData>> components = new DisjointSet<IGraphNode<RoomData, DoorwayData>>(128);
ordering.add(core);
components.makeSet(core);
@@ -492,7 +493,7 @@ public class MazeDesigner
current = ordering.pop();
subgraph.add(current);
for (IEdge<PartitionNode, DoorwayData> edge : current.inbound())
for (IEdge<RoomData, DoorwayData> edge : current.inbound())
{
neighbor = edge.head();
if (components.makeSet(neighbor))
@@ -500,7 +501,7 @@ public class MazeDesigner
ordering.add(neighbor);
}
}
for (IEdge<PartitionNode, DoorwayData> edge : current.outbound())
for (IEdge<RoomData, DoorwayData> edge : current.outbound())
{
neighbor = edge.tail();
if (components.makeSet(neighbor))
@@ -510,15 +511,17 @@ public class MazeDesigner
}
}
// Now iterate over the list of nodes and merge their sets
// We only have to look at outbound edges since inbound edges mirror them
// Also list any Y_AXIS doorways we come across
ArrayList<IEdge<PartitionNode, DoorwayData>> targets =
new ArrayList<IEdge<PartitionNode, DoorwayData>>();
// Now iterate over the list of nodes and merge their sets based on
// being connected by X_AXIS or Z_AXIS doorways. We only have to look
// at outbound edges since inbound edges mirror them. List any Y_AXIS
// doorways we come across to consider removing them later, depending
// on their impact on connectedness.
ArrayList<IEdge<RoomData, DoorwayData>> targets =
new ArrayList<IEdge<RoomData, DoorwayData>>();
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
for (IGraphNode<RoomData, DoorwayData> room : subgraph)
{
for (IEdge<PartitionNode, DoorwayData> passage : room.outbound())
for (IEdge<RoomData, DoorwayData> passage : room.outbound())
{
if (passage.data().axis() != DoorwayData.Y_AXIS)
{
@@ -535,11 +538,12 @@ public class MazeDesigner
Collections.shuffle(targets, random);
// Merge sets together and remove unnecessary doorways
for (IEdge<PartitionNode, DoorwayData> passage : targets)
for (IEdge<RoomData, DoorwayData> passage : targets)
{
if (!components.mergeSets(passage.head(), passage.tail()))
{
rooms.removeEdge(passage);
layout.removeEdge(passage);
}
}
@@ -548,13 +552,13 @@ public class MazeDesigner
components.clear();
targets.clear();
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
for (IGraphNode<RoomData, DoorwayData> room : subgraph)
{
components.makeSet(room);
}
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
for (IGraphNode<RoomData, DoorwayData> room : subgraph)
{
for (IEdge<PartitionNode, DoorwayData> passage : room.outbound())
for (IEdge<RoomData, DoorwayData> passage : room.outbound())
{
if (passage.data().axis() == DoorwayData.Y_AXIS)
{
@@ -567,13 +571,198 @@ public class MazeDesigner
}
}
Collections.shuffle(targets, random);
for (IEdge<PartitionNode, DoorwayData> passage : targets)
for (IEdge<RoomData, DoorwayData> passage : targets)
{
if (!components.mergeSets(passage.head(), passage.tail()) && random.nextBoolean())
{
rooms.removeEdge(passage);
layout.removeEdge(passage);
}
}
}
private static void createMazeLinks(DirectedGraph<RoomData, DoorwayData> layout,
ArrayList<RoomData> cores, Random random)
{
// We have 4 objectives here...
// 1. Place the entrance to the maze
// 2. Place links to other dungeons
// 3. Place internal links connecting the different sections of the maze
// 4. Place more internal links to confuse people
// We need to start by building up data for each section, such as their
// door capacities and the rooms available for placing doors.
int index;
int count;
SectionData selection;
SectionData destination;
ArrayList<SectionData> allSections;
ArrayList<SectionData> usableSections;
// Check if there is only one section. Our concerns differ depending
// on whether there is one or more than one.
if (cores.size() > 1)
{
// More than 1 section
allSections = new ArrayList<SectionData>(cores.size());
for (RoomData core : cores)
{
allSections.add( SectionData.createFromCore(core.getLayoutNode()) );
}
usableSections = (ArrayList<SectionData>) allSections.clone();
// Select the room in which to place the entrance.
// We can safely consider all sections because createMazeSections()
// guarantees that each one has at least the capacity for 2 doors.
// Remove the selected section if it falls below a capacity of 2
// since we need to leave at least 1 capacity for section linking.
index = random.nextInt(usableSections.size());
selection = usableSections.get(index);
selection.createEntranceLink(random);
if (selection.capacity() <= 1)
{
usableSections.remove(index);
}
// Place 3 to 4 dungeon doors in random sections
// Remove any sections that fall under a capacity of 2.
count = 3 + random.nextInt(2);
for (; count > 0 && !usableSections.isEmpty(); count--)
{
index = random.nextInt(usableSections.size());
selection = usableSections.get(index);
selection.createDungeonLink(random);
if (selection.capacity() <= 1)
{
usableSections.remove(index);
}
}
// The next task is to place internal links. These links must connect
// the different maze sections to create a strongly connected graph.
linkMazeSections(allSections, random);
// Add 1 to 3 extra internal links to confuse people
usableSections.clear();
for (SectionData section : allSections)
{
if (section.capacity() > 0)
{
usableSections.add(section);
}
}
count = 1 + random.nextInt(3);
for (; count > 0 && !usableSections.isEmpty(); count--)
{
index = random.nextInt(usableSections.size());
selection = usableSections.get(index);
destination = allSections.get( random.nextInt(allSections.size()) );
selection.reserveSectionLink(destination, random);
if (selection.capacity() == 0)
{
usableSections.remove(index);
}
}
// Finally, make sure to process all reservations for section links.
for (SectionData section : allSections)
{
section.processReservedLinks(random);
}
}
else
{
// Only 1 section
selection = SectionData.createFromCore(cores.get(0).getLayoutNode());
// Place entrance door in a random room
selection.createEntranceLink(random);
// Place 3 to 4 dungeon doors or fewer, based on capacity
count = Math.min(3 + random.nextInt(2), selection.capacity());
for (; count > 0; count--)
{
selection.createDungeonLink(random);
}
}
}
private static void linkMazeSections(ArrayList<SectionData> sections, Random random)
{
// This algorithm constructs links sections together using Dimensional Doors
// to create a random strongly connected graph. It takes into account capacity
// constraints as well. We assume that all sections have at least 1 door capacity.
final int EXTENSION_CHANCE = 2;
final int MAX_EXTENSION_CHANCE = 3;
int index;
SectionData start;
SectionData current;
SectionData next;
// Total spare capacity of the sections not in "remaining"
int capacity;
// Sections not in the graph
ArrayList<SectionData> remaining = (ArrayList<SectionData>) sections.clone();
// Sections that are part of an incomplete cycle
ArrayList<SectionData> attached = new ArrayList<SectionData>(sections.size());
// Sections that are part of a cycle and thus strongly connected
ArrayList<SectionData> connected = new ArrayList<SectionData>(sections.size());
// Sections that are part of a cycle and have spare capacity - used to start new cycles
ArrayList<SectionData> starters = new ArrayList<SectionData>(sections.size());
// Shuffle remaining to achieve randomness
Collections.shuffle(remaining, random);
// Remove the starting node to serve as the base of our strongly connected graph
start = remaining.remove(remaining.size() - 1);
starters.add(start);
connected.add(start);
capacity = start.capacity();
// Repeat until all sections are connected
while (!remaining.isEmpty())
{
// Select a section from which to start a new cycle
index = random.nextInt(starters.size());
start = starters.get(index);
// Select the first new section in the cycle and link to it
current = remaining.remove(remaining.size() - 1);
attached.add(current);
start.reserveSectionLink(current, random);
// Add the current section's capacity to the total, but subtract two to account
// for the link just created and for the future link from this section to another
capacity += current.capacity() - 2;
// Remove the starting section from starters if it has exhausted its capacity
if (start.capacity() == 0)
{
starters.remove(index);
}
// Continue attaching sections to the partial cycle while there are are still sections
// left to be added and we have no spare capacity. Or we could randomly decide to
// continue even with spare capacity. Spare capacity means we could start a new cycle
// safely and still achieve strong connectivity. Randomness here influences the kinds
// of graphs we can get.
while (!remaining.isEmpty() && (capacity == 0 ||
random.nextInt(MAX_EXTENSION_CHANCE) < EXTENSION_CHANCE))
{
next = remaining.remove(remaining.size() - 1);
attached.add(next);
current.reserveSectionLink(next, random);
// Account for this section's capacity, but subtract one for
// the future link that will connect this section to another
capacity += next.capacity() - 1;
current = next;
}
next = connected.get(random.nextInt(connected.size()));
current.reserveSectionLink(next, random);
for (SectionData section : attached)
{
connected.add(section);
if (section.capacity() > 0)
{
starters.add(section);
}
}
}
// Done! At this point, all sections are connected.
}
}

View File

@@ -2,11 +2,12 @@ package StevenDimDoors.experimental;
import StevenDimDoors.mod_pocketDim.Point3D;
public class PartitionNode extends BoundingBox
public class PartitionNode<T> extends BoundingBox
{
private PartitionNode parent;
private PartitionNode leftChild = null;
private PartitionNode rightChild = null;
private T data = null;
public PartitionNode(int width, int height, int length)
{
@@ -122,4 +123,14 @@ public class PartitionNode extends BoundingBox
return this;
}
}
public void setData(T value)
{
this.data = value;
}
public T getData()
{
return data;
}
}

View File

@@ -0,0 +1,133 @@
package StevenDimDoors.experimental;
import java.util.ArrayList;
public class RoomData
{
/* Implementation Note:
* Plans for links between rooms are stored in lists rather than a graph,
* even though they duplicate some graph functionality, because there are
* relatively few of them compared to the number of rooms. Moreover, some
* links don't even have destinations because they're intended to lead to
* other dungeons.
*/
private int capacity;
private int distance;
private boolean decayed;
private PartitionNode partitionNode;
private ArrayList<LinkPlan> inboundLinks;
private ArrayList<LinkPlan> outboundLinks;
private DirectedGraph<RoomData, DoorwayData> layout;
private IGraphNode<RoomData, DoorwayData> layoutNode;
public RoomData(PartitionNode partitionNode)
{
this.partitionNode = partitionNode;
this.inboundLinks = new ArrayList<LinkPlan>();
this.outboundLinks = new ArrayList<LinkPlan>();
this.layoutNode = null;
this.layout = null;
this.distance = -1;
this.capacity = -1;
this.decayed = false;
partitionNode.setData(this);
}
public PartitionNode getPartitionNode()
{
return this.partitionNode;
}
public IGraphNode<RoomData, DoorwayData> getLayoutNode()
{
return this.layoutNode;
}
public void addToLayout(DirectedGraph<RoomData, DoorwayData> layout)
{
this.layout = layout;
this.layoutNode = layout.addNode(this);
}
public boolean isDecayed()
{
return decayed;
}
public void setDecayed(boolean value)
{
this.decayed = value;
}
public ArrayList<LinkPlan> getInboundLinks()
{
return this.inboundLinks;
}
public ArrayList<LinkPlan> getOutboundLinks()
{
return this.outboundLinks;
}
public int getDistance()
{
return distance;
}
public void setDistance(int value)
{
distance = value;
}
public void remove()
{
// Remove the room from the partition tree and from the layout graph.
// Also remove any ancestors that become leaf nodes.
PartitionNode parent;
PartitionNode current = partitionNode;
while (current != null && current.isLeaf())
{
parent = current.parent();
current.remove();
current = parent;
}
// Remove the room from the layout graph
layout.removeNode(layoutNode);
// Remove any links
while (!inboundLinks.isEmpty())
inboundLinks.get(inboundLinks.size() - 1).remove();
while (!outboundLinks.isEmpty())
outboundLinks.get(outboundLinks.size() - 1).remove();
// Wipe the room's data, as a precaution
layout = null;
partitionNode = null;
inboundLinks = null;
outboundLinks = null;
}
public int estimateDoorCapacity()
{
if (capacity >= 0)
return capacity;
int cellsX = (partitionNode.width() - 3) / 2;
int cellsZ = (partitionNode.length() - 3) / 2;
capacity = Math.min(cellsX * cellsZ, 3);
return capacity;
}
public int getRemainingDoorCapacity()
{
return (estimateDoorCapacity() - outboundLinks.size());
}
public boolean isProtected()
{
return !inboundLinks.isEmpty() || !outboundLinks.isEmpty();
}
}

View File

@@ -0,0 +1,192 @@
package StevenDimDoors.experimental;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
import java.util.Stack;
public class SectionData
{
// Specifies the chance of selecting a destination from protectedRooms
// rather than from destinationRooms (which will then become protected)
private static final int PROTECTED_DESTINATION_CHANCE = 4;
private static final int MAX_PROTECTED_DESTINATION_CHANCE = 5;
private int capacity;
private ArrayList<RoomData> sourceRooms;
private ArrayList<RoomData> protectedRooms;
private ArrayList<RoomData> destinationRooms;
private ArrayList<LinkPlan> reservations;
private SectionData(ArrayList<RoomData> sourceRooms, ArrayList<RoomData> destinationRooms, int capacity)
{
this.capacity = capacity;
this.sourceRooms = sourceRooms;
this.destinationRooms = destinationRooms;
this.protectedRooms = new ArrayList<RoomData>();
this.reservations = new ArrayList<LinkPlan>();
}
public static SectionData createFromCore(IGraphNode<RoomData, DoorwayData> core)
{
int capacity = 0;
ArrayList<RoomData> sourceRooms = new ArrayList<RoomData>();
ArrayList<RoomData> destinationRooms = new ArrayList<RoomData>();
boolean hasHoles;
RoomData currentRoom;
IGraphNode<RoomData, DoorwayData> current;
IGraphNode<RoomData, DoorwayData> neighbor;
Stack<IGraphNode<RoomData, DoorwayData>> ordering = new Stack<IGraphNode<RoomData, DoorwayData>>();
HashSet<IGraphNode<RoomData, DoorwayData>> visited = new HashSet<IGraphNode<RoomData, DoorwayData>>();
visited.add(core);
ordering.add(core);
while (!ordering.isEmpty())
{
current = ordering.pop();
hasHoles = false;
for (IEdge<RoomData, DoorwayData> edge : current.outbound())
{
neighbor = edge.tail();
if (visited.add(neighbor))
{
ordering.add(neighbor);
}
}
for (IEdge<RoomData, DoorwayData> edge : current.inbound())
{
neighbor = edge.head();
if (visited.add(neighbor))
{
ordering.add(neighbor);
}
if (edge.data().axis() == DoorwayData.Y_AXIS)
{
hasHoles = true;
}
}
if (!hasHoles)
{
currentRoom = current.data();
destinationRooms.add(currentRoom);
if (currentRoom.estimateDoorCapacity() > 0)
{
capacity += currentRoom.estimateDoorCapacity();
sourceRooms.add(currentRoom);
}
}
}
return new SectionData(sourceRooms, destinationRooms, capacity);
}
public int capacity()
{
return capacity;
}
public void createEntranceLink(Random random)
{
int index = random.nextInt(sourceRooms.size());
RoomData room = sourceRooms.get(index);
LinkPlan.createEntranceLink(room);
if (room.getRemainingDoorCapacity() == 0)
{
sourceRooms.remove(index);
}
// It's okay to check containment in this list because
// the number of protected rooms is expected to be small
if (!protectedRooms.contains(room))
{
protectedRooms.add(room);
}
capacity--;
}
public void createDungeonLink(Random random)
{
int index = random.nextInt(sourceRooms.size());
RoomData room = sourceRooms.get(index);
LinkPlan.createDungeonLink(room);
if (room.getRemainingDoorCapacity() == 0)
{
sourceRooms.remove(index);
}
// It's okay to check containment in this list because
// the number of protected rooms is expected to be small
if (!protectedRooms.contains(room))
{
protectedRooms.add(room);
}
capacity--;
}
public void reserveSectionLink(SectionData destination, Random random)
{
// This method "reserves" a link by decrementing the capacity of this
// section and assigning a source room to the link. However, assigning
// its destination in a particular section is deferred. Why?
// We favor using source rooms as destinations to cut down the number
// of rooms that have to be marked as protected against decay effects.
// We defer assigning a destination until after all source rooms are
// known so that we have that information available. Otherwise,
// destination selection would be biased toward non-source rooms and
// rooms with dungeon doors, which are placed before section links.
int index = random.nextInt(sourceRooms.size());
RoomData room = sourceRooms.get(index);
destination.reserveDestination(LinkPlan.createInternalLink(room));
if (room.getRemainingDoorCapacity() == 0)
{
sourceRooms.remove(index);
}
// It's okay to check containment in this list because
// the number of protected rooms is expected to be small
if (!protectedRooms.contains(room))
{
protectedRooms.add(room);
}
capacity--;
}
public void processReservedLinks(Random random)
{
for (LinkPlan link : reservations)
{
link.setDestination( getLinkDestination(random) );
}
reservations.clear();
}
private void reserveDestination(LinkPlan link)
{
reservations.add(link);
}
private RoomData getLinkDestination(Random random)
{
RoomData destination;
// Choose whether to select a room that is already protected or select
// from all possible destination rooms. Note that some destination rooms
// may also be protected rooms already.
if (random.nextInt(MAX_PROTECTED_DESTINATION_CHANCE) < PROTECTED_DESTINATION_CHANCE)
{
destination = protectedRooms.get( random.nextInt(protectedRooms.size()) );
}
else
{
destination = destinationRooms.get( random.nextInt(destinationRooms.size()) );
// It's okay to check containment in this list because
// the number of protected rooms is expected to be small
if (!protectedRooms.contains(destination))
{
protectedRooms.add(destination);
}
}
return destination;
}
}

View File

@@ -0,0 +1,17 @@
package StevenDimDoors.experimental.decorators;
import java.util.Random;
import net.minecraft.world.World;
import StevenDimDoors.experimental.RoomData;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
public abstract class BaseDecorator
{
public BaseDecorator() { }
public abstract boolean canDecorate(RoomData room);
public abstract void decorate(RoomData room, World world, Point3D offset, Random random, DDProperties properties);
}

View File

@@ -0,0 +1,51 @@
package StevenDimDoors.experimental.decorators;
import java.util.ArrayList;
import java.util.Random;
import StevenDimDoors.experimental.RoomData;
public class DecoratorFinder
{
private static ArrayList<BaseDecorator> decorators = null;
private DecoratorFinder() { }
public static BaseDecorator find(RoomData room, Random random)
{
if (decorators == null)
{
load();
}
// Since there are only a few decorators right now, we just iterate
// over the list and check them all. If we add a lot, we'll need to
// switch to a more efficient approach.
ArrayList<BaseDecorator> matches = new ArrayList<BaseDecorator>();
for (BaseDecorator decorator : decorators)
{
if (decorator.canDecorate(room))
{
matches.add(decorator);
}
}
if (matches.isEmpty())
{
return null;
}
else
{
return matches.get( random.nextInt(matches.size()) );
}
}
private static void load()
{
// List all the decorators we have
decorators = new ArrayList<BaseDecorator>();
decorators.add(new LinkDestinationDecorator());
decorators.add(new DefaultDoorDecorator());
decorators.add(new TorchDecorator());
}
}

View File

@@ -0,0 +1,49 @@
package StevenDimDoors.experimental.decorators;
import java.util.Random;
import net.minecraft.item.ItemDoor;
import net.minecraft.world.World;
import StevenDimDoors.experimental.LinkPlan;
import StevenDimDoors.experimental.RoomData;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
public class DefaultDoorDecorator extends BaseDecorator
{
@Override
public boolean canDecorate(RoomData room)
{
return !room.getOutboundLinks().isEmpty();
}
@Override
public void decorate(RoomData room, World world, Point3D offset, Random random, DDProperties properties)
{
// TODO: This is just an improvised implementation for testing
Point3D corner = room.getPartitionNode().minCorner().clone();
corner.add(offset);
int count = 0;
Point3D source = null;
for (LinkPlan plan : room.getOutboundLinks())
{
source = new Point3D(corner.getX() + 2, corner.getY() + 2, corner.getZ() + count + 1);
ItemDoor.placeDoorBlock(world, source.getX(), source.getY() - 1, source.getZ(), 0, mod_pocketDim.dimensionalDoor);
plan.setSourcePoint(source);
count++;
}
if (source == null)
{
throw new IllegalStateException("This should never happen because this decorator only applies if outbound links exist!");
}
for (LinkPlan plan : room.getInboundLinks())
{
plan.setDestinationPoint(source);
}
}
}

View File

@@ -0,0 +1,37 @@
package StevenDimDoors.experimental.decorators;
import java.util.Random;
import net.minecraft.world.World;
import StevenDimDoors.experimental.LinkPlan;
import StevenDimDoors.experimental.PartitionNode;
import StevenDimDoors.experimental.RoomData;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
public class LinkDestinationDecorator extends BaseDecorator
{
@Override
public boolean canDecorate(RoomData room)
{
return room.getOutboundLinks().isEmpty() && !room.getInboundLinks().isEmpty();
}
@Override
public void decorate(RoomData room, World world, Point3D offset, Random random, DDProperties properties)
{
// Set the center of the room as the destination for all inbound links
PartitionNode<RoomData> partition = room.getPartitionNode();
Point3D destination = partition.minCorner().clone();
destination.add(
offset.getX() + partition.width() / 2,
offset.getY() + 2,
offset.getZ() + partition.length() / 2);
for (LinkPlan plan : room.getInboundLinks())
{
plan.setDestinationPoint(destination);
}
}
}

View File

@@ -0,0 +1,86 @@
package StevenDimDoors.experimental.decorators;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import StevenDimDoors.experimental.PartitionNode;
import StevenDimDoors.experimental.RoomData;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
public class TorchDecorator extends BaseDecorator
{
@Override
public boolean canDecorate(RoomData room)
{
return !room.isProtected();
}
@Override
public void decorate(RoomData room, World world, Point3D offset, Random random, DDProperties properties)
{
// SenseiKiwi: Place a single random torch along the walls.
// We could do more complex arrangements but I feel that a single
// torches here and there will be a little unsettling.
// The walls might be broken by passages or decay, so this will
// require trial and error.
final int MAX_ATTEMPTS = 5;
int x;
int z;
int attempts = 0;
PartitionNode<RoomData> partition = room.getPartitionNode();
int minX = partition.minCorner().getX() + offset.getX();
int minZ = partition.minCorner().getZ() + offset.getZ();
int maxX = partition.maxCorner().getX() + offset.getX();
int maxZ = partition.maxCorner().getZ() + offset.getZ();
int torchLevel = partition.minCorner().getY() + offset.getY() + 2;
for (; attempts < MAX_ATTEMPTS; attempts++)
{
// Choose a random side of the room to place the torch. The sides are numbered arbitrarily here.
// Then choose a random position along the wall and check if there is a block there to place the
// torch against. We assume that all blocks are bricks and thus valid.
switch (random.nextInt(4))
{
case 0: // Positive X side
z = MathHelper.getRandomIntegerInRange(random, minZ + 1, maxZ - 1);
if (!world.isAirBlock(maxX, torchLevel, z))
{
world.setBlock(maxX - 1, torchLevel, z, Block.torchWood.blockID, 2, 0);
return;
}
break;
case 1: // Negative X side
z = MathHelper.getRandomIntegerInRange(random, minZ + 1, maxZ - 1);
if (!world.isAirBlock(minX, torchLevel, z))
{
world.setBlock(minX + 1, torchLevel, z, Block.torchWood.blockID, 1, 0);
return;
}
break;
case 2: // Positive Z side
x = MathHelper.getRandomIntegerInRange(random, minX + 1, maxX - 1);
if (!world.isAirBlock(x, torchLevel, maxZ))
{
world.setBlock(x, torchLevel, maxZ - 1, Block.torchWood.blockID, 4, 0);
return;
}
break;
case 3: // Negative Z side
x = MathHelper.getRandomIntegerInRange(random, minX + 1, maxX - 1);
if (!world.isAirBlock(x, torchLevel, minZ))
{
world.setBlock(x, torchLevel, minZ + 1, Block.torchWood.blockID, 3, 0);
return;
}
break;
}
}
}
}

View File

@@ -1,14 +1,11 @@
package StevenDimDoors.mod_pocketDim;
import java.io.File;
import java.io.FileOutputStream;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.IGuiHandler;
@@ -133,20 +130,6 @@ public class CommonProxy implements IGuiHandler
{
}
public void updateDoorTE(BaseDimDoor door, World world, int x, int y, int z)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityDimDoor)
{
int metadata = world.getBlockMetadata(x, y, z);
TileEntityDimDoor dimTile = (TileEntityDimDoor) tile;
dimTile.openOrClosed = door.isDoorOnRift(world, x, y, z)&&door.isUpperDoorBlock(metadata);
dimTile.orientation = door.getFullMetadata(world, x, y, z) & 7;
dimTile.lockStatus = door.getLockStatus(world, x, y, z);
}
}
}

View File

@@ -1,11 +1,17 @@
package StevenDimDoors.mod_pocketDim;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet1Login;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.network.ForgePacket;
import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
@@ -59,8 +65,7 @@ public class ConnectionHandler implements IConnectionHandler
@Override
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
{
// Hax... please don't do this! >_<
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionDataDangerously(0)));
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(0)));
}
}

View File

@@ -1,23 +1,15 @@
package StevenDimDoors.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDispenser;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.ShapedOreRecipe;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.items.behaviors.DispenserBehaviorStabilizedRS;
import cpw.mods.fml.common.ICraftingHandler;
import cpw.mods.fml.common.registry.GameRegistry;
import static StevenDimDoors.mod_pocketDim.mod_pocketDim.*;
public class CraftingManager implements ICraftingHandler
public class CraftingManager
{
CraftingManager() { }
private CraftingManager() { }
public static void registerRecipes(DDProperties properties)
{
@@ -26,19 +18,19 @@ public class CraftingManager implements ICraftingHandler
switch (properties.WorldThreadRequirementLevel)
{
case 1:
GameRegistry.addShapelessRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
GameRegistry.addShapelessRecipe(new ItemStack(itemStableFabric, 1),
Item.enderPearl, mod_pocketDim.itemWorldThread);
break;
case 2:
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
"yxy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
case 3:
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
default:
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
}
@@ -46,125 +38,54 @@ public class CraftingManager implements ICraftingHandler
if (properties.CraftingDimensionalDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDimensionalDoor, 1),
GameRegistry.addRecipe(new ItemStack(itemDimensionalDoor, 1),
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorIron);
}
if (properties.CraftingUnstableDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemUnstableDoor, 1),
GameRegistry.addRecipe(new ItemStack(itemUnstableDoor, 1),
"yxy", 'x', Item.eyeOfEnder, 'y', mod_pocketDim.itemDimensionalDoor);
}
if (properties.CraftingWarpDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemWarpDoor, 1),
"yxy", 'x', Item.enderPearl, 'y', Item.doorWood);
GameRegistry.addRecipe(new ItemStack(itemWarpDoor, 1),
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorWood);
}
if (properties.CraftingTransTrapdoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.transTrapdoor, 1),
"y", "x", "y", 'x', Item.enderPearl, 'y', Block.trapdoor);
GameRegistry.addRecipe(new ItemStack(transTrapdoor, 1),
"y", "x", "y", 'x', mod_pocketDim.itemStableFabric, 'y', Block.trapdoor);
}
if (properties.CraftingRiftSignatureAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftSignature, 1),
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', Item.ingotIron);
GameRegistry.addRecipe(new ItemStack(itemRiftSignature, 1),
" y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron);
}
if (properties.CraftingRiftRemoverAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftRemover, 1),
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', Item.ingotGold);
GameRegistry.addRecipe(new ItemStack(itemRiftRemover, 1),
"yyy", "yxy", "yyy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotGold);
}
if (properties.CraftingRiftBladeAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftBlade, 1),
GameRegistry.addRecipe(new ItemStack(itemRiftBlade, 1),
"x", "x", "y", 'x', mod_pocketDim.itemStableFabric, 'y', Item.blazeRod);
}
if (properties.CraftingStabilizedRiftSignatureAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedRiftSignature, 1),
" y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedLinkSignature,1),
" y ", "yxy", " y ", 'x', mod_pocketDim.itemRiftSignature, 'y', mod_pocketDim.itemStableFabric);
}
if (properties.CraftingGoldenDimensionalDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor, 1),
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', mod_pocketDim.itemGoldenDoor);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor,1),
"yxy", 'x', mod_pocketDim.itemGoldenDoor, 'y', mod_pocketDim.itemStableFabric);
}
if (properties.CraftingGoldenDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDoor, 1),
"yy", "yy", "yy", 'y', Item.ingotGold);
}
if (properties.CraftingPersonalDimDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemPersonalDoor,1),
"yxy", 'y', mod_pocketDim.itemGoldenDoor, 'x', mod_pocketDim.itemStableFabric);
}
if (properties.CraftingQuartzDoorAllowed)
{
GameRegistry.addRecipe(new ShapedOreRecipe(mod_pocketDim.itemQuartzDoor, new Object[]{
"yy", "yy", "yy", Character.valueOf('y'), "oreQuartz"}));
}
if (properties.CraftingDDKeysAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDDKey, 1),
" z", " y ", "y ", 'y', Item.ingotGold, 'z', Item.enderPearl);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDDKey, 1),
"z", "z", 'z', mod_pocketDim.itemDDKey);
}
}
@Override
public void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix)
{
if(item.getItem() instanceof ItemDDKey)
{
ItemDDKey keyItem = (ItemDDKey) item.getItem();
ItemStack topKey = null;
ItemStack bottomKey = null;
int topKeySlot = 0;
for(int i = 0; i<craftMatrix.getSizeInventory();i++)
{
ItemStack slot = craftMatrix.getStackInSlot(i);
if(slot!=null)
{
if(topKey==null)
{
topKey = slot;
topKeySlot = i;
}
else
{
bottomKey = slot;
break;
}
}
}
DDLock.addKeys(bottomKey, DDLock.getKeys(topKey));
item.setTagCompound(bottomKey.getTagCompound());
player.inventory.addItemStackToInventory(topKey);
}
}
@Override
public void onSmelting(EntityPlayer player, ItemStack item)
{
// TODO Auto-generated method stub
}
public static void registerDispenserBehaviors()
{
// Register the dispenser behaviors for certain DD items
BlockDispenser.dispenseBehaviorRegistry.putObject(mod_pocketDim.itemStabilizedRiftSignature, new DispenserBehaviorStabilizedRS());
}
}

View File

@@ -1,14 +1,15 @@
package StevenDimDoors.mod_pocketDim;
import net.minecraft.block.Block;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent;
import net.minecraftforge.client.event.sound.SoundLoadEvent;
import net.minecraftforge.event.EventPriority;
@@ -18,18 +19,12 @@ import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.event.terraingen.InitMapGenEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.config.DDWorldProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.BaseItemDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PocketProvider;
@@ -39,26 +34,13 @@ import cpw.mods.fml.relauncher.SideOnly;
public class EventHookContainer
{
private static final int MAX_FOOD_LEVEL = 20;
private final DDProperties properties;
private DDWorldProperties worldProperties;
private RiftRegenerator regenerator;
public EventHookContainer(DDProperties properties)
{
this.properties = properties;
}
public void setSessionFields(DDWorldProperties worldProperties, RiftRegenerator regenerator)
{
// SenseiKiwi:
// Why have a setter rather than accessing mod_pocketDim directly?
// I want to make this dependency explicit in our code.
this.worldProperties = worldProperties;
this.regenerator = regenerator;
}
@ForgeSubscribe(priority = EventPriority.LOW)
public void onInitMapGen(InitMapGenEvent event)
{
@@ -77,10 +59,6 @@ public class EventHookContainer
@ForgeSubscribe
public void onSoundLoad(SoundLoadEvent event)
{
event.manager.addSound(mod_pocketDim.modid + ":doorLockRemoved.ogg");
event.manager.addSound(mod_pocketDim.modid + ":doorLocked.ogg");
event.manager.addSound(mod_pocketDim.modid + ":keyLock.ogg");
event.manager.addSound(mod_pocketDim.modid + ":keyUnlock.ogg");
event.manager.addSound(mod_pocketDim.modid + ":monk.ogg");
event.manager.addSound(mod_pocketDim.modid + ":crack.ogg");
event.manager.addSound(mod_pocketDim.modid + ":tearing.ogg");
@@ -97,6 +75,7 @@ public class EventHookContainer
public void onSoundEffectResult(PlayBackgroundMusicEvent event)
{
if (FMLClientHandler.instance().getClient().thePlayer.worldObj.provider.dimensionId == mod_pocketDim.properties.LimboDimensionID)
;
{
this.playMusicForDim(FMLClientHandler.instance().getClient().thePlayer.worldObj);
}
@@ -106,33 +85,21 @@ public class EventHookContainer
public void onPlayerEvent(PlayerInteractEvent event)
{
// Handle all door placement here
if (event.action == Action.LEFT_CLICK_BLOCK)
if(event.action == Action.LEFT_CLICK_BLOCK)
{
return;
}
World world = event.entity.worldObj;
ItemStack stack = event.entityPlayer.inventory.getCurrentItem();
if (stack != null)
if (stack != null && stack.getItem() instanceof ItemDoor)
{
if(stack.getItem() instanceof ItemWarpDoor)
{
NewDimData data = PocketManager.getDimensionData(world);
if(data.type() == DimensionType.PERSONAL)
{
mod_pocketDim.sendChat(event.entityPlayer,("Something prevents the Warp Door from tunneling out here"));
event.setCanceled(true);
return;
}
}
if (BaseItemDoor.tryToPlaceDoor(stack, event.entityPlayer, world,
if (mod_pocketDim.itemDimensionalDoor.tryToPlaceDoor(stack, event.entityPlayer, world,
event.x, event.y, event.z, event.face))
{
// Cancel the event so that we don't get two doors from vanilla doors
event.setCanceled(true);
}
}
}
@ForgeSubscribe
@@ -170,24 +137,13 @@ public class EventHookContainer
Entity entity = event.entity;
if (properties.LimboEnabled && properties.LimboReturnsInventoryEnabled &&
entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider)
{
if(entity.worldObj.provider instanceof PocketProvider)
{
EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username);
revivePlayerInLimbo(player);
event.setCanceled(true);
return false;
}
else if(entity.worldObj.provider instanceof LimboProvider && event.source == DamageSource.outOfWorld)
{
EntityPlayer player = (EntityPlayer) entity;
revivePlayerInLimbo(player);
mod_pocketDim.sendChat(player, "Search for the dark red pools which accumulate in the lower reaches of Limbo");
event.setCanceled(true);
return false;
}
EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username);
revivePlayerInLimbo(player);
event.setCanceled(true);
return false;
}
return true;
}
@@ -203,7 +159,7 @@ public class EventHookContainer
Entity entity = event.entity;
if (entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
if (entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider)
{
EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username);
@@ -219,23 +175,11 @@ public class EventHookContainer
return true;
}
private boolean isValidSourceForLimbo(WorldProvider provider)
{
// Returns whether a given world is a valid place for sending a player
// to Limbo. We can send someone to Limbo from a certain dimension if
// Universal Limbo is enabled and the source dimension is not Limbo, or
// if the source dimension is a pocket dimension.
return (worldProperties.UniversalLimboEnabled && provider.dimensionId != properties.LimboDimensionID) ||
(provider instanceof PocketProvider);
}
private void revivePlayerInLimbo(EntityPlayer player)
{
player.extinguish();
player.clearActivePotions();
player.setHealth(player.getMaxHealth());
player.getFoodStats().addStats(MAX_FOOD_LEVEL, 0);
Point4D destination = LimboProvider.getLimboSkySpawn(player, properties);
DDTeleporter.teleportEntity(player, destination, false);
}
@@ -254,25 +198,6 @@ public class EventHookContainer
}
}
@ForgeSubscribe
public void onChunkLoad(ChunkEvent.Load event)
{
// Schedule rift regeneration for any links located in this chunk.
// This event runs on both the client and server. Allow server only.
// Also, check that PocketManager is loaded, because onChunkLoad() can
// fire while chunks are being initialized in a new world, before
// onWorldLoad() fires.
Chunk chunk = event.getChunk();
if (!chunk.worldObj.isRemote && PocketManager.isLoaded())
{
NewDimData dimension = PocketManager.createDimensionData(chunk.worldObj);
for (DimLink link : dimension.getChunkLinks(chunk.xPosition, chunk.zPosition))
{
regenerator.scheduleSlowRegeneration(link);
}
}
}
public void playMusicForDim(World world)
{
if (world.isRemote)

View File

@@ -4,6 +4,5 @@ import net.minecraftforge.common.ForgeChunkManager.Ticket;
public interface IChunkLoader
{
public boolean isInitialized();
public void initialize(Ticket ticket);
public void forceChunkLoading(Ticket ticket,int x, int z);
}

View File

@@ -12,6 +12,5 @@ public class PacketConstants
public static final byte CREATE_LINK_PACKET_ID = 4;
public static final byte DELETE_LINK_PACKET_ID = 5;
public static final byte CLIENT_LOGIN_DIM_REGISTER = 6;
public static final byte UPDATE_LINK_PACKET_ID = 7;
}

View File

@@ -56,6 +56,20 @@ public class Point3D implements Serializable {
return this.z = z;
}
public void add(int x, int y, int z)
{
this.x += x;
this.y += y;
this.z += z;
}
public void add(Point3D other)
{
this.x += other.x;
this.y += other.y;
this.z += other.z;
}
@Override
public Point3D clone()
{

View File

@@ -39,13 +39,6 @@ public class ServerPacketHandler implements IPacketHandler
{
sendDimPacket(PacketConstants.DELETE_DIM_PACKET_ID, message);
}
@Override
public void update(ClientDimData message)
{
// TODO Auto-generated method stub
}
}
private static class LinkWatcher implements IUpdateWatcher<ClientLinkData>
@@ -61,12 +54,6 @@ public class ServerPacketHandler implements IPacketHandler
{
sendLinkPacket(PacketConstants.DELETE_LINK_PACKET_ID, message);
}
@Override
public void update(ClientLinkData message)
{
sendLinkPacket(PacketConstants.UPDATE_LINK_PACKET_ID, message);
}
}
public static Packet250CustomPayload createLinkPacket(ClientLinkData data)

View File

@@ -1,6 +1,7 @@
package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.ITileEntityProvider;
@@ -10,8 +11,7 @@ import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Item;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
@@ -22,7 +22,7 @@ import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -32,9 +32,9 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
protected final DDProperties properties;
@SideOnly(Side.CLIENT)
protected Icon[] upperTextures;
private Icon[] upperTextures;
@SideOnly(Side.CLIENT)
protected Icon[] lowerTextures;
private Icon[] lowerTextures;
public BaseDimDoor(int blockID, Material material, DDProperties properties)
{
@@ -74,18 +74,6 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ)
{
ItemStack stack = player.inventory.getCurrentItem();
if (stack != null && stack.getItem() instanceof ItemDDKey)
{
return false;
}
if(!checkCanOpen(world, x, y, z, player))
{
return false;
}
final int MAGIC_CONSTANT = 1003;
int metadata = this.getFullMetadata(world, x, y, z);
@@ -104,7 +92,6 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
}
world.playAuxSFXAtEntity(player, MAGIC_CONSTANT, x, y, z, 0);
return true;
}
@@ -172,26 +159,28 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
reversed = !reversed;
}
}
if (isUpperDoorBlock(fullMetadata))
{
return this.upperTextures[reversed ? 1 : 0];
}
return this.lowerTextures[reversed ? 1 : 0];
else
return this.lowerTextures[reversed ? 1 : 0];
}
else
{
return this.lowerTextures[0];
}
return this.lowerTextures[0];
}
//Called to update the render information on the tile entity. Could probably implement a data watcher,
//but this works fine and is more versatile I think.
public BaseDimDoor updateAttachedTile(World world, int x, int y, int z)
{
mod_pocketDim.proxy.updateDoorTE(this, world, x, y, z);
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityDimDoor)
{
int metadata = world.getBlockMetadata(x, y, z);
TileEntityDimDoor dimTile = (TileEntityDimDoor) tile;
dimTile.openOrClosed = isDoorOnRift(world, x, y, z) && isUpperDoorBlock(metadata);
dimTile.openOrClosed = this.isDoorOnRift(world, x, y, z)&&this.isUpperDoorBlock(metadata);
dimTile.orientation = this.getFullMetadata(world, x, y, z) & 7;
}
return this;
@@ -199,34 +188,21 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
public boolean isDoorOnRift(World world, int x, int y, int z)
{
return this.getLink(world, x, y, z) != null;
}
public DimLink getLink(World world, int x, int y, int z)
{
DimLink link= PocketManager.getLink(x, y, z, world.provider.dimensionId);
if(link!=null)
if(this.isUpperDoorBlock( world.getBlockMetadata(x, y, z)))
{
return link;
}
if(isUpperDoorBlock( world.getBlockMetadata(x, y, z)))
{
link = PocketManager.getLink(x, y-1, z, world.provider.dimensionId);
if(link!=null)
if(PocketManager.getLink(x, y, z, world.provider.dimensionId) != null||PocketManager.getLink(x, y-1, z, world.provider.dimensionId) != null)
{
return link;
return true;
}
}
else
{
link = PocketManager.getLink(x, y+1, z, world.provider.dimensionId);
if(link != null)
if(PocketManager.getLink(x, y, z, world.provider.dimensionId) != null||PocketManager.getLink(x, y+1, z, world.provider.dimensionId) != null)
{
return link;
return true;
}
}
return null;
return false;
}
/**
@@ -336,14 +312,14 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int neighborID)
{
int metadata = world.getBlockMetadata(x, y, z);
if (isUpperDoorBlock(metadata))
{
if (world.getBlockId(x, y - 1, z) != this.blockID)
{
world.setBlockToAir(x, y, z);
world.setBlock(x, y, z, 0);
}
if (neighborID > 0 && neighborID != this.blockID)
{
this.onNeighborBlockChange(world, x, y - 1, z, neighborID);
@@ -353,13 +329,13 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
{
if (world.getBlockId(x, y + 1, z) != this.blockID)
{
world.setBlockToAir(x, y, z);
world.setBlock(x, y, z, 0);
if (!world.isRemote)
{
this.dropBlockAsItem(world, x, y, z, metadata, 0);
}
}
else if(this.getLockStatus(world, x, y, z)<=1)
else
{
boolean powered = world.isBlockIndirectlyGettingPowered(x, y, z) || world.isBlockIndirectlyGettingPowered(x, y + 1, z);
if ((powered || neighborID > 0 && Block.blocksList[neighborID].canProvidePower()) && neighborID != this.blockID)
@@ -375,20 +351,31 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
*/
@Override
@SideOnly(Side.CLIENT)
public int idPicked(World world, int x, int y, int z)
public int idPicked(World par1World, int par2, int par3, int par4)
{
return this.getDoorItem();
return this.getDrops();
}
/**
* Returns the ID of the items to drop on destruction.
*/
@Override
public int idDropped(int metadata, Random random, int fortune)
public int idDropped(int metadata, Random random, int fortune)
{
return isUpperDoorBlock(metadata) ? 0 : this.getDrops();
}
/**
* Called when the block is attempted to be harvested
*/
@Override
public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer)
{
if (par6EntityPlayer.capabilities.isCreativeMode && (par5 & 8) != 0 && par1World.getBlockId(par2, par3 - 1, par4) == this.blockID)
{
par1World.setBlock(par2, par3 - 1, par4, 0);
}
}
@Override
public TileEntity createNewTileEntity(World world)
{
@@ -442,77 +429,16 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
}
}
public boolean isUpperDoorBlock(int metadata)
public static boolean isUpperDoorBlock(int metadata)
{
return (metadata & 8) != 0;
}
public boolean isDoorOpen(int metadata)
public static boolean isDoorOpen(int metadata)
{
return (metadata & 4) != 0;
}
/**
* 0 if link is no lock;
* 1 if there is a lock;
* 2 if the lock is locked.
* @param world
* @param x
* @param y
* @param z
* @return
*/
public byte getLockStatus(World world, int x, int y, int z)
{
byte status = 0;
DimLink link = getLink(world, x, y, z);
if(link!=null&&link.hasLock())
{
status++;
if(link.getLockState())
{
status++;
}
}
return status;
}
public boolean checkCanOpen(World world, int x, int y, int z)
{
return this.checkCanOpen(world, x, y, z, null);
}
public boolean checkCanOpen(World world, int x, int y, int z, EntityPlayer player)
{
DimLink link = getLink(world, x, y, z);
if(link==null||player==null)
{
return link==null;
}
if(!link.getLockState())
{
return true;
}
for(ItemStack item : player.inventory.mainInventory)
{
if(item != null)
{
if(item.getItem() instanceof ItemDDKey)
{
if(link.tryToOpen(item))
{
return true;
}
}
}
}
player.playSound(mod_pocketDim.modid + ":doorLocked", 1F, 1F);
return false;
}
protected static boolean isEntityFacingDoor(int metadata, EntityLivingBase entity)
{
// Although any entity has the proper fields for this check,
@@ -529,18 +455,4 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
world.setBlockTileEntity(x, y, z, te);
return te;
}
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was replaced
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world);
}
}
}

View File

@@ -14,10 +14,8 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDimClient.PrivatePocketRender;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -25,7 +23,7 @@ public class BlockDimWall extends Block
{
private static final float SUPER_HIGH_HARDNESS = 10000000000000F;
private static final float SUPER_EXPLOSION_RESISTANCE = 18000000F;
private Icon[] blockIcon = new Icon[3];
private Icon[] blockIcon = new Icon[2];
public BlockDimWall(int blockID, int j, Material par2Material)
{
@@ -36,7 +34,7 @@ public class BlockDimWall extends Block
@Override
public float getBlockHardness(World world, int x, int y, int z)
{
if (world.getBlockMetadata(x, y, z) != 1)
if (world.getBlockMetadata(x, y, z) == 0)
{
return this.blockHardness;
}
@@ -49,7 +47,7 @@ public class BlockDimWall extends Block
@Override
public float getExplosionResistance(Entity entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ)
{
if (world.getBlockMetadata(x, y, z) != 1)
if (world.getBlockMetadata(x, y, z) == 0)
{
return super.getExplosionResistance(entity, world, x, y, z, explosionX, explosionY, explosionZ);
}
@@ -59,41 +57,25 @@ public class BlockDimWall extends Block
}
}
public int getRenderType()
{
return PrivatePocketRender.renderID;
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.blockIcon[0] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName());
this.blockIcon[1] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "Perm");
this.blockIcon[2] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "Personal");
}
@SideOnly(Side.CLIENT)
@Override
public Icon getIcon(int par1, int par2)
{
switch(par2)
{
case 0:
return blockIcon[0];
case 1:
return blockIcon[1];
case 2:
return blockIcon[2];
default:
return blockIcon[0];
}
return (par2 != 1) ? blockIcon[0] : blockIcon[1];
}
@Override
public int damageDropped(int metadata)
{
//Return 0 to avoid dropping Ancient Fabric even if the player somehow manages to break it
return metadata == 1 ? 0 : metadata;
return 0;
}
@Override
@@ -101,12 +83,11 @@ public class BlockDimWall extends Block
@SideOnly(Side.CLIENT)
public void getSubBlocks(int unknown, CreativeTabs tab, List subItems)
{
for (int ix = 0; ix < 3; ix++)
for (int ix = 0; ix < 2; ix++)
{
subItems.add(new ItemStack(this, 1, ix));
}
}
@Override
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {}
@@ -129,7 +110,7 @@ public class BlockDimWall extends Block
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9)
{
//Check if the metadata value is 0 -- we don't want the user to replace Ancient Fabric
if (entityPlayer.getCurrentEquippedItem() != null && world.getBlockMetadata(x, y, z) != 1)
if (entityPlayer.getCurrentEquippedItem() != null && world.getBlockMetadata(x, y, z) == 0)
{
Item playerEquip = entityPlayer.getCurrentEquippedItem().getItem();

View File

@@ -2,34 +2,123 @@ package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.IconFlipped;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.item.Item;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockDoorGold extends BlockDoor
{
@SideOnly(Side.CLIENT)
private Icon[] upperTextures;
@SideOnly(Side.CLIENT)
private Icon[] lowerTextures;
public BlockDoorGold(int par1, Material par2Material)
{
super(par1, par2Material);
}
@SideOnly(Side.CLIENT)
protected String getTextureName()
{
return mod_pocketDim.modid + ":" + this.getUnlocalizedName();
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister iconRegister)
{
upperTextures = new Icon[2];
lowerTextures = new Icon[2];
upperTextures[0] = iconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "_upper");
lowerTextures[0] = iconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "_lower");
upperTextures[1] = new IconFlipped(upperTextures[0], true, false);
lowerTextures[1] = new IconFlipped(lowerTextures[0], true, false);
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return (par1 & 8) != 0 ? 0 : mod_pocketDim.itemGoldenDoor.itemID;
}
/**
* From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
*/
@Override
@SideOnly(Side.CLIENT)
public Icon getIcon(int side, int metadata)
{
return this.upperTextures[0];
}
/**
* Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side
*/
@Override
@SideOnly(Side.CLIENT)
public Icon getBlockTexture(IBlockAccess blockAccess, int x, int y, int z, int side)
{
if (side != 1 && side != 0)
{
int fullMetadata = this.getFullMetadata(blockAccess, x, y, z);
int orientation = fullMetadata & 3;
boolean reversed = false;
if (BaseDimDoor.isDoorOpen(fullMetadata))
{
if (orientation == 0 && side == 2)
{
reversed = !reversed;
}
else if (orientation == 1 && side == 5)
{
reversed = !reversed;
}
else if (orientation == 2 && side == 3)
{
reversed = !reversed;
}
else if (orientation == 3 && side == 4)
{
reversed = !reversed;
}
}
else
{
if (orientation == 0 && side == 5)
{
reversed = !reversed;
}
else if (orientation == 1 && side == 3)
{
reversed = !reversed;
}
else if (orientation == 2 && side == 4)
{
reversed = !reversed;
}
else if (orientation == 3 && side == 2)
{
reversed = !reversed;
}
if ((fullMetadata & 16) != 0)
{
reversed = !reversed;
}
}
if (BaseDimDoor.isUpperDoorBlock(fullMetadata))
return this.upperTextures[reversed ? 1 : 0];
else
return this.lowerTextures[reversed ? 1 : 0];
}
else
{
return this.lowerTextures[0];
}
}
}

View File

@@ -1,28 +0,0 @@
package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material;
public class BlockDoorQuartz extends BlockDoor
{
public BlockDoorQuartz(int par1, Material par2Material)
{
super(par1, par2Material);
}
@SideOnly(Side.CLIENT)
protected String getTextureName()
{
return mod_pocketDim.modid + ":" + this.getUnlocalizedName();
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return (par1 & 8) != 0 ? 0 : mod_pocketDim.itemGoldenDoor.itemID;
}
}

View File

@@ -3,7 +3,7 @@ package StevenDimDoors.mod_pocketDim.blocks;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold;
@@ -25,21 +25,15 @@ public class BlockGoldDimDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.createDimensionData(world);
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null)
{
dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemGoldenDimensionalDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -9,7 +9,7 @@ import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecay;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

View File

@@ -47,28 +47,14 @@ public class BlockRift extends Block implements ITileEntityProvider
public static final int MAX_WORLD_THREAD_DROP_CHANCE = 1000;
private final DDProperties properties;
private final ArrayList<Integer> blocksImmuneToRift; // List of Vanilla blocks immune to rifts
private final ArrayList<Integer> modBlocksImmuneToRift; // List of DD blocks immune to rifts
private final ArrayList<Integer> blocksImmuneToRift;
public BlockRift(int i, int j, Material par2Material, DDProperties properties)
{
super(i, par2Material);
this.setTickRandomly(true);
this.properties = properties;
this.modBlocksImmuneToRift = new ArrayList<Integer>();
this.modBlocksImmuneToRift.add(properties.FabricBlockID);
this.modBlocksImmuneToRift.add(properties.PermaFabricBlockID);
this.modBlocksImmuneToRift.add(properties.DimensionalDoorID);
this.modBlocksImmuneToRift.add(properties.WarpDoorID);
this.modBlocksImmuneToRift.add(properties.TransTrapdoorID);
this.modBlocksImmuneToRift.add(properties.UnstableDoorID);
this.modBlocksImmuneToRift.add(properties.RiftBlockID);
this.modBlocksImmuneToRift.add(properties.TransientDoorID);
this.modBlocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
this.modBlocksImmuneToRift.add(properties.GoldenDoorID);
this.blocksImmuneToRift = new ArrayList<Integer>();
this.blocksImmuneToRift.add(properties.FabricBlockID);
this.blocksImmuneToRift.add(properties.PermaFabricBlockID);
this.blocksImmuneToRift.add(properties.DimensionalDoorID);
@@ -79,7 +65,7 @@ public class BlockRift extends Block implements ITileEntityProvider
this.blocksImmuneToRift.add(properties.TransientDoorID);
this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
this.blocksImmuneToRift.add(properties.GoldenDoorID);
this.blocksImmuneToRift.add(properties.PersonalDimDoorID);
this.blocksImmuneToRift.add(Block.blockLapis.blockID);
this.blocksImmuneToRift.add(Block.blockIron.blockID);
this.blocksImmuneToRift.add(Block.blockGold.blockID);
@@ -99,6 +85,9 @@ public class BlockRift extends Block implements ITileEntityProvider
return false;
}
@Override
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {}
@Override
public boolean isOpaqueCube()
{
@@ -124,10 +113,10 @@ public class BlockRift extends Block implements ITileEntityProvider
return true;
}
//this doesnt do anything yet.
@Override
public int getRenderType()
{
// This doesn't do anything yet
if (mod_pocketDim.isPlayerWearingGoogles)
{
return 0;
@@ -231,7 +220,7 @@ public class BlockRift extends Block implements ITileEntityProvider
return targets;
}
public void dropWorldThread(int blockID, World world, int x, int y, int z, Random random)
private void dropWorldThread(int blockID, World world, int x, int y, int z, Random random)
{
if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance)
&& !(Block.blocksList[blockID] instanceof BlockFlowing ||
@@ -243,7 +232,7 @@ public class BlockRift extends Block implements ITileEntityProvider
}
}
private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points)
private void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points)
{
Point3D[] neighbors = new Point3D[] {
new Point3D(x - 1, y, z),
@@ -263,6 +252,16 @@ public class BlockRift extends Block implements ITileEntityProvider
}
}
public void regenerateRift(World world, int x, int y, int z, Random random)
{
if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4))
{
int blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, properties.RiftBlockID))
dropWorldThread(blockID, world, x, y, z, random);
}
}
public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random)
{
int x, y, z, blockID;
@@ -414,15 +413,6 @@ public class BlockRift extends Block implements ITileEntityProvider
}
}
public boolean tryPlacingRift(World world, int x, int y, int z)
{
if (world != null && !isBlockImmune(world, x, y, z))
{
return world.setBlock(x, y, z, mod_pocketDim.blockRift.blockID);
}
return false;
}
public boolean isBlockImmune(World world, int x, int y, int z)
{
Block block = Block.blocksList[world.getBlockId(x, y, z)];
@@ -434,21 +424,7 @@ public class BlockRift extends Block implements ITileEntityProvider
// is designed to receive an entity, the source of the blast. We have no entity so
// I've set this to access blockResistance directly. Might need changing later.
return (block.blockResistance >= MIN_IMMUNE_RESISTANCE ||
modBlocksImmuneToRift.contains(block.blockID) ||
blocksImmuneToRift.contains(block.blockID));
}
return false;
}
public boolean isModBlockImmune(World world, int x, int y, int z)
{
// Check whether the block at the specified location is one of the
// rift-resistant blocks from DD.
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (block != null)
{
return modBlocksImmuneToRift.contains(block.blockID);
return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || blocksImmuneToRift.contains(block.blockID));
}
return false;
}
@@ -470,18 +446,4 @@ public class BlockRift extends Block implements ITileEntityProvider
{
return new TileEntityRift();
}
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was changed
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleSlowRegeneration(x, y, z, world);
}
}
}

View File

@@ -3,15 +3,16 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class DimensionalDoor extends BaseDimDoor
{
public DimensionalDoor(int blockID, Material material, DDProperties properties)
{
super(blockID, material, properties);
@@ -22,21 +23,14 @@ public class DimensionalDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.createDimensionData(world);
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null)
{
dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemDimensionalDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -6,39 +6,11 @@ import net.minecraft.world.World;
public interface IDimDoor
{
/**
* A function to enter a dim door and traverse its link, called when a player collides with an open door
* @param world
* @param x
* @param y
* @param z
* @param entity
*/
public void enterDimDoor(World world, int x, int y, int z, Entity entity);
/**
* called when a door is placed to determine how it will place a link
* @param world
* @param x
* @param y
* @param z
*/
public void placeLink(World world, int x, int y, int z);
public int getDrops();
public int getDoorItem();
public TileEntity initDoorTE(World world, int x, int y, int z);
/**
* checks if any of this doors blocks are overlapping with a rift
* @param world
* @param x
* @param y
* @param z
* @return
*/
public boolean isDoorOnRift(World world, int x, int y, int z);
}

View File

@@ -1,47 +0,0 @@
package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
public class PersonalDimDoor extends BaseDimDoor
{
public PersonalDimDoor(int blockID, Material material, DDProperties properties)
{
super(blockID, material, properties);
// TODO Auto-generated constructor stub
}
@Override
public void placeLink(World world, int x, int y, int z)
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null)
{
dimension.createLink(x, y, z, LinkType.PERSONAL, world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDrops()
{
return mod_pocketDim.itemQuartzDoor.itemID;
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemPersonalDoor.itemID;
}
}

View File

@@ -2,28 +2,23 @@ package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockTrapDoor;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor;
@SuppressWarnings("deprecation")
public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntityProvider
{
@@ -46,66 +41,18 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
enterDimDoor(world, x, y, z, entity);
}
public boolean checkCanOpen(World world, int x, int y, int z)
{
return this.checkCanOpen(world, x, y, z, null);
}
public boolean checkCanOpen(World world, int x, int y, int z, EntityPlayer player)
{
DimLink link = PocketManager.getLink( x, y, z, world);
if(link==null||player==null)
{
return link==null;
}
if(!link.getLockState())
{
return true;
}
for(ItemStack item : player.inventory.mainInventory)
{
if(item != null)
{
if(item.getItem() instanceof ItemDDKey)
{
if(link.tryToOpen(item))
{
return true;
}
}
}
}
return false;
}
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
{
if(this.checkCanOpen(par1World, par2, par3, par4, par5EntityPlayer))
{
return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9);
}
return false;
}
public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5)
{
if(this.checkCanOpen(par1World, par2, par3, par4))
{
super.onPoweredBlockChange(par1World, par2, par3, par4, par5);
}
}
@Override
public void enterDimDoor(World world, int x, int y, int z, Entity entity)
{
if (!world.isRemote && isTrapdoorOpen(world.getBlockMetadata(x, y, z)))
{
this.onPoweredBlockChange(world, x, y, z, false);
DimLink link = PocketManager.getLink(x, y, z, world);
if (link != null)
{
DDTeleporter.traverseDimDoor(world, link, entity,this);
}
super.onPoweredBlockChange(world, x, y, z, false);
}
}
@@ -114,6 +61,14 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
{
this.placeLink(world, x, y, z);
world.setBlockTileEntity(x, y, z, this.createNewTileEntity(world));
this.updateAttachedTile(world, x, y, z);
}
@Override
public void updateTick(World world, int x, int y, int z, Random random)
{
TileEntityTransTrapdoor tile = (TileEntityTransTrapdoor) world.getBlockTileEntity(x, y, z);
tile.hasRift = PocketManager.getLink(x, y, z, world) != null;
}
@Override
@@ -122,43 +77,41 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
return new TileEntityTransTrapdoor();
}
public void updateAttachedTile(World world, int x, int y, int z)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityTransTrapdoor)
{
TileEntityTransTrapdoor trapdoorTile = (TileEntityTransTrapdoor) tile;
trapdoorTile.hasRift = (PocketManager.getLink(x, y, z, world) != null);
}
}
@Override
public void placeLink(World world, int x, int y, int z)
{
if (!world.isRemote)
{
NewDimData dimension = PocketManager.createDimensionData(world);
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension())
{
dimension.createLink(x, y, z, LinkType.UNSAFE_EXIT,0);
dimension.createLink(x, y, z, LinkTypes.UNSAFE_EXIT,0);
}
}
}
@Override
@SideOnly(Side.CLIENT)
public int idPicked(World world, int x, int y, int z)
{
return this.getDoorItem();
}
@Override
public int idDropped(int metadata, Random random, int fortuneLevel)
{
return this.getDrops();
return getDrops();
}
@Override
public int getDoorItem()
{
return mod_pocketDim.transTrapdoor.blockID;
}
@Override
public int getDrops()
{
return Block.trapdoor.blockID;
return Block.trapdoor.blockID;
}
public static boolean isTrapdoorSetLow(int metadata)
@@ -173,24 +126,4 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
world.setBlockTileEntity(x, y, z, te);
return te;
}
@Override
public boolean isDoorOnRift(World world, int x, int y, int z)
{
return PocketManager.getLink(x, y, z, world)!=null;
}
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was replaced
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world);
}
}
}

View File

@@ -9,7 +9,7 @@ import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@@ -64,21 +64,15 @@ public class TransientDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.createDimensionData(world);
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension())
{
dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return 0;
}
@Override
public int getDrops()
{

View File

@@ -3,9 +3,8 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@@ -22,16 +21,9 @@ public class UnstableDoor extends BaseDimDoor
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
dimension.createLink(x, y, z, LinkType.RANDOM,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkTypes.RANDOM,world.getBlockMetadata(x, y - 1, z));
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemUnstableDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -3,13 +3,13 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class WarpDoor extends BaseDimDoor
{
public WarpDoor(int blockID, Material material, DDProperties properties)
@@ -22,21 +22,15 @@ public class WarpDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.createDimensionData(world);
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension())
{
dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemWarpDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -1,18 +1,20 @@
package StevenDimDoors.mod_pocketDim.commands;
import java.util.Collection;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
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.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
import java.util.Collection;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
public class CommandCreateDungeonRift extends DDCommandBase
{
private static CommandCreateDungeonRift instance = null;
@@ -36,6 +38,10 @@ public class CommandCreateDungeonRift extends DDCommandBase
NewDimData dimension;
DungeonHelper dungeonHelper = DungeonHelper.instance();
if (sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length == 0)
{
return DDCommandResult.TOO_FEW_ARGUMENTS;
@@ -62,8 +68,7 @@ public class CommandCreateDungeonRift extends DDCommandBase
if (result != null)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
{
// Create a rift to our selected dungeon and notify the player

View File

@@ -1,5 +1,6 @@
package StevenDimDoors.mod_pocketDim.commands;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
@@ -23,21 +24,26 @@ public class CommandCreatePocket extends DDCommandBase
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
if (command.length > 0)
//TODO: Some commands have isRemote checks, some do not. Why? Can commands even run locally anyway?
//What does it mean when you run a command locally? ~SenseiKiwi
if (!sender.worldObj.isRemote)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
if (command.length > 0)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
//Place a door leading to a pocket dimension where the player is standing.
//The pocket dimension will serve as a room for the player to build a dungeon.
int x = (int) sender.posX;
int y = (int) sender.posY;
int z = (int) sender.posZ;
DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z);
//Notify the player
sendChat(sender,("Created a door to a pocket dimension. Please build your dungeon there."));
}
//Place a door leading to a pocket dimension where the player is standing.
//The pocket dimension will serve as a room for the player to build a dungeon.
int x = (int) sender.posX;
int y = (int) sender.posY;
int z = (int) sender.posZ;
DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z);
//Notify the player
sendChat(sender, "Created a door to a pocket dimension. Please build your dungeon there.");
return DDCommandResult.SUCCESS;
}
}

View File

@@ -8,7 +8,7 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
@@ -39,6 +39,10 @@ public class CommandCreateRandomRift extends DDCommandBase
NewDimData dimension;
DungeonHelper dungeonHelper = DungeonHelper.instance();
if (sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length > 1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
@@ -54,8 +58,7 @@ public class CommandCreateRandomRift extends DDCommandBase
if (command.length == 0)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
sender.worldObj.setBlock(x, y + 1, z,mod_pocketDim.blockRift.blockID, 0, 3);
sendChat(sender, "Created a rift to a random dungeon.");
}
@@ -71,8 +74,7 @@ public class CommandCreateRandomRift extends DDCommandBase
if (result != null)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
{
// Create a rift to our selected dungeon and notify the player
@@ -116,6 +118,9 @@ public class CommandCreateRandomRift extends DDCommandBase
{
return null;
}
return matches.get( random.nextInt(matches.size()) );
else
{
return matches.get( random.nextInt(matches.size()) );
}
}
}

View File

@@ -0,0 +1,69 @@
package StevenDimDoors.mod_pocketDim.commands;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import java.util.ArrayList;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
@SuppressWarnings("deprecation")
public class CommandDeleteAllLinks extends DDCommandBase
{
private static CommandDeleteAllLinks instance = null;
private CommandDeleteAllLinks()
{
super("dd-deletelinks", "???");
}
public static CommandDeleteAllLinks instance()
{
if (instance == null)
instance = new CommandDeleteAllLinks();
return instance;
}
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
int linksRemoved=0;
int targetDim;
boolean shouldGo= true;
if(command.length==1)
{
targetDim = parseInt(sender, command[0]);
}
else
{
targetDim=0;
shouldGo=false;
sendChat(sender, ("Error-Invalid argument, delete_all_links <targetDimID>"));
}
if(shouldGo)
{
NewDimData dim = PocketManager.getDimensionData(targetDim);
ArrayList<DimLink> linksInDim = dim.getAllLinks();
for (DimLink link : linksInDim)
{
World targetWorld = PocketManager.loadDimension(targetDim);
targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0);
dim.deleteLink(link);
//TODO Probably should check what the block is, but thats annoying so Ill do it later.
linksRemoved++;
}
sendChat(sender,("Removed " + linksRemoved + " links."));
}
return DDCommandResult.SUCCESS; //TEMPORARY HACK
}
}

View File

@@ -2,21 +2,22 @@ package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
@SuppressWarnings("deprecation")
public class CommandDeleteRifts extends DDCommandBase
{
private static CommandDeleteRifts instance = null;
private CommandDeleteRifts()
{
super("dd-deleterifts", "[dimension number]");
super("dd-???", "???");
}
public static CommandDeleteRifts instance()
@@ -30,64 +31,47 @@ public class CommandDeleteRifts extends DDCommandBase
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
int linksRemoved = 0;
int targetDimension;
int linksRemoved=0;
int targetDim;
boolean shouldGo= true;
if (command.length > 1)
if(command.length==1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
if (command.length == 0)
{
targetDimension = sender.worldObj.provider.dimensionId;
targetDim = parseInt(sender, command[0]);
}
else
{
try
{
targetDimension = Integer.parseInt(command[0]);
}
catch (NumberFormatException e)
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
targetDim=0;
shouldGo=false;
sendChat(sender,("Error-Invalid argument, delete_all_links <targetDimID>"));
}
World world = PocketManager.loadDimension(targetDimension);
if (world == null)
if(shouldGo)
{
return DDCommandResult.UNREGISTERED_DIMENSION;
}
int x;
int y;
int z;
Point4D location;
NewDimData dimension = PocketManager.createDimensionData(world);
ArrayList<DimLink> links = dimension.getAllLinks();
for (DimLink link : links)
{
location = link.source();
x = location.getX();
y = location.getY();
z = location.getZ();
if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID)
{
// Remove the rift and its link
world.setBlockToAir(x, y, z);
dimension.deleteLink(link);
linksRemoved++;
}
else if (!mod_pocketDim.blockRift.isBlockImmune(world, x, y, z))
{
// If a block is not immune, then it must not be a DD block.
// The link would regenerate into a rift eventually.
// We only need to remove the link.
dimension.deleteLink(link);
linksRemoved++;
}
NewDimData dim = PocketManager.getDimensionData(targetDim);
ArrayList<DimLink> linksInDim = dim.getAllLinks();
for (DimLink link : linksInDim)
{
World targetWorld = PocketManager.loadDimension(targetDim);
if(!mod_pocketDim.blockRift.isBlockImmune(sender.worldObj,link.source().getX(), link.source().getY(), link.source().getZ())||
(targetWorld.getBlockId(link.source().getX(), link.source().getY(), link.source().getZ())==mod_pocketDim.blockRift.blockID))
{
linksRemoved++;
targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0);
dim.deleteLink(link);
}
//TODO Probably should check what the block is, but thats annoying so Ill do it later.
}
sendChat(sender,("Removed " + linksRemoved + " links."));
}
sendChat(sender, "Removed " + linksRemoved + " links.");
return DDCommandResult.SUCCESS;
return DDCommandResult.SUCCESS; //TEMPORARY HACK
}
}

View File

@@ -2,6 +2,7 @@ package StevenDimDoors.mod_pocketDim.commands;
import java.io.File;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
@@ -59,51 +60,66 @@ public class CommandExportDungeon extends DDCommandBase
//Export the schematic
return exportDungeon(sender, command[0]);
}
//The schematic name contains illegal characters. Inform the user.
return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores.");
else
{
//The schematic name contains illegal characters. Inform the user.
return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores.");
}
}
else
{
//The command is malformed in some way. Assume that the user meant to use
//the 3-argument version and report an error.
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
//The command is malformed in some way. Assume that the user meant to use
//the 3-argument version and report an error.
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
//The user must have used the 3-argument version of this command
//TODO: This validation should be in DungeonHelper or in another class. We should move it
//during the save file format rewrite. ~SenseiKiwi
//TODO: Why do we check remoteness here but not before? And why not for the other export case?
//Something feels wrong... ~SenseiKiwi
if (!sender.worldObj.isRemote)
{
//TODO: This validation should be in DungeonHelper or in another class. We should move it
//during the save file format rewrite. ~SenseiKiwi
if (!dungeonHelper.validateDungeonType(command[0], dungeonHelper.getDungeonPack("ruins")))
{
return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types.");
}
if (!DungeonHelper.DUNGEON_NAME_PATTERN.matcher(command[1]).matches())
{
return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes.");
}
if (!command[2].equalsIgnoreCase("open") && !command[2].equalsIgnoreCase("closed"))
{
return new DDCommandResult("Error: Please specify whether the dungeon is 'open' or 'closed'.");
}
//If there are no more arguments, export the dungeon.
if (command.length == 3)
{
return exportDungeon(sender, join(command, "_", 0, 3));
}
//Validate the weight argument
try
{
int weight = Integer.parseInt(command[3]);
if (weight >= DungeonHelper.MIN_DUNGEON_WEIGHT && weight <= DungeonHelper.MAX_DUNGEON_WEIGHT)
if (!dungeonHelper.validateDungeonType(command[0], dungeonHelper.getDungeonPack("ruins")))
{
return exportDungeon(sender, join(command, "_", 0, 4));
return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types.");
}
if (!DungeonHelper.DUNGEON_NAME_PATTERN.matcher(command[1]).matches())
{
return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes.");
}
if (!command[2].equalsIgnoreCase("open") && !command[2].equalsIgnoreCase("closed"))
{
return new DDCommandResult("Error: Please specify whether the dungeon is 'open' or 'closed'.");
}
}
catch (Exception e) { }
//If we've reached this point, then we must have an invalid weight.
return new DDCommandResult("Invalid dungeon weight. Please specify a weight between "
+ DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive.");
//If there are no more arguments, export the dungeon.
if (command.length == 3)
{
return exportDungeon(sender, join(command, "_", 0, 3));
}
else
{
//Validate the weight argument
try
{
int weight = Integer.parseInt(command[3]);
if (weight >= DungeonHelper.MIN_DUNGEON_WEIGHT && weight <= DungeonHelper.MAX_DUNGEON_WEIGHT)
{
return exportDungeon(sender, join(command, "_", 0, 4));
}
}
catch (Exception e) { }
}
//If we've reached this point, then we must have an invalid weight.
return new DDCommandResult("Invalid dungeon weight. Please specify a weight between "
+ DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive.");
}
return DDCommandResult.SUCCESS;
}
private static DDCommandResult exportDungeon(EntityPlayer player, String name)
@@ -121,7 +137,10 @@ public class CommandExportDungeon extends DDCommandBase
dungeonHelper.registerDungeon(exportPath, dungeonHelper.getDungeonPack("ruins"), false, true);
return DDCommandResult.SUCCESS;
}
return new DDCommandResult("Error: Failed to save dungeon schematic!");
else
{
return new DDCommandResult("Error: Failed to save dungeon schematic!");
}
}
private static String join(String[] source, String delimiter, int start, int end)

View File

@@ -31,6 +31,10 @@ public class CommandListDungeons extends DDCommandBase
int pageCount;
ArrayList<String> dungeonNames;
if (sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length > 1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;

View File

@@ -1,14 +1,16 @@
package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList;
import java.util.HashSet;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class CommandResetDungeons extends DDCommandBase
{
private static CommandResetDungeons instance = null;
@@ -29,78 +31,61 @@ public class CommandResetDungeons extends DDCommandBase
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
if(sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length > 0)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
int id;
int resetCount = 0;
int dungeonCount = 0;
HashSet<Integer> deletedDimensions = new HashSet<Integer>();
ArrayList<NewDimData> loadedDungeons = new ArrayList<NewDimData>();
int resetCount = 0;
ArrayList<Integer> dimsToDelete = new ArrayList<Integer>();
ArrayList<Integer> dimsToFix = new ArrayList<Integer>();
// Copy the list of dimensions to iterate over the copy. Otherwise,
// we would trigger an exception by modifying the original list.
ArrayList<NewDimData> dimensions = new ArrayList<NewDimData>();
for (NewDimData dimension : PocketManager.getDimensions())
for (NewDimData data : PocketManager.getDimensions())
{
dimensions.add(dimension);
}
// Iterate over the list of dimensions. Check which ones are dungeons.
// If a dungeon is found, try to delete it. If it can't be deleted,
// then it must be loaded and needs to be updated to prevent bugs.
for (NewDimData dimension : dimensions)
{
if (dimension.type() == DimensionType.DUNGEON)
if(DimensionManager.getWorld(data.id())==null&&data.isDungeon())
{
resetCount++;
dungeonCount++;
id = dimension.id();
if (PocketManager.deletePocket(dimension, true))
dimsToDelete.add(data.id());
}
else if(data.isDungeon())
{
dimsToFix.add(data.id());
dungeonCount++;
for(DimLink link : data.links())
{
resetCount++;
deletedDimensions.add(id);
}
else
{
loadedDungeons.add(dimension);
if(link.linkType()==LinkTypes.REVERSE)
{
data.createLink(link.source(), LinkTypes.DUNGEON_EXIT, link.orientation());
}
if(link.linkType()==LinkTypes.DUNGEON)
{
data.createLink(link.source(), LinkTypes.DUNGEON, link.orientation());
}
}
}
}
// Modify the loaded dungeons to prevent bugs
for (NewDimData dungeon : loadedDungeons)
for(Integer dimID:dimsToDelete)
{
// Find top-most loaded dungeons and update their parents.
// They will automatically update their children.
// Dungeons with non-dungeon parents don't need to be fixed.
if (dungeon.parent() == null)
{
dungeon.setParentToRoot();
}
// Links to any deleted dungeons must be replaced
for (DimLink link : dungeon.links())
{
if (link.hasDestination() && deletedDimensions.contains(link.destination().getDimension()))
{
if (link.linkType() == LinkType.DUNGEON)
{
dungeon.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null);
}
else if (link.linkType() == LinkType.REVERSE)
{
dungeon.createLink(link.source(), LinkType.DUNGEON_EXIT, link.orientation(), null);
}
}
}
PocketManager.deletePocket(PocketManager.getDimensionData(dimID), true);
}
// Notify the user of the results
/**
* temporary workaround
*/
for(Integer dimID: dimsToFix)
{
PocketManager.getDimensionData(dimID).setParentToRoot();
}
//TODO- for some reason the parent field of loaded dimenions get reset to null if I call .setParentToRoot() before I delete the pockets.
//TODO implement blackList
//Notify the user of the results
sendChat(sender,("Reset complete. " + resetCount + " out of " + dungeonCount + " dungeons were reset."));
return DDCommandResult.SUCCESS;
}

View File

@@ -1,23 +1,23 @@
package StevenDimDoors.mod_pocketDim.commands;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import java.util.Arrays;
import java.util.List;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.DimensionManager;
public class CommandTeleportPlayer extends DDCommandBase
{
private static CommandTeleportPlayer instance = null;
private CommandTeleportPlayer()
{
super("dd-tp", new String[] {
"<player name> <dimension number>",
"<player name> <x> <y> <z>",
"<player name> <dimension number> <x> <y> <z>"} );
super("dd-tp", new String[] {"<Player Name> <Dimension ID> <X Coord> <Y Coord> <Z Coord>","<Player Name> <Dimension ID>"} );
}
public static CommandTeleportPlayer instance()
@@ -28,119 +28,110 @@ public class CommandTeleportPlayer extends DDCommandBase
return instance;
}
/**
* TODO- Change to accept variety of input, like just coords, just dim ID, or two player names.
*/
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
int x;
int y;
int z;
World world;
int dimensionID;
Point4D destination;
NewDimData dimension;
boolean checkOrientation;
EntityPlayer targetPlayer;
EntityPlayer targetPlayer = sender;
int dimDestinationID = sender.worldObj.provider.dimensionId;
if (command.length < 2)
if(command.length == 5)
{
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
if (command.length > 5)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
if (command.length == 3)
{
return DDCommandResult.INVALID_ARGUMENTS;
}
// Check that all arguments after the username are integers
for (int k = 1; k < command.length; k++)
{
if (!isInteger(command[k]))
for(int i= 1; i <5;i++)
{
return DDCommandResult.INVALID_ARGUMENTS;
if(!isInteger(command[i]))
{
return DDCommandResult.INVALID_ARGUMENTS;
}
}
}
// Check if the target player is logged in
targetPlayer = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(command[0]);
if (targetPlayer == null)
{
return DDCommandResult.PLAYER_OFFLINE;
}
// If a dimension ID was provided, try to load it
if (command.length != 4)
{
dimensionID = Integer.parseInt(command[1]);
world = PocketManager.loadDimension(dimensionID);
if (world == null)
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player
{
return DDCommandResult.UNREGISTERED_DIMENSION;
}
}
else
{
dimensionID = targetPlayer.worldObj.provider.dimensionId;
world = targetPlayer.worldObj;
}
// If we teleport to a pocket dimension, set checkOrientation to true
// so the player is placed correctly relative to the entrance door.
checkOrientation = false;
// Parse or calculate the destination as necessary
// The Y coordinate must be increased by 1 because of the way that
// DDTeleporter considers destination points. It assumes that the
// point provided is the upper block of a door.
if (command.length == 2)
{
// Check if the destination is a pocket dimension
dimension = PocketManager.createDimensionData(world);
if (dimension.isPocketDimension())
{
// The destination is a pocket dimension.
// Teleport the player to its original entrance (the origin).
destination = dimension.origin();
checkOrientation = true;
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]);
}
else
{
// The destination is not a pocket dimension, which means we
// don't automatically know a safe location where we can send
// the player. Send the player to (0, Y, 0), where Y is chosen
// by searching. Add 2 to place the player ABOVE the top block.
y = world.getTopSolidOrLiquidBlock(0, 0) + 2;
destination = new Point4D(0, y, 0, dimensionID);
return DDCommandResult.INVALID_ARGUMENTS;
}
dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
PocketManager.loadDimension(dimDestinationID);
Point4D destination = new Point4D(Integer.parseInt(command[2]),Integer.parseInt(command[3]),Integer.parseInt(command[4]),dimDestinationID);
DDTeleporter.teleportEntity(targetPlayer, destination, false);
}
else if (command.length == 4)
else if(command.length == 2 && isInteger(command[1]))
{
x = Integer.parseInt(command[1]);
y = Integer.parseInt(command[2]) + 1; // Correct the Y value
z = Integer.parseInt(command[3]);
destination = new Point4D(x, y, z, dimensionID);
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player
{
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]);
}
else
{
return DDCommandResult.INVALID_ARGUMENTS;
}
dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin();
if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension())
{
destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock(
destination.getX(), destination.getZ()),
destination.getZ(),destination.getDimension());
}
DDTeleporter.teleportEntity(targetPlayer, destination, false);
}
else if(command.length == 1 && isInteger(command[0]))
{
targetPlayer = sender;
dimDestinationID=Integer.parseInt(command[0]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin();
if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension())
{
destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock(
destination.getX(), destination.getZ()),
destination.getZ(),destination.getDimension());
}
DDTeleporter.teleportEntity(targetPlayer, destination, false);
}
else
{
x = Integer.parseInt(command[2]);
y = Integer.parseInt(command[3]) + 1; // Correct the Y value
z = Integer.parseInt(command[4]);
destination = new Point4D(x, y, z, dimensionID);
return DDCommandResult.INVALID_ARGUMENTS;
}
// Teleport!
DDTeleporter.teleportEntity(targetPlayer, destination, checkOrientation);
return DDCommandResult.SUCCESS;
}
private static boolean isInteger(String input)
{
try
{
Integer.parseInt(input);
return true;
}
catch(Exception e)
{
return false;
}
}
public boolean isInteger( String input )
{
try
{
Integer.parseInt( input );
return true;
}
catch(Exception e )
{
return false;
}
}
}

View File

@@ -5,6 +5,7 @@ import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatMessageComponent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
/*
* An abstract base class for our Dimensional Doors commands. This cleans up the code a little and provides
@@ -95,15 +96,13 @@ public abstract class DDCommandBase extends CommandBase
* that Dryware and Technic Jenkins don't have those functions defined. How in the world?
* I have no idea. But it's breaking our builds. -_- ~SenseiKiwi
*/
@Override
public int compareTo(ICommand command)
public int compareTo(ICommand par1ICommand)
{
return this.getCommandName().compareTo(command.getCommandName());
return this.getCommandName().compareTo(par1ICommand.getCommandName());
}
@Override
public int compareTo(Object other)
public int compareTo(Object par1Obj)
{
return this.compareTo((ICommand) other);
return this.compareTo((ICommand)par1Obj);
}
}

View File

@@ -8,8 +8,7 @@ public class DDCommandResult {
public static final DDCommandResult TOO_MANY_ARGUMENTS = new DDCommandResult(2, "Error: Too many arguments passed to the command", true);
public static final DDCommandResult INVALID_DIMENSION_ID = new DDCommandResult(3, "Error: Invalid dimension ID", true);
public static final DDCommandResult UNREGISTERED_DIMENSION = new DDCommandResult(4, "Error: Dimension is not registered", false);
public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command", true);
public static final DDCommandResult PLAYER_OFFLINE = new DDCommandResult(6, "Error: Player is not online", false);
public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command.", true);
public static final int CUSTOM_ERROR_CODE = -1;

View File

@@ -23,9 +23,6 @@ public class DDProperties
public final int TransientDoorID;
public final int FabricBlockID;
public final int RiftBlockID;
public final int QuartzDoorID;
public final int PersonalDimDoorID;
/**
* World Generation Block IDs
@@ -49,9 +46,7 @@ public class DDProperties
public final int UnstableDoorItemID;
public final int WarpDoorItemID;
public final int WorldThreadItemID;
public final int DDKeyItemID;
public final int ItemQuartzDoorID;
public final int ItemPersonalDimDoorID;
/**
* Other IDs
@@ -62,7 +57,6 @@ public class DDProperties
public final int LimboDimensionID;
public final int LimboProviderID;
public final int PocketProviderID;
public final int PersonalPocketProviderID;
public final int DoorRenderEntityID;
public final int MonolithEntityID;
@@ -81,9 +75,6 @@ public class DDProperties
public final boolean CraftingStableFabricAllowed;
public final boolean CraftingGoldenDimensionalDoorAllowed;
public final boolean CraftingGoldenDoorAllowed;
public final boolean CraftingDDKeysAllowed;
public final boolean CraftingQuartzDoorAllowed;
public final boolean CraftingPersonalDimDoorAllowed;
/**
* Loot Flags
@@ -156,9 +147,6 @@ public class DDProperties
CraftingStableFabricAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Stable Fabric", true).getBoolean(true);
CraftingGoldenDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Door", true).getBoolean(true);
CraftingGoldenDimensionalDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Dimensional Door", true).getBoolean(true);
CraftingDDKeysAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Rift Keys", true).getBoolean(true);
CraftingQuartzDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Quartz Doors", true).getBoolean(true);
CraftingPersonalDimDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Personal Dim Doors", true).getBoolean(true);
WorldThreadRequirementLevel = config.get(CATEGORY_CRAFTING, "World Thread Requirement Level", 4,
"Controls the amount of World Thread needed to craft Stable Fabric. The number must be an " +
@@ -204,8 +192,6 @@ public class DDProperties
TransientDoorID = config.getBlock("Transient Door Block ID", 1979).getInt();
GoldenDoorID = config.getBlock("Gold Door Block ID", 1980).getInt();
GoldenDimensionalDoorID = config.getBlock("Gold Dim Door Block ID", 1981).getInt();
QuartzDoorID = config.getBlock("Quartz Door Block ID", 1982).getInt();
PersonalDimDoorID = config.getBlock("Personal Dim Door ID", 1983).getInt();
WarpDoorItemID = config.getItem("Warp Door Item ID", 5670).getInt();
RiftRemoverItemID = config.getItem("Rift Remover Item ID", 5671).getInt();
@@ -218,9 +204,6 @@ public class DDProperties
GoldenDoorItemID = config.getItem("Gold Door Item ID", 5678).getInt();
GoldenDimensionalDoorItemID = config.getItem("Gold Dim Door Item ID", 5679).getInt();
WorldThreadItemID = config.getItem("World Thread Item ID", 5680).getInt();
DDKeyItemID = config.getItem("Rift Key Item ID", 5681).getInt();
ItemQuartzDoorID = config.getItem("Quartz Door Item ID", 5681).getInt();
ItemPersonalDimDoorID = config.getItem("Personal Dim Door ID", 5681).getInt();
LimboBlockID = config.getTerrainBlock("World Generation Block IDs - must be less than 256", "Limbo Block ID", 217,
"Blocks used for the terrain in Limbo").getInt();
@@ -230,7 +213,6 @@ public class DDProperties
LimboDimensionID = config.get(CATEGORY_DIMENSION, "Limbo Dimension ID", -23).getInt();
PocketProviderID = config.get(CATEGORY_PROVIDER, "Pocket Provider ID", 124).getInt();
LimboProviderID = config.get(CATEGORY_PROVIDER, "Limbo Provider ID", 113).getInt();
PersonalPocketProviderID = config.get(CATEGORY_PROVIDER, "Personal Pocket Provider ID", 125).getInt();
MonolithTeleportationEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Monolith Teleportation", true,
"Sets whether Monoliths can teleport players").getBoolean(true);

View File

@@ -9,6 +9,7 @@ public class DDWorldProperties
/**
* World Generation Settings
*/
public final DimensionFilter RiftClusterDimensions;
public final DimensionFilter RiftGatewayDimensions;
@@ -16,7 +17,7 @@ public class DDWorldProperties
* General Flags
*/
public final boolean LimboEscapeEnabled;
public final boolean UniversalLimboEnabled;
//Names of categories
private static final String CATEGORY_WORLD_GENERATION = "world generation";
@@ -43,12 +44,6 @@ public class DDWorldProperties
"generates near the bottom of the dimension. If disabled, players could still leave through " +
"dungeons in Limbo or by dying (if Hardcore Limbo is disabled). The default value is true.").getBoolean(true);
UniversalLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Universal Limbo", false,
"Sets whether players are teleported to Limbo when they die in any dimension (except Limbo). " +
"Normally, players only go to Limbo if they die in a pocket dimension. This setting will not " +
"affect deaths in Limbo, which can be set with the Hardcore Limbo option. " +
"The default value is false.").getBoolean(false);
config.save();
}

View File

@@ -1,169 +0,0 @@
package StevenDimDoors.mod_pocketDim.core;
import java.io.IOException;
import com.google.gson.stream.JsonReader;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagIntArray;
import net.minecraft.nbt.NBTTagList;
public class DDLock
{
private boolean lockState;
private final int lockKey;
public DDLock(boolean isLocked, int lockKey)
{
this.lockState = isLocked;
this.lockKey = lockKey;
}
public int getLockKey()
{
return this.lockKey;
}
/**
* See if the lock is currently locked. False if there is no lock.
* @return
*/
public boolean getLockState()
{
return this.lockState;
}
/**
* set the state of the lock. Returns false if there is no lock to set,
* otherwise returns true
* @param flag
*/
protected void setLockState(boolean flag)
{
this.lockState = flag;
}
/**
* see if we could unlock this door if it where locked.
* @param link
* @param itemStack
* @return
*/
public boolean doesKeyUnlock(ItemStack itemStack)
{
for(int key :getKeys(itemStack))
{
if(this.lockKey == key)
{
return true;
}
}
return false;
}
/**
* Tries to open this lock
* @param item
* @return
*/
public boolean tryToOpen(ItemStack itemStack)
{
return (!this.lockState)||this.doesKeyUnlock(itemStack);
}
/**
* sets the key/s to the given key/s
* @return
* @return
*/
/**
* gets all the keys stored on a single key item
* @return
*/
public static int[] getKeys(ItemStack itemStack)
{
if (!itemStack.hasTagCompound())
{
initNBTTags(itemStack);
}
return itemStack.getTagCompound().getIntArray("DDKeys");
}
/**
* adds the key/s to the given key
* @return
* @return
*/
public static void addKeys(ItemStack itemStack, int[] keysToAdd)
{
int[] oldKeys = DDLock.getKeys(itemStack);
int[] newKeys = new int[keysToAdd.length+oldKeys.length];
System.arraycopy(oldKeys, 0, newKeys, 0, oldKeys.length);
System.arraycopy(keysToAdd, 0, newKeys, oldKeys.length, keysToAdd.length);
setKeys(itemStack,newKeys);
}
/**
* sets the key/s to the given key/s
* @return
* @return
*/
public static void setKeys(ItemStack itemStack, int[] keys)
{
if (!itemStack.hasTagCompound())
{
initNBTTags(itemStack);
}
NBTTagCompound tag = itemStack.getTagCompound();
tag.setIntArray("DDKeys", keys);
itemStack.setTagCompound(tag);
}
/**
* Gives the key a new NBTTag
* @param itemStack
*/
public static void initNBTTags(ItemStack itemStack)
{
itemStack.setTagCompound(new NBTTagCompound());
NBTTagCompound tag = itemStack.getTagCompound();
tag.setIntArray("DDKeys", new int[0]);
tag.setBoolean("HasCreatedLock", false);
itemStack.setTagCompound(tag);
}
public static boolean hasCreatedLock(ItemStack key)
{
if(isItemKey(key))
{
if(key.hasTagCompound())
{
return key.getTagCompound().getBoolean("HasCreatedLock");
}
initNBTTags(key);
}
return false;
}
public static boolean isItemKey(ItemStack key)
{
return key.getItem() instanceof ItemDDKey;
}
protected static DDLock generateLockKeyPair(ItemStack itemStack, int lockKey2)
{
itemStack.getTagCompound().setBoolean("HasCreatedLock", true);
DDLock.setKeys(itemStack, new int[]{lockKey2});
return new DDLock(true, lockKey2);
}
}

View File

@@ -2,6 +2,7 @@ package StevenDimDoors.mod_pocketDim.core;
import java.util.ArrayList;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
@@ -22,9 +23,9 @@ import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import StevenDimDoors.mod_pocketDim.util.Point4D;
@@ -51,49 +52,59 @@ public class DDTeleporter
private DDTeleporter() { }
/**
* Checks if the destination supplied is safe (i.e. filled by any replaceable or non-opaque blocks)
/**Checks if the destination supplied is valid, ie, filled by any non-replaceable block.
*
* @param entity
* @param world
* @param destination
* @param properties
* @return
*/
private static boolean checkDestination(WorldServer world, Point4D destination, int orientation)
private static boolean checkDestination(Entity entity, WorldServer world, Point4D destination,DDProperties properties)
{
int x = destination.getX();
int y = destination.getY();
int z = destination.getZ();
int blockIDTop;
int blockIDBottom;
Point3D point;
int orientation;
orientation = getDestinationOrientation(destination, properties);
entity.rotationYaw = (orientation * 90) + 90;
switch (orientation)
{
case 0:
point = new Point3D(x - 1, y - 1, z);
point = new Point3D(MathHelper.floor_double(x - 0.5), y - 1, MathHelper.floor_double(z + 0.5));
break;
case 1:
point = new Point3D(x, y - 1, z - 1);
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z - 0.5));
break;
case 2:
point = new Point3D(x + 1, y - 1, z);
point = new Point3D(MathHelper.floor_double(x + 1.5), y - 1, MathHelper.floor_double(z + 0.5));
break;
case 3:
point = new Point3D(x, y - 1, z + 1);
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z + 1.5));
break;
default:
point = new Point3D(x, y - 1, z);
break;
}
blockIDBottom = world.getBlockId(point.getX(), point.getY(), point.getZ());
blockIDTop = world.getBlockId(point.getX(), point.getY() + 1, point.getZ());
blockIDTop = world.getBlockId(point.getX(), point.getY()+1, point.getZ());
if (Block.blocksList[blockIDBottom] != null)
{
if (!Block.blocksList[blockIDBottom].isBlockReplaceable(world, point.getX(), point.getY(), point.getZ()) && world.isBlockOpaqueCube(point.getX(), point.getY(), point.getZ()))
if(!Block.blocksList[blockIDBottom].isBlockReplaceable(world, point.getX(), point.getY(), point.getZ())&&world.isBlockOpaqueCube(point.getX(), point.getY(), point.getZ()))
{
return false;
}
}
if (Block.blocksList[blockIDTop] != null)
{
if (!Block.blocksList[blockIDTop].isBlockReplaceable(world, point.getX(), point.getY() + 1, point.getZ()))
if (!Block.blocksList[blockIDTop].isBlockReplaceable(world, point.getX(), point.getY()+1, point.getZ()))
{
return false;
}
@@ -115,37 +126,56 @@ public class DDTeleporter
}
else
{
// Teleport the entity to the precise destination point
//Teleport the entity to the precise destination point
orientation = -1;
}
if (entity instanceof EntityPlayer)
if (!checkDestination(entity, world, destination, properties))
{
if (entity instanceof EntityPlayerMP)
{
EntityPlayer player = (EntityPlayer) entity;
player.rotationYaw = (orientation * 90) + 90;
switch (orientation)
{
case 0:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 1:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 2:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 3:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
default:
player.setPositionAndUpdate(x, y - 1, z);
break;
}
}
}
else if (entity instanceof EntityPlayer)
{
EntityPlayer player = (EntityPlayer) entity;
if (checkDestination(world, destination, orientation))
switch (orientation)
{
switch (orientation)
{
case 0:
player.setPositionAndUpdate(x - 0.5, y - 1, z + 0.5);
break;
case 1:
player.setPositionAndUpdate(x + 0.5, y - 1, z - 0.5);
break;
case 2:
player.setPositionAndUpdate(x + 1.5, y - 1, z + 0.5);
break;
case 3:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 1.5);
break;
default:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
}
}
else
{
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
case 0:
player.setPositionAndUpdate(x - 0.5, y - 1, z + 0.5);
break;
case 1:
player.setPositionAndUpdate(x + 0.5, y - 1, z - 0.5);
break;
case 2:
player.setPositionAndUpdate(x + 1.5, y - 1, z + 0.5);
break;
case 3:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 1.5);
break;
default:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
}
}
else if (entity instanceof EntityMinecart)
@@ -171,7 +201,7 @@ public class DDTeleporter
entity.worldObj.updateEntityWithOptionalForce(entity, false);
break;
case 3:
DDTeleporter.setEntityPosition(entity, x + 0.5, y, z + 1.5);
DDTeleporter.setEntityPosition(entity, x + 0.5, y, z + 1.5 );
entity.motionZ = 0.39;
entity.worldObj.updateEntityWithOptionalForce(entity, false);
break;
@@ -221,14 +251,15 @@ public class DDTeleporter
}
//Check if the block below that point is actually a door
Block block = Block.blocksList[world.getBlockId(door.getX(), door.getY() - 1, door.getZ())];
if (block==null || !(block instanceof IDimDoor))
int blockID = world.getBlockId(door.getX(), door.getY() - 1, door.getZ());
if (blockID != properties.DimensionalDoorID && blockID != properties.WarpDoorID &&
blockID != properties.TransientDoorID && blockID != properties.UnstableDoorID
&& blockID != properties.GoldenDimensionalDoorID)
{
//Return the pocket's orientation instead
return PocketManager.createDimensionData(world).orientation();
return PocketManager.getDimensionData(door.getDimension()).orientation();
}
//Return the orientation portion of its metadata
return world.getBlockMetadata(door.getX(), door.getY() - 1, door.getZ()) & 3;
}
@@ -293,7 +324,7 @@ public class DDTeleporter
// to prevent us from doing bad things. Moreover, no dimension is being created, so if we ever
// tie code to that, it could cause confusing bugs.
// No hacky for you! ~SenseiKiwi
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionData(newWorld)));
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(destination.getDimension())));
// Set the new dimension and inform the client that it's moving to a new world.
player.dimension = destination.getDimension();
@@ -427,11 +458,11 @@ public class DDTeleporter
return;
}
if (!initializeDestination(link, DDProperties.instance(),entity,door))
if (!initializeDestination(link, DDProperties.instance(),door))
{
return;
}
if (link.linkType() == LinkType.RANDOM)
if (link.linkType() == LinkTypes.RANDOM)
{
Point4D randomDestination = getRandomDestination();
if (randomDestination != null)
@@ -443,43 +474,18 @@ public class DDTeleporter
else
{
buildExitDoor(door, link, DDProperties.instance());
entity = teleportEntity(entity, link.destination(), link.linkType() != LinkType.UNSAFE_EXIT);
entity = teleportEntity(entity, link.destination(), link.linkType() != LinkTypes.UNSAFE_EXIT);
entity.worldObj.playSoundEffect(entity.posX, entity.posY, entity.posZ, "mob.endermen.portal", 1.0F, 1.0F);
}
}
private static boolean initializeDestination(DimLink link, DDProperties properties, Entity entity, Block door)
private static boolean initializeDestination(DimLink link, DDProperties properties, Block door)
{
if (link.hasDestination()&&link.linkType()!=LinkType.PERSONAL)
if (link.hasDestination())
{
if (PocketManager.isBlackListed(link.destination().getDimension()))
if(PocketManager.isBlackListed(link.destination().getDimension()))
{
// This link leads to a dimension that has been blacklisted.
// That means that it was a pocket and it was deleted.
// Depending on the link type, we must overwrite it or cancel
// the teleport operation. We don't need to assign 'link' with
// a different value. NewDimData will overwrite it in-place.
NewDimData start = PocketManager.getDimensionData(link.source().getDimension());
if (link.linkType() == LinkType.DUNGEON)
{
// Ovewrite the link into a dungeon link with no destination
start.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null);
}
else
{
if (start.isPocketDimension())
{
// Ovewrite the link into a safe exit link, because
// this could be the only way out from a pocket.
start.createLink(link.source(), LinkType.SAFE_EXIT, link.orientation(), null);
}
else
{
// Cancel the teleport attempt
return false;
}
}
link=PocketManager.getDimensionData(link.source().getDimension()).createLink(link.link.point,LinkTypes.SAFE_EXIT,link.link.orientation);
}
else
{
@@ -490,50 +496,25 @@ public class DDTeleporter
// Check the destination type and respond accordingly
switch (link.linkType())
{
case DUNGEON:
case LinkTypes.DUNGEON:
return PocketBuilder.generateNewDungeonPocket(link, properties);
case POCKET:
return PocketBuilder.generateNewPocket(link, properties, door, DimensionType.POCKET);
case PERSONAL:
return setupPersonalLink(link, properties, entity, door);
case SAFE_EXIT:
case LinkTypes.POCKET:
return PocketBuilder.generateNewPocket(link, properties,door);
case LinkTypes.SAFE_EXIT:
return generateSafeExit(link, properties);
case DUNGEON_EXIT:
case LinkTypes.DUNGEON_EXIT:
return generateDungeonExit(link, properties);
case UNSAFE_EXIT:
case LinkTypes.UNSAFE_EXIT:
return generateUnsafeExit(link);
case NORMAL:
case REVERSE:
case RANDOM:
case LinkTypes.NORMAL:
case LinkTypes.REVERSE:
case LinkTypes.RANDOM:
return true;
default:
throw new IllegalArgumentException("link has an unrecognized link type.");
}
}
private static boolean setupPersonalLink(DimLink link, DDProperties properties,Entity player, Block door)
{
if(!(player instanceof EntityPlayer))
{
return false;
}
NewDimData dim = PocketManager.getPersonalDimensionForPlayer(player.getEntityName());
if(dim == null)
{
return PocketBuilder.generateNewPersonalPocket(link, properties, player, door);
}
DimLink personalHomeLink = dim.getLink(dim.origin());
if(personalHomeLink!=null)
{
PocketManager.getDimensionData(link.source().getDimension()).setLinkDestination(personalHomeLink, link.source().getX(), link.source().getY(), link.source().getZ());
}
dim.setLinkDestination(link, dim.origin.getX(), dim.origin.getY(), dim.origin.getZ());
return true;
}
private static Point4D getRandomDestination()
{
// Our aim is to return a random link's source point
@@ -551,7 +532,7 @@ public class DDTeleporter
{
for (DimLink link : dimension.getAllLinks())
{
if (link.linkType() != LinkType.RANDOM)
if (link.linkType() != LinkTypes.RANDOM)
{
matches.add(link.source());
}
@@ -563,7 +544,10 @@ public class DDTeleporter
{
return matches.get( random.nextInt(matches.size()) );
}
return null;
else
{
return null;
}
}
private static boolean generateUnsafeExit(DimLink link)
@@ -577,8 +561,7 @@ public class DDTeleporter
// To avoid loops, don't generate a destination if the player is
// already in a non-pocket dimension.
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension());
if (current.isPocketDimension())
{
Point4D source = link.source();
@@ -591,7 +574,7 @@ public class DDTeleporter
Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ());
if (destination != null)
{
current.root().setLinkDestination(link, destination.getX(), destination.getY(), destination.getZ());
current.root().setDestination(link, destination.getX(), destination.getY(), destination.getZ());
return true;
}
}
@@ -602,7 +585,7 @@ public class DDTeleporter
{
World startWorld = PocketManager.loadDimension(link.source().getDimension());
World destWorld = PocketManager.loadDimension(link.destination().getDimension());
TileEntity doorTE = startWorld.getBlockTileEntity(link.source().getX(), link.source().getY(), link.point.getZ());
TileEntity doorTE = startWorld.getBlockTileEntity(link.source().getX(), link.source().getY(), link.link.point.getZ());
if(doorTE instanceof TileEntityDimDoor)
{
if((TileEntityDimDoor.class.cast(doorTE).hasGennedPair))
@@ -632,10 +615,9 @@ public class DDTeleporter
}
}
}
private static boolean generateSafeExit(DimLink link, DDProperties properties)
{
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension());
return generateSafeExit(current.root(), link, properties);
}
@@ -646,8 +628,7 @@ public class DDTeleporter
// There is a chance of choosing the Nether first before other root dimensions
// to compensate for servers with many Mystcraft ages or other worlds.
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension());
ArrayList<NewDimData> roots = PocketManager.getRootDimensions();
int shiftChance = START_ROOT_SHIFT_CHANCE + ROOT_SHIFT_CHANCE_PER_LEVEL * (current.packDepth() - 1);
@@ -655,11 +636,11 @@ public class DDTeleporter
{
if (current.root().id() != OVERWORLD_DIMENSION_ID && random.nextInt(MAX_OVERWORLD_EXIT_CHANCE) < OVERWORLD_EXIT_CHANCE)
{
return generateSafeExit(PocketManager.createDimensionDataDangerously(OVERWORLD_DIMENSION_ID), link, properties);
return generateSafeExit(PocketManager.getDimensionData(OVERWORLD_DIMENSION_ID), link, properties);
}
if (current.root().id() != NETHER_DIMENSION_ID && random.nextInt(MAX_NETHER_EXIT_CHANCE) < NETHER_EXIT_CHANCE)
{
return generateSafeExit(PocketManager.createDimensionDataDangerously(NETHER_DIMENSION_ID), link, properties);
return generateSafeExit(PocketManager.getDimensionData(NETHER_DIMENSION_ID), link, properties);
}
for (int attempts = 0; attempts < 10; attempts++)
{
@@ -763,17 +744,16 @@ public class DDTeleporter
// Create a reverse link for returning
int orientation = getDestinationOrientation(source, properties);
NewDimData sourceDim = PocketManager.getDimensionData(link.source().getDimension());
DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkType.REVERSE,orientation);
sourceDim.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkTypes.REVERSE,orientation);
sourceDim.setDestination(reverse, source.getX(), source.getY(), source.getZ());
// Set up the warp door at the destination
orientation = BlockRotator.transformMetadata(orientation, 2, properties.WarpDoorID);
ItemDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor);
ItemDimensionalDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor);
// Complete the link to the destination
// This comes last so the destination isn't set unless everything else works first
destinationDim.setLinkDestination(link, x, y + 2, z);
destinationDim.setDestination(link, x, y + 2, z);
}
return (destination != null);

View File

@@ -2,99 +2,73 @@ package StevenDimDoors.mod_pocketDim.core;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.world.ChunkCoordIntPair;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
public abstract class DimLink
{
protected Point4D point;
protected int orientation;
protected DDLock lock;
protected ClientLinkData link;
protected DimLink parent;
protected LinkTail tail;
protected List<DimLink> children;
protected DimLink(Point4D point, int orientation, DDLock lock, DimLink parent)
protected DimLink(ClientLinkData link, DimLink parent)
{
if (parent.point.getDimension() != point.getDimension())
if (parent.link.point.getDimension() != link.point.getDimension())
{
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension.");
}
this.lock = lock;
this.parent = parent;
this.point = point;
this.link = link;
this.tail = parent.tail;
this.orientation = orientation;
this.children = new LinkedList<DimLink>();
parent.children.add(this);
}
protected DimLink(Point4D point, int orientation, DDLock lock, LinkType linkType)
protected DimLink(ClientLinkData link, int linkType)
{
/**This really cant happen anymore, I guess.
*
if ((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE)
{
throw new IllegalArgumentException("The specified link type is invalid.");
}
**/
this.lock = lock;
this.parent = null;
this.point = point;
this.orientation = orientation;
this.link = link;
this.tail = new LinkTail(linkType, null);
this.children = new LinkedList<DimLink>();
}
public Point4D source()
{
return point;
}
public void clear()
{
//Release children
for (DimLink child : children)
{
child.parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
parent.children.remove(this);
}
parent = null;
point = null;
tail = new LinkTail(LinkType.NORMAL, null);
return link.point;
}
public int orientation()
{
return orientation;
return link.orientation;
}
public ClientLinkData link()
{
return link;
}
public Point4D destination()
{
return tail.getDestination();
}
public int getDestinationOrientation()
{
DimLink destinationLink = PocketManager.getLink(tail.getDestination());
if (destinationLink != null)
DimLink link = PocketManager.getLink(this.destination().getX(), this.destination().getY(), this.destination().getZ(), this.destination().getDimension());
if(link !=null)
{
return destinationLink.orientation();
return link.orientation();
}
return (orientation + 2) % 4;
return (this.orientation()+2)%4;
}
public boolean hasDestination()
{
return (tail.getDestination() != null);
@@ -115,65 +89,13 @@ public abstract class DimLink
return parent;
}
public LinkType linkType()
public int linkType()
{
return tail.getLinkType();
}
/**
* Tries to open this lock. Returns true if the lock is open or if the key can open it
* @return
*/
public boolean tryToOpen(ItemStack item)
{
return lock.tryToOpen(item);
}
/**
* Tests if the given key item fits this lock
* @return
*/
public boolean doesKeyUnlock(ItemStack item)
{
return lock.doesKeyUnlock(item);
}
/**
* test if there is a lock, regardless if it is locked or not.
* @return
*/
public boolean hasLock()
{
return this.lock!=null;
}
/**
* Tests if the lock is open or not
*
*/
public boolean getLockState()
{
return this.hasLock()&&this.lock.getLockState();
}
/**
* gets the actual lock object
* @return
*/
public DDLock getLock()
{
return this.lock;
}
public ChunkCoordIntPair getChunkCoordinates()
{
return new ChunkCoordIntPair(point.getX() >> 4, point.getZ() >> 4);
}
@Override
public String toString()
{
return point + " -> " + (hasDestination() ? destination() : "()");
return link.point + " -> " + (hasDestination() ? destination() : "");
}
}

View File

@@ -1,41 +0,0 @@
package StevenDimDoors.mod_pocketDim.core;
public enum DimensionType
{
// WARNING: Don't modify these values carelessly or you'll risk breaking existing worlds!
ROOT(0,false),
POCKET(1,true),
DUNGEON(2,true),
PERSONAL(3,true);
DimensionType(int index, boolean isPocket)
{
this.index = index;
this.isPocket = isPocket;
}
public final int index;
public final boolean isPocket;
/**
* Get the DimensionType given an index. I feel like there should be a better way to do this.
* @param index
* @return
*/
public static DimensionType getTypeFromIndex(int index)
{
for(DimensionType type : DimensionType.values())
{
if(type.index == index)
{
return type;
}
}
return null;
}
public boolean isPocketDimension()
{
return this.isPocket;
}
}

View File

@@ -2,5 +2,5 @@ package StevenDimDoors.mod_pocketDim.core;
public interface IDimRegistrationCallback
{
public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type);
public NewDimData registerDimension(int dimensionID, int rootID);
}

View File

@@ -5,9 +5,9 @@ import StevenDimDoors.mod_pocketDim.util.Point4D;
class LinkTail
{
private Point4D destination;
private LinkType linkType;
private int linkType;
public LinkTail(LinkType linkType, Point4D destination)
public LinkTail(int linkType, Point4D destination)
{
this.linkType = linkType;
this.destination = destination;
@@ -21,11 +21,12 @@ class LinkTail
this.destination = destination;
}
public LinkType getLinkType() {
public int getLinkType() {
return linkType;
}
public void setLinkType(LinkType linkType) {
public void setLinkType(int linkType) {
this.linkType = linkType;
}
}

View File

@@ -1,42 +0,0 @@
package StevenDimDoors.mod_pocketDim.core;
import java.util.HashMap;
public enum LinkType
{
// WARNING: Don't modify these values carelessly or you'll risk breaking links in existing worlds!
NORMAL(0),
POCKET(1),
DUNGEON(2),
RANDOM(3),
DUNGEON_EXIT(4),
SAFE_EXIT(5),
UNSAFE_EXIT(6),
REVERSE(7),
PERSONAL(8),
CLIENT(-1337);
LinkType(int index)
{
this.index = index;
}
public final int index;
/**
* Get the LinkType given an index. I feel like there should be a better way to do this.
* @param index
* @return
*/
public static LinkType getLinkTypeFromIndex(int index)
{
for(LinkType type : LinkType.values())
{
if(type.index == index)
{
return type;
}
}
return null;
}
}

View File

@@ -0,0 +1,21 @@
package StevenDimDoors.mod_pocketDim.core;
public class LinkTypes
{
private LinkTypes() { }
public static final int ENUM_MIN = 0;
public static final int ENUM_MAX = 7;
public static final int CLIENT_SIDE = -1337;
// WARNING: Don't modify these values carelessly or you'll risk breaking links in existing worlds!
public static final int NORMAL = 0;
public static final int POCKET = 1;
public static final int DUNGEON = 2;
public static final int RANDOM = 3;
public static final int DUNGEON_EXIT = 4;
public static final int SAFE_EXIT = 5;
public static final int UNSAFE_EXIT = 6;
public static final int REVERSE = 7;
}

View File

@@ -1,42 +1,32 @@
package StevenDimDoors.mod_pocketDim.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Stack;
import java.util.TreeMap;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import net.minecraft.item.ItemStack;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import StevenDimDoors.mod_pocketDim.saving.PackedDungeonData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkTail;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
public abstract class NewDimData implements IPackable<PackedDimData>
public abstract class NewDimData
{
private static class InnerDimLink extends DimLink
{
public InnerDimLink(Point4D source, DimLink parent, int orientation, DDLock lock)
public InnerDimLink(Point4D source, DimLink parent, int orientation)
{
super(source, orientation, lock, parent);
super(new ClientLinkData(source, orientation), parent);
}
public InnerDimLink(Point4D source, LinkType linkType, int orientation, DDLock lock)
public InnerDimLink(Point4D source, int linkType, int orientation)
{
super(source, orientation, lock, linkType);
super(new ClientLinkData(source, orientation), linkType);
}
public void setDestination(int x, int y, int z, NewDimData dimension)
@@ -44,6 +34,26 @@ public abstract class NewDimData implements IPackable<PackedDimData>
tail.setDestination(new Point4D(x, y, z, dimension.id()));
}
public void clear()
{
//Release children
for (DimLink child : children)
{
((InnerDimLink) child).parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
parent.children.remove(this);
}
parent = null;
link = null;
tail = new LinkTail(0, null);
}
public boolean overwrite(InnerDimLink nextParent,int orientation)
{
if (nextParent == null)
@@ -55,7 +65,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
//Ignore this request silently
return false;
}
if (nextParent.point.getDimension() != point.getDimension())
if (nextParent.link.point.getDimension() != link.point.getDimension())
{
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension.");
@@ -78,11 +88,11 @@ public abstract class NewDimData implements IPackable<PackedDimData>
parent = nextParent;
tail = nextParent.tail;
nextParent.children.add(this);
this.orientation=orientation;
this.link.orientation=orientation;
return true;
}
public void overwrite(LinkType linkType, int orientation)
public void overwrite(int linkType, int orientation)
{
//Release children
for (DimLink child : children)
@@ -101,54 +111,19 @@ public abstract class NewDimData implements IPackable<PackedDimData>
parent = null;
tail = new LinkTail(linkType, null);
//Set new orientation
this.orientation=orientation;
this.link.orientation=orientation;
}
/**
* only use this on the client to update errything
* @param lock
*/
public void setLock(DDLock lock)
{
this.lock = lock;
}
/**
* create a lock from a key. Returns false if this door already has a lock, or if they has already locked a door
* @param itemStack
* @return
*/
public boolean createLock(ItemStack itemStack, int lockKey)
{
if(this.hasLock()||DDLock.hasCreatedLock(itemStack))
{
return false;
}
this.lock = DDLock.generateLockKeyPair(itemStack, lockKey);
return true;
}
public void removeLock(ItemStack itemStack, InnerDimLink link)
{
if(link.doesKeyUnlock(itemStack))
{
link.lock = null;
}
}
}
private static int EXPECTED_LINKS_PER_CHUNK = 2;
protected static Random random = new Random();
protected int id;
protected Map<Point4D, InnerDimLink> linkMapping;
protected List<InnerDimLink> linkList;
protected boolean isDungeon;
protected boolean isFilled;
protected int depth;
protected int packDepth;
protected DimensionType type;
protected NewDimData parent;
protected NewDimData root;
protected List<NewDimData> children;
@@ -158,16 +133,18 @@ public abstract class NewDimData implements IPackable<PackedDimData>
protected boolean modified;
public IUpdateWatcher<ClientLinkData> linkWatcher;
// Don't write this field to a file - it should be recreated on startup
private Map<ChunkCoordIntPair, List<InnerDimLink>> chunkMapping;
protected NewDimData(int id, NewDimData parent, DimensionType type, IUpdateWatcher<ClientLinkData> linkWatcher)
protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon,
IUpdateWatcher<ClientLinkData> linkWatcher)
{
if (type != DimensionType.ROOT && (parent == null))
// The isPocket flag is redundant. It's meant as an integrity safeguard.
if (isPocket && (parent == null))
{
throw new NullPointerException("Dimensions can be pocket dimensions if and only if they have a parent dimension.");
}
if (isDungeon && !isPocket)
{
throw new IllegalArgumentException("A dimensional dungeon must also be a pocket dimension.");
}
this.id = id;
this.linkMapping = new TreeMap<Point4D, InnerDimLink>(); //Should be stored in oct tree -- temporary solution
@@ -175,13 +152,12 @@ public abstract class NewDimData implements IPackable<PackedDimData>
this.children = new ArrayList<NewDimData>();
this.parent = parent;
this.packDepth = 0;
this.type = type;
this.isDungeon = isDungeon;
this.isFilled = false;
this.orientation = 0;
this.origin = null;
this.dungeon = null;
this.linkWatcher = linkWatcher;
this.chunkMapping = new HashMap<ChunkCoordIntPair, List<InnerDimLink>>();
this.modified = true;
//Register with parent
@@ -200,7 +176,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
}
}
protected NewDimData(int id, NewDimData root, DimensionType type)
protected NewDimData(int id, NewDimData root)
{
// This constructor is meant for client-side code only
if (root == null)
@@ -214,7 +190,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
this.children = new ArrayList<NewDimData>();
this.parent = null;
this.packDepth = 0;
this.type = type;
this.isDungeon = false;
this.isFilled = false;
this.orientation = 0;
this.origin = null;
@@ -222,26 +198,28 @@ public abstract class NewDimData implements IPackable<PackedDimData>
this.linkWatcher = null;
this.depth = 0;
this.root = root;
this.chunkMapping = null;
}
public DimLink findNearestRift(World world, int range, int x, int y, int z)
{
// Sanity check...
//TODO: Rewrite this later to use an octtree
//Sanity check...
if (world.provider.dimensionId != id)
{
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
}
// Note: Only detect rifts at a distance > 0, so we ignore the rift
// at the center of the search space.
DimLink link;
DimLink nearest = null;
//Note: Only detect rifts at a distance > 1, so we ignore the rift
//that called this function and any adjacent rifts.
DimLink nearest = null;
DimLink link;
int i, j, k;
int distance;
int minDistance = Integer.MAX_VALUE;
int i, j, k;
DDProperties properties = DDProperties.instance();
for (i = -range; i <= range; i++)
@@ -253,7 +231,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
distance = getAbsoluteSum(i, j, k);
if (distance > 0 && distance < minDistance && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID)
{
link = getLink(x + i, y + j, z + k);
link = getLink(x+i, y+j, z+k);
if (link != null)
{
nearest = link;
@@ -269,19 +247,23 @@ public abstract class NewDimData implements IPackable<PackedDimData>
public ArrayList<DimLink> findRiftsInRange(World world, int range, int x, int y, int z)
{
// Sanity check...
ArrayList<DimLink> links = new ArrayList<DimLink>();
//TODO: Rewrite this later to use an octtree
//Sanity check...
if (world.provider.dimensionId != id)
{
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
}
// Note: Only detect rifts at a distance > 0, so we ignore the rift
// at the center of the search space.
int i, j, k;
int distance;
//Note: Only detect rifts at a distance > 1, so we ignore the rift
//that called this function and any adjacent rifts.
DimLink link;
int distance;
int i, j, k;
DDProperties properties = DDProperties.instance();
ArrayList<DimLink> links = new ArrayList<DimLink>();
for (i = -range; i <= range; i++)
{
@@ -292,7 +274,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
distance = getAbsoluteSum(i, j, k);
if (distance > 0 && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID)
{
link = getLink(x + i, y + j, z + k);
link = getLink(x+i, y+j, z+k);
if (link != null)
{
links.add(link);
@@ -310,33 +292,20 @@ public abstract class NewDimData implements IPackable<PackedDimData>
return Math.abs(i) + Math.abs(j) + Math.abs(k);
}
public DimLink createLink(int x, int y, int z, LinkType linkType, int orientation)
public DimLink createLink(int x, int y, int z, int linkType, int orientation)
{
return createLink(new Point4D(x, y, z, id), linkType, orientation, null);
return createLink(new Point4D(x, y, z, id), linkType, orientation);
}
public DimLink createLink(Point4D source, LinkType linkType, int orientation, DDLock locked)
public DimLink createLink(Point4D source, int linkType, int orientation)
{
// Return an existing link if there is one to avoid creating multiple links starting at the same point.
//Return an existing link if there is one to avoid creating multiple links starting at the same point.
InnerDimLink link = linkMapping.get(source);
if (link == null)
{
link = new InnerDimLink(source, linkType, orientation, locked);
link = new InnerDimLink(source, linkType, orientation);
linkMapping.put(source, link);
linkList.add(link);
// If this code is running on the server side, add this link to chunkMapping.
if (linkType != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
chunkLinks.add(link);
}
}
else
{
@@ -345,59 +314,44 @@ public abstract class NewDimData implements IPackable<PackedDimData>
modified = true;
//Link created!
if (linkType != LinkType.CLIENT)
if (linkType != LinkTypes.CLIENT_SIDE)
{
linkWatcher.onCreated(new ClientLinkData(link));
linkWatcher.onCreated(link.link);
}
return link;
}
public DimLink createChildLink(int x, int y, int z, DimLink parent)
{
return createChildLink(new Point4D(x, y, z, id), (InnerDimLink) parent, null);
}
public DimLink createChildLink(Point4D source, DimLink parent, DDLock locked)
{
// To avoid having multiple links at a single point, if we find an existing link then we overwrite
// its destination data instead of creating a new instance.
if (parent == null)
{
throw new IllegalArgumentException("parent cannot be null.");
}
return createChildLink(new Point4D(x, y, z, id), (InnerDimLink) parent);
}
private DimLink createChildLink(Point4D source, InnerDimLink parent)
{
//To avoid having multiple links at a single point, if we find an existing link then we overwrite
//its destination data instead of creating a new instance.
InnerDimLink link = linkMapping.get(source);
if (link == null)
{
link = new InnerDimLink(source, parent, parent.orientation, locked);
link = new InnerDimLink(source, parent, parent.link.orientation);
linkMapping.put(source, link);
linkList.add(link);
// If this code is running on the server side, add this link to chunkMapping.
// Granted, the client side code should never create child links anyway...
if (link.linkType() != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
chunkLinks.add(link);
}
// Link created!
linkWatcher.onCreated(new ClientLinkData(link));
//Link created!
linkWatcher.onCreated(link.link);
}
else
{
if (link.overwrite((InnerDimLink) parent, parent.orientation))
if (link.overwrite(parent, parent.link.orientation))
{
//Link created!
linkWatcher.onCreated(new ClientLinkData(link));
linkWatcher.onCreated(link.link);
}
}
modified = true;
@@ -414,20 +368,8 @@ public abstract class NewDimData implements IPackable<PackedDimData>
if (target != null)
{
linkList.remove(target);
// If this code is running on the server side, remove this link to chunkMapping.
if (link.linkType() != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = target.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks != null)
{
chunkLinks.remove(target);
}
}
// Raise deletion event
linkWatcher.onDeleted(new ClientLinkData(link));
//Raise deletion event
linkWatcher.onDeleted(target.link);
target.clear();
modified = true;
}
@@ -436,10 +378,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
public boolean deleteLink(int x, int y, int z)
{
return this.deleteLink(this.getLink(x, y, z));
}
public boolean deleteLink(Point4D location)
{
Point4D location = new Point4D(x, y, z, id);
return this.deleteLink(this.getLink(location));
}
@@ -451,7 +390,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
public DimLink getLink(Point3D location)
{
return linkMapping.get(new Point4D(location.getX(), location.getY(), location.getZ(), this.id));
return linkMapping.get(new Point4D(location.getX(),location.getY(),location.getZ(),this.id));
}
public DimLink getLink(Point4D location)
@@ -474,10 +413,11 @@ public abstract class NewDimData implements IPackable<PackedDimData>
return (root != this);
}
public DimensionType type()
public boolean isDungeon()
{
return this.type;
return isDungeon;
}
public boolean isFilled()
{
return isFilled;
@@ -551,7 +491,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon)
{
if (this.type != DimensionType.DUNGEON)
if (!isDungeon)
{
throw new IllegalStateException("Cannot invoke initializeDungeon() on a non-dungeon dimension.");
}
@@ -563,7 +503,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
{
throw new IllegalArgumentException("orientation must be between 0 and 3, inclusive.");
}
setLinkDestination(incoming, originX, originY, originZ);
setDestination(incoming, originX, originY, originZ);
this.origin = incoming.destination();
this.orientation = orientation;
this.dungeon = dungeon;
@@ -576,42 +516,11 @@ public abstract class NewDimData implements IPackable<PackedDimData>
*/
public void setParentToRoot()
{
// Update this dimension's information
if (parent != null)
{
parent.children.remove(this);
}
this.depth = 1;
this.parent = this.root;
this.root.children.add(this);
this.root.modified = true;
this.modified = true;
if (this.type == DimensionType.DUNGEON)
{
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
// Update the depths for child dimensions using a depth-first traversal
Stack<NewDimData> ordering = new Stack<NewDimData>();
ordering.addAll(this.children);
while (!ordering.isEmpty())
{
NewDimData current = ordering.pop();
current.resetDepth();
ordering.addAll(current.children);
}
}
private void resetDepth()
{
// We assume that this is only applied to dimensions with parents
this.depth = this.parent.depth + 1;
if (this.type == DimensionType.DUNGEON)
{
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
this.modified = true;
}
public static int calculatePackDepth(NewDimData parent, DungeonData current)
@@ -640,7 +549,10 @@ public abstract class NewDimData implements IPackable<PackedDimData>
{
return parent.packDepth + 1;
}
return 1;
else
{
return 1;
}
}
public void initializePocket(int originX, int originY, int originZ, int orientation, DimLink incoming)
@@ -654,47 +566,19 @@ public abstract class NewDimData implements IPackable<PackedDimData>
throw new IllegalStateException("The dimension has already been initialized.");
}
setLinkDestination(incoming, originX, originY, originZ);
setDestination(incoming, originX, originY, originZ);
this.origin = incoming.destination();
this.orientation = orientation;
this.modified = true;
}
public void setLinkDestination(DimLink incoming, int x, int y, int z)
public void setDestination(DimLink incoming, int x, int y, int z)
{
InnerDimLink link = (InnerDimLink) incoming;
link.setDestination(x, y, z, this);
this.modified = true;
}
public void lock(DimLink link, boolean locked)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.lock.setLockState(locked);
modified = true;
}
public void setLock(DimLink link, DDLock lock)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.setLock(lock);
modified = true;
}
public void createLock(DimLink link, ItemStack item, int lockKey)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.createLock(item, lockKey);
modified = true;
}
public void removeLock(DimLink link, ItemStack item)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.removeLock(item, innerLink);
modified = true;
}
public DimLink getRandomLink()
{
if (linkMapping.isEmpty())
@@ -705,17 +589,10 @@ public abstract class NewDimData implements IPackable<PackedDimData>
{
return linkList.get(random.nextInt(linkList.size()));
}
return linkList.get(0);
}
public Iterable<? extends DimLink> getChunkLinks(int chunkX, int chunkZ)
{
List<InnerDimLink> chunkLinks = chunkMapping.get(new ChunkCoordIntPair(chunkX, chunkZ));
if (chunkLinks != null)
else
{
return chunkLinks;
return linkList.get(0);
}
return new ArrayList<InnerDimLink>(0);
}
public boolean isModified()
@@ -728,101 +605,6 @@ public abstract class NewDimData implements IPackable<PackedDimData>
this.modified = false;
}
public void clear()
{
// If this dimension has a parent, remove it from its parent's list of children
if (parent != null)
{
parent.children.remove(this);
}
// Remove this dimension as the parent of its children
for (NewDimData child : children)
{
child.parent = null;
}
// Clear all fields
id = Integer.MIN_VALUE;
linkMapping.clear();
linkMapping = null;
linkList.clear();
linkList = null;
children.clear();
children = null;
type = null;
isFilled = false;
depth = Integer.MIN_VALUE;
packDepth = Integer.MIN_VALUE;
origin = null;
orientation = Integer.MIN_VALUE;
dungeon = null;
linkWatcher = null;
}
public PackedDimData pack()
{
ArrayList<Integer> ChildIDs = new ArrayList<Integer>();
ArrayList<PackedLinkData> Links = new ArrayList<PackedLinkData>();
ArrayList<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
PackedDungeonData packedDungeon=null;
if(this.dungeon!=null)
{
packedDungeon= new PackedDungeonData(dungeon.weight(), dungeon.isOpen(), dungeon.isInternal(),
dungeon.schematicPath(), dungeon.schematicName(), dungeon.dungeonType().Name,
dungeon.dungeonType().Owner.getName());
}
//Make a list of children
for(NewDimData data : this.children)
{
ChildIDs.add(data.id);
}
for(DimLink link:this.links())
{
ArrayList<Point3D> children = new ArrayList<Point3D>();
Point3D parentPoint = new Point3D(-1,-1,-1);
if(link.parent!=null)
{
parentPoint=link.parent.point.toPoint3D();
}
for(DimLink childLink : link.children)
{
children.add(childLink.source().toPoint3D());
}
PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
Links.add(new PackedLinkData(link.point,parentPoint,tail,link.orientation,children,link.lock));
PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
if(Tails.contains(tempTail))
{
Tails.add(tempTail);
}
}
int parentID=this.id;
Point3D originPoint=new Point3D(0,0,0);
if(this.parent!=null)
{
parentID = this.parent.id;
}
if(this.origin!=null)
{
originPoint=this.origin.toPoint3D();
}
return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation,
type, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails);
// FIXME: IMPLEMENTATION PLZTHX
//I tried
}
@Override
public String name()
{
return String.valueOf(id);
}
@Override
public String toString()
{
return "DimID= " + this.id;

View File

@@ -7,26 +7,32 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.Compactor;
import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder;
import StevenDimDoors.mod_pocketDim.saving.DDSaveHandler;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.OldSaveImporter;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import StevenDimDoors.mod_pocketDim.saving.PackedDungeonData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkTail;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* This class regulates all the operations involving the storage and manipulation of dimensions.
@@ -35,25 +41,120 @@ import cpw.mods.fml.relauncher.SideOnly;
*/
public class PocketManager
{
private static class InnerDimData extends NewDimData
private static class InnerDimData extends NewDimData implements IPackable<PackedDimData>
{
// This class allows us to instantiate NewDimData indirectly without exposing
// a public constructor from NewDimData. It's meant to stop us from constructing
// instances of NewDimData going through PocketManager. In turn, that enforces
// that any link destinations must be real dimensions controlled by PocketManager.
public InnerDimData(int id, InnerDimData parent, DimensionType type,
public InnerDimData(int id, InnerDimData parent, boolean isPocket, boolean isDungeon,
IUpdateWatcher<ClientLinkData> linkWatcher)
{
super(id, parent, type, linkWatcher);
super(id, parent, isPocket, isDungeon, linkWatcher);
}
public InnerDimData(int id, NewDimData root, DimensionType type)
public InnerDimData(int id, InnerDimData root)
{
// This constructor is meant for client-side code only
super(id, root, type);
super(id, root);
}
public void clear()
{
// If this dimension has a parent, remove it from its parent's list of children
if (parent != null)
{
parent.children.remove(this);
}
// Remove this dimension as the parent of its children
for (NewDimData child : children)
{
child.parent = null;
}
// Clear all fields
id = Integer.MIN_VALUE;
linkMapping.clear();
linkMapping = null;
linkList.clear();
linkList = null;
children.clear();
children = null;
isDungeon = false;
isFilled = false;
depth = Integer.MIN_VALUE;
packDepth = Integer.MIN_VALUE;
origin = null;
orientation = Integer.MIN_VALUE;
dungeon = null;
linkWatcher = null;
}
@Override
public String name()
{
return String.valueOf(id);
}
@Override
public PackedDimData pack()
{
ArrayList<Integer> ChildIDs = new ArrayList<Integer>();
ArrayList<PackedLinkData> Links = new ArrayList<PackedLinkData>();
ArrayList<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
PackedDungeonData packedDungeon=null;
if(this.dungeon!=null)
{
packedDungeon= new PackedDungeonData(dungeon.weight(), dungeon.isOpen(), dungeon.isInternal(),
dungeon.schematicPath(), dungeon.schematicName(), dungeon.dungeonType().Name,
dungeon.dungeonType().Owner.getName());
}
//Make a list of children
for(NewDimData data : this.children)
{
ChildIDs.add(data.id);
}
for(DimLink link:this.links())
{
ArrayList<Point3D> children = new ArrayList<Point3D>();
Point3D parentPoint = new Point3D(-1,-1,-1);
if(link.parent!=null)
{
parentPoint=link.parent.link.point.toPoint3D();
}
for(DimLink childLink : link.children)
{
children.add(childLink.source().toPoint3D());
}
PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
Links.add(new PackedLinkData(link.link.point,parentPoint,tail,link.link.orientation,children));
PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
if(Tails.contains(tempTail))
{
Tails.add(tempTail);
}
}
int parentID=this.id;
Point3D originPoint=new Point3D(0,0,0);
if(this.parent!=null)
{
parentID = this.parent.id;
}
if(this.origin!=null)
{
originPoint=this.origin.toPoint3D();
}
return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation,
isDungeon, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails);
// FIXME: IMPLEMENTATION PLZTHX
//I tried
}
}
private static class ClientLinkWatcher implements IUpdateWatcher<ClientLinkData>
@@ -63,7 +164,7 @@ public class PocketManager
{
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
dimension.createLink(source, LinkType.CLIENT, 0, link.lock);
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE,link.orientation);
}
@Override
@@ -72,17 +173,7 @@ public class PocketManager
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
dimension.deleteLink(source.getX(), source.getY(), source.getZ());
}
@Override
public void update(ClientLinkData link)
{
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
DimLink dLink = dimension.getLink(source);
dLink.lock=link.lock;
}
}
}
private static class ClientDimWatcher implements IUpdateWatcher<ClientDimData>
@@ -90,7 +181,7 @@ public class PocketManager
@Override
public void onCreated(ClientDimData data)
{
registerClientDimension(data.ID, data.rootID, data.type);
registerClientDimension(data.ID, data.RootID);
}
@Override
@@ -98,12 +189,6 @@ public class PocketManager
{
deletePocket(getDimensionData(data.ID), false);
}
@Override
public void update(ClientDimData message)
{
// TODO Auto-generated method stub
}
}
private static class DimRegistrationCallback implements IDimRegistrationCallback
@@ -114,9 +199,9 @@ public class PocketManager
// exposing a private constructor ONLY to a very specific trusted class.
@Override
public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type)
public NewDimData registerDimension(int dimensionID, int rootID)
{
return registerClientDimension(dimensionID, rootID, type);
return registerClientDimension(dimensionID, rootID);
}
}
@@ -138,9 +223,6 @@ public class PocketManager
//ArrayList that stores the dimension IDs of any dimension that has been deleted.
private static ArrayList<Integer> dimensionIDBlackList = null;
//Stores all the personal pocket mappings
private static HashMap<String, NewDimData> personalPocketsMapping = null;
public static boolean isLoaded()
{
return isLoaded;
@@ -165,8 +247,6 @@ public class PocketManager
dimensionData = new HashMap<Integer, InnerDimData>();
rootDimensions = new ArrayList<NewDimData>();
dimensionIDBlackList = new ArrayList<Integer>();
personalPocketsMapping = new HashMap<String, NewDimData>();
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
{
@@ -178,8 +258,7 @@ public class PocketManager
}
//Register Limbo
DDProperties properties = DDProperties.instance();
registerDimension(properties.LimboDimensionID, null, DimensionType.ROOT);
registerDimension(properties.LimboDimensionID, null, false, false);
loadInternal();
@@ -192,16 +271,12 @@ public class PocketManager
public static boolean registerPackedDimData(PackedDimData packedData)
{
InnerDimData dimData;
DimensionType type = DimensionType.getTypeFromIndex(packedData.DimensionType);
if(type == null)
{
throw new IllegalArgumentException("Invalid dimension type");
}
//register roots
if(packedData.ID==packedData.ParentID)
{
dimData = new InnerDimData(packedData.ID, null, type, linkWatcher);
dimData = new InnerDimData(packedData.ID, null, false, false, linkWatcher);
dimData.root=dimData;
dimData.parent=dimData;
dimData.depth=packedData.Depth;
@@ -213,10 +288,10 @@ public class PocketManager
else //register children
{
InnerDimData test = PocketManager.dimensionData.get(packedData.ParentID);
dimData = new InnerDimData(packedData.ID, test, type, linkWatcher);
dimData = new InnerDimData(packedData.ID, test,true, packedData.IsDungeon, linkWatcher);
dimData.isFilled=packedData.IsFilled;
dimData.origin = new Point4D(packedData.Origin.getX(),packedData.Origin.getY(),packedData.Origin.getZ(),packedData.ID);
dimData.root = PocketManager.createDimensionData(packedData.RootID);
dimData.root=PocketManager.getDimensionData(packedData.RootID);
if(packedData.DungeonData!=null)
{
@@ -240,48 +315,44 @@ public class PocketManager
{
if (deleteFolder)
{
deleteDimensionFiles(dimension);
deleteDimensionFiles(target);
}
// Note: We INTENTIONALLY don't unregister the dimensions that we
// delete with Forge. Instead, we keep them registered to stop Forge
// from reallocating those IDs to other mods such as Mystcraft. This
// is to prevent bugs. Blacklisted dimensions are still properly
// unregistered when the server shuts down.
dimensionIDBlackList.add(dimension.id);
deleteDimensionData(dimension);
deleteDimensionData(dimension.id);
return true;
}
return false;
}
private static void deleteDimensionFiles(InnerDimData dimension)
private static boolean deleteDimensionFiles(NewDimData target)
{
// We assume that the caller checks if the dimension is loaded, for the
// sake of efficiency. Don't call this on a loaded dimension or bad
// things will happen!
String saveRootPath = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath();
File saveDirectory = new File(saveRootPath + "/DimensionalDoors/pocketDimID" + dimension.id());
DeleteFolder.deleteFolder(saveDirectory);
File dataFile = new File(saveRootPath + "/DimensionalDoors/data/dim_" + dimension.id() + ".txt");
dataFile.delete();
InnerDimData dimension = (InnerDimData) target;
if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null)
{
String saveRootPath = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath();
File saveDirectory = new File(saveRootPath + "/DimensionalDoors/pocketDimID" + dimension.id());
DeleteFolder.deleteFolder(saveDirectory);
File dataFile = new File(saveRootPath + "/DimensionalDoors/data/dim_" + dimension.id() + ".txt");
dataFile.delete();
return true;
}
return false;
}
private static void deleteDimensionData(InnerDimData dimension)
private static boolean deleteDimensionData(int dimensionID)
{
// We assume that the caller checks if the dimension is loaded, for the
// sake of efficiency. Don't call this on a loaded dimension or bad
// things will happen!
if (dimensionData.remove(dimension.id()) != null)
if (dimensionData.containsKey(dimensionID) && DimensionManager.getWorld(dimensionID) == null)
{
NewDimData target = PocketManager.getDimensionData(dimensionID);
InnerDimData dimension = (InnerDimData) target;
dimensionData.remove(dimensionID);
// Raise the dim deleted event
getDimwatcher().onDeleted(new ClientDimData(dimension));
dimension.clear();
return true;
}
else
{
// This should never happen. A simple sanity check.
throw new IllegalArgumentException("The specified dimension is not listed with PocketManager.");
}
return false;
}
private static void registerPockets(DDProperties properties)
@@ -292,14 +363,7 @@ public class PocketManager
{
try
{
if(personalPocketsMapping.containsValue(dimension))
{
DimensionManager.registerDimension(dimension.id(), properties.PersonalPocketProviderID);
}
else
{
DimensionManager.registerDimension(dimension.id(), properties.PocketProviderID);
}
DimensionManager.registerDimension(dimension.id(), properties.PocketProviderID);
}
catch (Exception e)
{
@@ -346,6 +410,8 @@ public class PocketManager
*/
private static void loadInternal()
{
//System.out.println(!FMLCommonHandler.instance().getSide().isClient());
File saveDir = DimensionManager.getCurrentSaveRootDirectory();
if (saveDir != null)
{
@@ -358,8 +424,7 @@ public class PocketManager
{
System.out.println("Importing old DD save data...");
OldSaveImporter.importOldSave(oldSaveData);
oldSaveData.renameTo(new File(oldSaveData.getAbsolutePath()+"_IMPORTED"));
oldSaveData.delete();
System.out.println("Import Succesful!");
}
@@ -413,11 +478,6 @@ public class PocketManager
public static WorldServer loadDimension(int id)
{
if (!DimensionManager.isDimensionRegistered(id))
{
return null;
}
WorldServer world = DimensionManager.getWorld(id);
if (world == null)
{
@@ -434,17 +494,10 @@ public class PocketManager
public static NewDimData registerDimension(World world)
{
return registerDimension(world.provider.dimensionId, null, DimensionType.ROOT);
return registerDimension(world.provider.dimensionId, null, false, false);
}
/**
* method to register a new pocket with DD and with forge.
* @param parent
* @param type
* @param playername
* @return
*/
public static NewDimData registerPocket(NewDimData parent, DimensionType type, String playername)
public static NewDimData registerPocket(NewDimData parent, boolean isDungeon)
{
if (parent == null)
{
@@ -453,40 +506,9 @@ public class PocketManager
DDProperties properties = DDProperties.instance();
int dimensionID = DimensionManager.getNextFreeDimId();
//register a personal pocket
if(type == DimensionType.PERSONAL)
{
if(playername == null)
{
throw new IllegalArgumentException("A personal pocket must be attached to a playername");
}
DimensionManager.registerDimension(dimensionID, properties.PersonalPocketProviderID);
NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, type);
personalPocketsMapping.put(playername, data);
return data;
}
else
{ //register a pocket as personal if its parents are personal, but without a mapping.
if(parent.type == DimensionType.PERSONAL)
{
DimensionManager.registerDimension(dimensionID, properties.PersonalPocketProviderID);
NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, DimensionType.PERSONAL);
return data;
}
//register a standard pocket
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
return registerDimension(dimensionID, (InnerDimData) parent, type);
}
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
return registerDimension(dimensionID, (InnerDimData) parent, true, isDungeon);
}
public static NewDimData registerPocket(NewDimData parent, DimensionType type)
{
return registerPocket(parent, type, null);
}
/**
* Registers a dimension with DD but NOT with forge.
* @param dimensionID
@@ -495,7 +517,7 @@ public class PocketManager
* @param isDungeon
* @return
*/
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, DimensionType type)
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, boolean isPocket, boolean isDungeon)
{
if (dimensionData.containsKey(dimensionID))
{
@@ -505,7 +527,7 @@ public class PocketManager
}
throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered.");
}
InnerDimData dimension = new InnerDimData(dimensionID, parent, type, linkWatcher);
InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher);
dimensionData.put(dimensionID, dimension);
if (!dimension.isPocketDimension())
{
@@ -517,17 +539,16 @@ public class PocketManager
}
@SideOnly(Side.CLIENT)
private static NewDimData registerClientDimension(int dimensionID, int rootID, DimensionType type)
private static NewDimData registerClientDimension(int dimensionID, int rootID)
{
// No need to raise events heres since this code should only run on the
// client side. createDimensionData() always handles root dimensions
// properly, even if they weren't defined before.
System.out.println("Registered dim "+dimensionID+" on the client.");
// No need to raise events heres 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 createDimensionData will raise
// 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) createDimensionData(rootID);
InnerDimData root = (InnerDimData) getDimensionData(rootID);
InnerDimData dimension;
if (rootID != dimensionID)
@@ -535,7 +556,7 @@ public class PocketManager
dimension = dimensionData.get(dimensionID);
if (dimension == null)
{
dimension = new InnerDimData(dimensionID, root, type);
dimension = new InnerDimData(dimensionID, root);
dimensionData.put(dimension.id(), dimension);
}
}
@@ -543,7 +564,7 @@ public class PocketManager
{
dimension = root;
}
if (dimension.isPocketDimension() && !DimensionManager.isDimensionRegistered(dimension.id()))
if(dimension.isPocketDimension()&&!DimensionManager.isDimensionRegistered(dimension.id()))
{
//Im registering pocket dims here. I *think* we can assume that if its a pocket and we are
//registering its dim data, we also need to register it with forge.
@@ -552,42 +573,32 @@ public class PocketManager
//Steven
DimensionManager.registerDimension(dimensionID, mod_pocketDim.properties.PocketProviderID);
}
return dimension;
return dimension;
}
public static NewDimData getDimensionData(World world)
{
return getDimensionData(world.provider.dimensionId);
}
public static NewDimData getDimensionData(int dimensionID)
{
return PocketManager.dimensionData.get(dimensionID);
}
//Retrieve the data for a dimension. If we don't have a record for that dimension,
//assume it's a non-pocket dimension that hasn't been initialized with us before
//and create a NewDimData instance for it.
//Any pocket dimension must be listed with PocketManager to have a dimension ID
//assigned, so it's safe to assume that any unknown dimensions don't belong to us.
public static NewDimData getDimensionData(World dimension)
{
return PocketManager.dimensionData.get(dimension.provider.dimensionId);
}
public static NewDimData createDimensionData(World world)
{
return createDimensionData(world.provider.dimensionId);
}
public static NewDimData createDimensionDataDangerously(int dimensionID)
{
// Same as createDimensionData(int), but public. Meant to discourage anyone from
// using it unless absolutely needed! We'll probably phase this out eventually.
return createDimensionData(dimensionID);
}
protected static NewDimData createDimensionData(int dimensionID)
{
// Retrieve the data for a dimension. If we don't have a record for that dimension,
// assume it's a non-pocket dimension that hasn't been initialized with us before
// and create a NewDimData instance for it.
//FIXME: What's the point of this condition? Most calls to this function will crash anyway! ~SenseiKiwi
if(PocketManager.dimensionData == null)
{
System.out.println("Something odd happend during shutdown");
return null;
}
NewDimData dimension = PocketManager.dimensionData.get(dimensionID);
// if we do not have a record of it, then it must be a root
if (dimension == null)
{
dimension = registerDimension(dimensionID, null, DimensionType.ROOT);
dimension = registerDimension(dimensionID, null, false, false);
}
return dimension;
}
@@ -613,7 +624,6 @@ public class PocketManager
unregisterPockets();
dimensionData = null;
personalPocketsMapping = null;
rootDimensions = null;
isLoaded = false;
isConnected = false;
@@ -636,7 +646,10 @@ public class PocketManager
{
return dimension.getLink(x, y, z);
}
return null;
else
{
return null;
}
}
public static boolean isBlackListed(int dimensionID)
@@ -702,6 +715,9 @@ public class PocketManager
load();
Compactor.readDimensions(input, new DimRegistrationCallback());
// Register pocket dimensions
DDProperties properties = DDProperties.instance();
isLoaded = true;
isLoading = false;
isConnected = true;
@@ -711,29 +727,4 @@ public class PocketManager
{
return dimWatcher;
}
public static UpdateWatcherProxy<ClientLinkData> getLinkWatcher()
{
return linkWatcher;
}
public static NewDimData getPersonalDimensionForPlayer(String name)
{
if(personalPocketsMapping.containsKey(name))
{
return personalPocketsMapping.get(name);
}
return null;
}
public static void setPersonalPocketsMapping(HashMap<String, NewDimData> ppMap)
{
personalPocketsMapping = ppMap;
}
public static HashMap<String, NewDimData> getPersonalPocketMapping()
{
// TODO Auto-generated method stub
return personalPocketsMapping;
}
}

View File

@@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.TreeMap;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
@@ -19,7 +20,7 @@ import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
@@ -161,7 +162,7 @@ public class DungeonSchematic extends Schematic {
applyFilter(standardizer);
}
private static Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties)
private Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties)
{
//If we ever need this broadly or support other mods, this should be moved to a separate class
TreeMap<Short, Short> mapping = new TreeMap<Short, Short>();
@@ -246,7 +247,7 @@ public class DungeonSchematic extends Schematic {
world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag));
}
setUpDungeon(PocketManager.createDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter);
setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter);
}
private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter)
@@ -321,10 +322,10 @@ public class DungeonSchematic extends Schematic {
private static void createEntranceReverseLink(World world, NewDimData dimension, Point3D pocketCenter, DimLink entryLink)
{
int orientation = world.getBlockMetadata(pocketCenter.getX(), pocketCenter.getY() - 1, pocketCenter.getZ());
DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkType.REVERSE, orientation);
DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkTypes.REVERSE, orientation);
Point4D destination = entryLink.source();
NewDimData prevDim = PocketManager.getDimensionData(destination.getDimension());
prevDim.setLinkDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
prevDim.setDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
initDoorTileEntity(world, pocketCenter);
}
@@ -334,7 +335,7 @@ public class DungeonSchematic extends Schematic {
Point3D location = point.clone();
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON_EXIT, orientation);
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON_EXIT, orientation);
//Replace the sandstone block under the exit door with the same block as the one underneath it
int x = location.getX();
int y = location.getY() - 3;
@@ -355,7 +356,7 @@ public class DungeonSchematic extends Schematic {
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON, orientation);
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON, orientation);
initDoorTileEntity(world, location);
}

View File

@@ -298,9 +298,4 @@ public class DungeonPack
WeightedContainer<DungeonData> resultContainer = (WeightedContainer<DungeonData>) WeightedRandom.getRandomItem(random, weights);
return (resultContainer != null) ? resultContainer.getData() : null;
}
@Override
public String toString()
{
return this.name;
}
}

View File

@@ -45,9 +45,4 @@ public class DungeonType implements Comparable<DungeonType>
final int prime = 2039;
return prime * ID;
}
@Override
public String toString()
{
return this.Name+" owned by "+this.Owner;
}
}

View File

@@ -1,91 +1,47 @@
package StevenDimDoors.mod_pocketDim.helpers;
import StevenDimDoors.mod_pocketDim.IChunkLoader;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import java.io.File;
import java.util.List;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.ForgeChunkManager.LoadingCallback;
import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.ForgeChunkManager.Type;
import StevenDimDoors.experimental.BoundingBox;
import StevenDimDoors.mod_pocketDim.IChunkLoader;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
public class ChunkLoaderHelper implements LoadingCallback
{
@Override
public void ticketsLoaded(List<Ticket> tickets, World world)
{
for (Ticket ticket : tickets)
{
boolean loaded = false;
int x = ticket.getModData().getInteger("goldDimDoorX");
int y = ticket.getModData().getInteger("goldDimDoorY");
int z = ticket.getModData().getInteger("goldDimDoorZ");
if (world.getBlockId(x, y, z) == mod_pocketDim.properties.GoldenDimensionalDoorID)
{
IChunkLoader loader = (IChunkLoader) world.getBlockTileEntity(x, y, z);
if (!loader.isInitialized())
{
loader.initialize(ticket);
loaded = true;
}
}
if (!loaded)
int goldDimDoorX = ticket.getModData().getInteger("goldDimDoorX");
int goldDimDoorY = ticket.getModData().getInteger("goldDimDoorY");
int goldDimDoorZ = ticket.getModData().getInteger("goldDimDoorZ");
if(world.getBlockId(goldDimDoorX, goldDimDoorY, goldDimDoorZ) != mod_pocketDim.properties.GoldenDimensionalDoorID)
{
ForgeChunkManager.releaseTicket(ticket);
}
}
}
public static Ticket createTicket(int x, int y, int z, World world)
{
NBTTagCompound data;
Ticket ticket = ForgeChunkManager.requestTicket(mod_pocketDim.instance, world, Type.NORMAL);
if (ticket != null)
{
data = ticket.getModData();
data.setInteger("goldDimDoorX", x);
data.setInteger("goldDimDoorY", y);
data.setInteger("goldDimDoorZ", z);
}
return ticket;
}
public static void forcePocketChunks(NewDimData pocket, Ticket ticket)
{
BoundingBox bounds = PocketBuilder.calculateDefaultBounds(pocket);
Point3D minCorner = bounds.minCorner();
Point3D maxCorner = bounds.maxCorner();
int minX = minCorner.getX() >> 4;
int minZ = minCorner.getZ() >> 4;
int maxX = maxCorner.getX() >> 4;
int maxZ = maxCorner.getZ() >> 4;
int chunkX;
int chunkZ;
for (chunkX = minX; chunkX <= maxX; chunkX++)
{
for (chunkZ = minZ; chunkZ <= maxZ; chunkZ++)
else
{
ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(chunkX, chunkZ));
IChunkLoader tile = (IChunkLoader) world.getBlockTileEntity(goldDimDoorX, goldDimDoorY, goldDimDoorZ);
tile.forceChunkLoading(ticket,goldDimDoorX,goldDimDoorZ);
}
}
}
public static void loadForcedChunkWorlds(FMLServerStartingEvent event)
public static void loadChunkForcedWorlds(FMLServerStartingEvent event)
{
for (NewDimData data : PocketManager.getDimensions())
for(NewDimData data : PocketManager.getDimensions())
{
if(data.isPocketDimension())
{

View File

@@ -6,10 +6,10 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.IDimRegistrationCallback;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
@@ -68,20 +68,19 @@ public class Compactor
{
int id = input.readInt();
int rootID = input.readInt();
DimensionType type = DimensionType.getTypeFromIndex(input.readInt());
if (rootIDs.add(rootID))
{
callback.registerDimension(rootID, rootID, type);
callback.registerDimension(rootID, rootID);
}
// Don't check if (id != rootID) - we want to retrieve the reference anyway
NewDimData dimension = callback.registerDimension(id, rootID, type);
NewDimData dimension = callback.registerDimension(id, rootID);
int linkCount = input.readInt();
for (int h = 0; h < linkCount; h++)
{
ClientLinkData link = ClientLinkData.read(input);
Point4D source = link.point;
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.CLIENT,0);
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE,link.orientation);
}
}
}

View File

@@ -2,33 +2,31 @@ package StevenDimDoors.mod_pocketDim.helpers;
import java.io.File;
public class DeleteFolder
{
public static boolean deleteFolder(File directory)
public static boolean deleteFolder(File file)
{
try
{
File[] contents = directory.listFiles();
if (contents != null)
File[] files = file.listFiles();
if(files==null)
{
for (File entry : contents)
{
if (entry.isDirectory())
{
deleteFolder(entry);
}
else
{
entry.delete();
}
}
file.delete();
return true;
}
return directory.delete();
for(File inFile : files)
{
DeleteFolder.deleteFolder(inFile);
}
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
}

View File

@@ -16,12 +16,13 @@ import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.regex.Pattern;
import net.minecraft.util.WeightedRandom;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
@@ -45,7 +46,7 @@ public class DungeonHelper
public static final String SCHEMATIC_FILE_EXTENSION = ".schematic";
private static final String DEFAULT_ERROR_SCHEMATIC_PATH = "/schematics/core/somethingBroke.schematic";
private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/assets/dimdoors/text/How_to_add_dungeons.txt";
private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/mods/DimDoors/text/How_to_add_dungeons.txt";
private static final String BUNDLED_PACK_BASE_PATH = "/schematics/";
private static final String STANDARD_CONFIG_FILE_NAME = "rules.txt";
@@ -263,7 +264,7 @@ public class DungeonHelper
{
//Create a link above the specified position. Link to a new pocket dimension.
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.createLink(x, y + 1, z, LinkType.POCKET, 3);
DimLink link = dimension.createLink(x, y + 1, z, LinkTypes.POCKET, 3);
//Place a Warp Door linked to that pocket
ItemDimensionalDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.warpDoor);

View File

@@ -1,6 +0,0 @@
package StevenDimDoors.mod_pocketDim.helpers;
public class PersonalPocketHelper
{
}

View File

@@ -215,7 +215,10 @@ public class yCoordHelper
{
for (int dz = -1; dz <= 1; dz++)
{
provider.loadChunk(chunkX, chunkZ);
if (!provider.chunkExists(chunkX + dx, chunkZ + dz))
{
provider.loadChunk(chunkX, chunkZ);
}
}
}
return target;

View File

@@ -2,7 +2,6 @@ package StevenDimDoors.mod_pocketDim.items;
import java.util.HashMap;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
@@ -24,9 +23,9 @@ import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
public abstract class BaseItemDoor extends ItemDoor
{
// Maps non-dimensional door items to their corresponding dimensional door item
// Also maps dimensional door items to themselves for simplicity
private static HashMap<ItemDoor, BaseItemDoor> doorItemMapping = new HashMap<ItemDoor, BaseItemDoor>();
// maps non-dimensional door items to their corresponding dimensional door
// item
private static HashMap<ItemDoor, BaseItemDoor> vanillaDoorMapping = new HashMap<ItemDoor, BaseItemDoor>();
private static DDProperties properties = null;
/**
@@ -35,7 +34,7 @@ public abstract class BaseItemDoor extends ItemDoor
* @param material
* @param door
*/
public BaseItemDoor(int itemID, Material material, ItemDoor vanillaDoor)
public BaseItemDoor(int itemID, Material material, ItemDoor door)
{
super(itemID, material);
this.setMaxStackSize(64);
@@ -43,10 +42,9 @@ public abstract class BaseItemDoor extends ItemDoor
if (properties == null)
properties = DDProperties.instance();
doorItemMapping.put(this, this);
if (vanillaDoor != null)
if(door!=null)
{
doorItemMapping.put(vanillaDoor, this);
vanillaDoorMapping.put(door, this);
}
}
@@ -66,7 +64,7 @@ public abstract class BaseItemDoor extends ItemDoor
*
* @return
*/
protected abstract BaseDimDoor getDoorBlock();
protected abstract BaseDimDoor getDoortoItemMapping();
/**
* Overriden here to remove vanilla block placement functionality from
@@ -75,12 +73,23 @@ public abstract class BaseItemDoor extends ItemDoor
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
{
// TODO Auto-generated method stub
return false;
}
public static BaseDimDoor getDoorToPlace(Item item)
{
if (!(item instanceof BaseItemDoor))
{
item = BaseItemDoor.vanillaDoorMapping.get(item);
}
return ((BaseItemDoor) item).getDoortoItemMapping();
}
/**
* Tries to place a door as a dimensional door
* Tries to place a door block, called in EventHookContainer
*
* @param doorBlock
* @param stack
* @param player
* @param world
@@ -88,6 +97,8 @@ public abstract class BaseItemDoor extends ItemDoor
* @param y
* @param z
* @param side
* @param requireLink
* @param reduceStack
* @return
*/
public static boolean tryToPlaceDoor(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side)
@@ -96,20 +107,15 @@ public abstract class BaseItemDoor extends ItemDoor
{
return false;
}
// Retrieve the actual door type that we want to use here.
// It's okay if stack isn't an ItemDoor. In that case, the lookup will
// return null, just as if the item was an unrecognized door type.
BaseItemDoor mappedItem = doorItemMapping.get(stack.getItem());
if (mappedItem == null)
if (!(stack.getItem() instanceof ItemDoor))
{
return false;
throw new IllegalArgumentException("The itemstack must correspond to some type of door");
}
BaseDimDoor doorBlock = mappedItem.getDoorBlock();
if (BaseItemDoor.placeDoorOnBlock(doorBlock, stack, player, world, x, y, z, side))
if (BaseItemDoor.placeDoorOnBlock(getDoorToPlace(stack.getItem()), stack, player, world, x, y, z, side))
{
return true;
}
return BaseItemDoor.placeDoorOnRift(doorBlock, world, player, stack);
return BaseItemDoor.placeDoorOnRift(getDoorToPlace(stack.getItem()), world, player, stack);
}
/**

View File

@@ -7,7 +7,7 @@ import StevenDimDoors.mod_pocketDim.mod_pocketDim;
public class ItemBlockDimWall extends ItemBlock
{
private final static String[] subNames = {"Fabric of Reality", "Ancient Fabric" , "Altered Fabric"};
private final static String[] subNames = {"Fabric of Reality", "Ancient Fabric"};
public ItemBlockDimWall(int par1)
{

View File

@@ -1,213 +0,0 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
public class ItemDDKey extends Item
{
public static final int TIME_TO_UNLOCK = 30;
public ItemDDKey(int itemID)
{
super(itemID);
this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab);
this.setMaxStackSize(1);
}
public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
}
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
if (DDLock.hasCreatedLock(par1ItemStack))
{
par3List.add("Bound");
}
else
{
par3List.add("Unbound");
}
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
}
@Override
@SideOnly(Side.CLIENT)
public boolean hasEffect(ItemStack par1ItemStack)
{
return !DDLock.hasCreatedLock(par1ItemStack);
}
public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World par3World, int par4, int par5, int par6, int par7, float par8, float par9,
float par10)
{
player.setItemInUse(itemStack, this.getMaxItemUseDuration(itemStack));
return false;
}
public boolean onItemUseFirst(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float playerX, float playerY,
float playerZ)
{
if (world.isRemote)
{
return false;
}
if (player.getItemInUse() != null)
{
return true;
}
int blockID = world.getBlockId(x, y, z);
// make sure we are dealing with a door
if (!(Block.blocksList[blockID] instanceof IDimDoor))
{
return false;
}
DimLink link = PocketManager.getLink(x, y, z, world);
// dont do anything to doors without links
if (link == null)
{
return false;
}
// what to do if the door has a lock already
if (link.hasLock())
{
if (link.doesKeyUnlock(itemStack))
{
if (link.getLockState())
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyUnlock", 1F, 1F);
}
else
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F);
}
PocketManager.getDimensionData(world).lock(link, !link.getLockState());
PocketManager.getLinkWatcher().update(new ClientLinkData(link));
}
else
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":doorLocked", 1F, 1F);
}
}
else
{
if (!DDLock.hasCreatedLock(itemStack))
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F);
PocketManager.getDimensionData(world).createLock(link, itemStack, world.rand.nextInt(Integer.MAX_VALUE));
PocketManager.getLinkWatcher().update(new ClientLinkData(link));
}
}
return false;
}
/**
* Handle removal of locks here
*/
@Override
public void onPlayerStoppedUsing(ItemStack itemStack, World world, EntityPlayer player, int heldTime)
{
int j = this.getMaxItemUseDuration(itemStack) - heldTime;
if (j >= TIME_TO_UNLOCK)
{
//Raytrace to make sure we are still looking at a door
MovingObjectPosition pos = getMovingObjectPositionFromPlayer(player.worldObj, player, true);
if (pos != null && pos.typeOfHit == EnumMovingObjectType.TILE)
{
//make sure we have a link and it has a lock
DimLink link = PocketManager.getLink(pos.blockX, pos.blockY, pos.blockZ, player.worldObj);
if (link != null && link.hasLock())
{
//make sure the given key is able to access the lock
if (link.doesKeyUnlock(itemStack) && !world.isRemote)
{
PocketManager.getDimensionData(world).removeLock(link, itemStack);
world.playSoundAtEntity(player, mod_pocketDim.modid + ":doorLockRemoved", 1F, 1F);
}
}
}
}
player.clearItemInUse();
}
/**
* Raytrace to make sure we are still looking at the right block while preparing to remove the lock
*/
@Override
public void onUsingItemTick(ItemStack stack, EntityPlayer player, int count)
{
// no need to check every tick, twice a second instead
if (count % 10 == 0)
{
MovingObjectPosition pos = getMovingObjectPositionFromPlayer(player.worldObj, player, true);
if (pos != null && pos.typeOfHit == EnumMovingObjectType.TILE)
{
DimLink link = PocketManager.getLink(pos.blockX, pos.blockY, pos.blockZ, player.worldObj);
if (link != null && link.hasLock())
{
if (link.doesKeyUnlock(stack))
{
return;
}
}
}
player.clearItemInUse();
}
}
public EnumAction getItemUseAction(ItemStack par1ItemStack)
{
return EnumAction.bow;
}
public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
return par1ItemStack;
}
public int getMaxItemUseDuration(ItemStack par1ItemStack)
{
return 72000;
}
public String getItemStackDisplayName(ItemStack par1ItemStack)
{
return StatCollector.translateToLocal(this.getUnlocalizedName(par1ItemStack));
}
}

View File

@@ -28,7 +28,7 @@ public class ItemDimensionalDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoorBlock()
protected BaseDimDoor getDoortoItemMapping()
{
return (BaseDimDoor) mod_pocketDim.dimensionalDoor;
}

View File

@@ -28,7 +28,7 @@ public class ItemGoldDimDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoorBlock()
protected BaseDimDoor getDoortoItemMapping()
{
return (BaseDimDoor) mod_pocketDim.goldenDimensionalDoor;
}

View File

@@ -15,7 +15,6 @@ public class ItemGoldDoor extends ItemDoor
public ItemGoldDoor(int par1, Material par2Material)
{
super(par1, par2Material);
this.setMaxStackSize(16);
}
@Override

View File

@@ -1,35 +0,0 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.List;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
public class ItemPersonalDoor extends BaseItemDoor
{
public ItemPersonalDoor(int itemID, Material material, ItemDoor door)
{
super(itemID, material, door);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
par3List.add("Creates a pathway to");
par3List.add("Your personal pocket");
}
@Override
protected BaseDimDoor getDoorBlock()
{
return (BaseDimDoor) mod_pocketDim.personalDimDoor;
}
}

View File

@@ -1,58 +0,0 @@
package StevenDimDoors.mod_pocketDim.items;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class ItemQuartzDoor extends ItemDoor
{
public ItemQuartzDoor(int par1, Material par2Material)
{
super(par1, par2Material);
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
}
@Override
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{
if (par7 != 1)
{
return false;
}
else
{
++par5;
Block block = mod_pocketDim.quartzDoor;
if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack))
{
if (!block.canPlaceBlockAt(par3World, par4, par5, par6))
{
return false;
}
else
{
int i1 = MathHelper.floor_double((par2EntityPlayer.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
placeDoorBlock(par3World, par4, par5, par6, i1, block);
--par1ItemStack.stackSize;
return true;
}
}
else
{
return false;
}
}
}
}

View File

@@ -1,6 +1,7 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
@@ -13,7 +14,7 @@ import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
@@ -33,13 +34,12 @@ public class ItemRiftSignature extends Item
@SideOnly(Side.CLIENT)
@Override
public boolean hasEffect(ItemStack stack, int pass)
public boolean hasEffect(ItemStack stack)
{
//Make the item glow if it has one endpoint stored
return (stack.getItemDamage() != 0);
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
@@ -60,47 +60,50 @@ public class ItemRiftSignature extends Item
return false;
}
//Increase y by 2 to place the rift at head level
int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
if (!player.canPlayerEdit(x, adjustedY, z, side, stack))
y += 2; //Increase y by 2 to place the rift at head level
if (!player.canPlayerEdit(x, y, z, side, stack))
{
return true;
}
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
Point4DOrientation source = getSource(stack);
int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
int orientation = MathHelper.floor_double((double) ((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
if (source != null)
{
// The link was used before and already has an endpoint stored.
// Create links connecting the two endpoints.
//The link was used before and already has an endpoint stored. Create links connecting the two endpoints.
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.getDimensionData(world);
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation());
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkTypes.NORMAL,orientation);
destinationDimension.setDestination(link, x, adjustedY, z);
sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ());
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL,source.getOrientation());
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkType.NORMAL,orientation);
//Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z))
{
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
}
destinationDimension.setLinkDestination(link, x, adjustedY, z);
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Try placing a rift at the destination point
mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
// Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
//Try placing a rift at the source point, but check if its world is loaded first
World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
if (sourceWorld != null &&
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
if (!player.capabilities.isCreativeMode)
{
stack.stackSize--;
}
clearSource(stack);
mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1);
mod_pocketDim.sendChat(player,("Rift Created"));
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftEnd", 0.6f, 1);
}
else
{
//The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world));
setSource(stack, x, adjustedY, z,orientation, PocketManager.getDimensionData(world));
mod_pocketDim.sendChat(player,("Location Stored in Rift Signature"));
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftStart", 0.6f, 1);
}
@@ -110,7 +113,6 @@ public class ItemRiftSignature extends Item
/**
* allows items to add custom lines of information to the mouseover description
*/
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
@@ -138,28 +140,26 @@ public class ItemRiftSignature extends Item
*/
public static int adjustYForSpecialBlocks(World world, int x, int y, int z)
{
int targetY = y - 2; // Get the block the player actually clicked on
Block block = Block.blocksList[world.getBlockId(x, targetY, z)];
if (block == null)
y=y-2;//get the block the player actually clicked on
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if(block==null)
{
return targetY + 2;
return y+2;
}
if (block.isBlockReplaceable(world, x, targetY, z))
if(block.isBlockReplaceable(world, x, y, z))
{
return targetY + 1; // Move block placement down (-2+1) one so its directly over things like snow
return y+1;//move block placement down (-2+1) one so its directly over things like snow
}
if (block instanceof BaseDimDoor)
if(block instanceof BaseDimDoor)
{
if (((BaseDimDoor) block).isUpperDoorBlock(world.getBlockMetadata(x, targetY, z)))
if(world.getBlockId(x, y-1, z)==block.blockID&&world.getBlockMetadata(x, y, z)==8)
{
return targetY; // Move rift placement down two so its in the right place on the door.
return y;//move rift placement down two so its in the right place on the door.
}
// Move rift placement down one so its in the right place on the door.
return targetY + 1;
return y+1;
}
return targetY + 2;
return y+2;
}
public static void setSource(ItemStack itemStack, int x, int y, int z, int orientation, NewDimData dimension)
{
NBTTagCompound tag = new NBTTagCompound();
@@ -200,12 +200,11 @@ public class ItemRiftSignature extends Item
Integer orientation = tag.getInteger("orientation");
Integer dimID = tag.getInteger("linkDimID");
if (x != null && y != null && z != null && orientation != null && dimID != null)
if (x != null && y != null && z != null && dimID != null)
{
return new Point4DOrientation(x, y, z, orientation, dimID);
return new Point4DOrientation(x, y, z,orientation, dimID);
}
}
// Mark the item as uninitialized if its source couldn't be read
itemStack.setItemDamage(0);
}
return null;
@@ -215,11 +214,10 @@ public class ItemRiftSignature extends Item
{
private Point4D point;
private int orientation;
Point4DOrientation(int x, int y, int z, int orientation, int dimID)
{
this.point = new Point4D(x, y, z, dimID);
this.orientation = orientation;
this.point= new Point4D(x,y,z,dimID);
this.orientation=orientation;
}
int getX()
@@ -241,16 +239,10 @@ public class ItemRiftSignature extends Item
{
return point.getDimension();
}
int getOrientation()
{
return orientation;
}
Point4D getPoint()
{
return point;
}
}
}

View File

@@ -1,6 +1,7 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.List;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
@@ -10,9 +11,10 @@ import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -38,124 +40,69 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
return false;
}
// Adjust Y so the rift is at head level, depending on the presence of certain blocks
int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
if (!player.canPlayerEdit(x, adjustedY, z, side, stack))
// We don't check for replaceable blocks. The user can deal with that. <_<
y += 2; //Increase y by 2 to place the rift at head level
if (!player.canPlayerEdit(x, y, z, side, stack))
{
return true;
}
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
Point4DOrientation source = getSource(stack);
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
// Check if the Stabilized Rift Signature has been initialized
Point4DOrientation source = getSource(stack);
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
if (source != null)
{
// Yes, it's initialized. Check if the player is in creative
// or if the player can pay with Stable Fabric to create a rift.
if (!player.capabilities.isCreativeMode && !player.inventory.hasItem(mod_pocketDim.itemStableFabric.itemID))
{
mod_pocketDim.sendChat(player, "You don't have any Stable Fabric!");
// I won't do this, but this is the chance to localize chat
// messages sent to the player; look at ChatMessageComponent
// and how MFR does it with items like the safari net launcher
return true;
}
// Yes, it's initialized.
//The link was used before and already has an endpoint stored. Create links connecting the two endpoints.
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.createDimensionData(world);
DimLink reverse = destinationDimension.getLink(x, adjustedY, z);
DimLink link;
NewDimData destinationDimension = PocketManager.getDimensionData(world);
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation());
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkTypes.NORMAL,orientation);
destinationDimension.setDestination(link, x, adjustedY, z);
sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ());
// Check whether the SRS is being used to restore one of its previous
// link pairs. In other words, the SRS is being used on a location
// that already has a link pointing to the SRS's source, with the
// intention of overwriting the source-side link to point there.
// Those benign redirection operations will be handled for free.
if (reverse != null && source.getPoint().equals(reverse.destination()))
//Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z))
{
// Only the source-to-destination link is needed.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
destinationDimension.setLinkDestination(link, x, adjustedY, z);
}
else
{
// Check if the player is in creative mode,
// or if the player can pay with an Ender Pearl to create a rift.
if (!player.capabilities.isCreativeMode &&
!player.inventory.consumeInventoryItem(Item.enderPearl.itemID))
{
mod_pocketDim.sendChat(player, "You don't have any Ender Pearls!");
// I won't do this, but this is the chance to localize chat
// messages sent to the player; look at ChatMessageComponent
// and how MFR does it with items like the safari net launcher
return true;
}
// Create links connecting the two endpoints.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
reverse = destinationDimension.createLink(x, adjustedY, z, LinkType.NORMAL, orientation);
destinationDimension.setLinkDestination(link, x, adjustedY, z);
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Try placing a rift at the destination point
mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
}
// Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
//Try placing a rift at the source point, but check if its world is loaded first
World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null &&
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);
if (!player.capabilities.isCreativeMode)
{
player.inventory.consumeInventoryItem(mod_pocketDim.itemStableFabric.itemID);
}
mod_pocketDim.sendChat(player,"Rift Created");
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftEnd", 0.6f, 1);
}
else
{
// The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world));
mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature");
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1);
//The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world));
mod_pocketDim.sendChat(player,"Location Stored in Stabilized Rift Signature");
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftStart", 0.6f, 1);
}
return true;
}
public static boolean useFromDispenser(ItemStack stack, World world, int x, int y, int z)
{
// Stabilized Rift Signatures can only be used from dispensers to restore
// a previous link pair. The operation would be free for a player, so
// dispensers can also perform it for free. Otherwise, the item does nothing.
if (world.isRemote)
{
return false;
}
// Adjust Y so the rift is at head level, depending on the presence of certain blocks
int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
Point4DOrientation source = getSource(stack);
// The SRS must have been initialized
if (source != null)
{
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.createDimensionData(world);
DimLink reverse = destinationDimension.getLink(x, adjustedY, z);
DimLink link;
// Check whether the SRS is being used to restore one of its previous
// link pairs. In other words, the SRS is being used on a location
// that already has a link pointing to the SRS's source, with the
// intention of overwriting the source-side link to point there.
if (reverse != null && source.getPoint().equals(reverse.destination()))
{
// Only the source-to-destination link is needed.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
destinationDimension.setLinkDestination(link, x, adjustedY, z);
// Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
// This call doesn't seem to be working...
world.playSoundEffect(x + 0.5, adjustedY + 0.5, z + 0.5, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);
return true;
}
}
return false;
}
/**
* allows items to add custom lines of information to the mouseover description
*/

View File

@@ -25,7 +25,7 @@ public class ItemUnstableDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoorBlock()
protected BaseDimDoor getDoortoItemMapping()
{
return (BaseDimDoor) mod_pocketDim.unstableDoor;
}

View File

@@ -28,7 +28,7 @@ public class ItemWarpDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoorBlock()
protected BaseDimDoor getDoortoItemMapping()
{
return (BaseDimDoor) mod_pocketDim.warpDoor;
}

View File

@@ -1,42 +0,0 @@
package StevenDimDoors.mod_pocketDim.items.behaviors;
import net.minecraft.block.BlockDispenser;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.items.ItemStabilizedRiftSignature;
public class DispenserBehaviorStabilizedRS extends BehaviorDefaultDispenseItem
{
@Override
public ItemStack dispenseStack(IBlockSource dispenser, ItemStack stack)
{
// Search for a non-air block up to 3 blocks in front of a dispenser.
// If it's found, call ItemStabilizedRiftSignature.useFromDispenser().
int x = dispenser.getXInt();
int y = dispenser.getYInt();
int z = dispenser.getZInt();
EnumFacing facing = BlockDispenser.getFacing(dispenser.getBlockMetadata());
int dx = facing.getFrontOffsetX();
int dy = facing.getFrontOffsetY();
int dz = facing.getFrontOffsetZ();
World world = dispenser.getWorld();
for (int k = 1; k <= 3; k++)
{
x += dx;
y += dy;
z += dz;
if (!world.isAirBlock(x, y, z))
{
// Found a block. Activate the item.
ItemStabilizedRiftSignature.useFromDispenser(stack, world, x, y, z);
break;
}
}
// The item stack isn't modified
return stack;
}
}

View File

@@ -54,7 +54,7 @@ public class itemRiftRemover extends Item
int hx = hit.blockX;
int hy = hit.blockY;
int hz = hit.blockZ;
NewDimData dimension = PocketManager.createDimensionData(world);
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(hx, hy, hz);
if (world.getBlockId(hx, hy, hz) == mod_pocketDim.blockRift.blockID && link != null &&
player.canPlayerEdit(hx, hy, hz, hit.sideHit, stack))
@@ -85,7 +85,7 @@ public class itemRiftRemover extends Item
y = hit.blockY;
z = hit.blockZ;
NewDimData dimension = PocketManager.createDimensionData(world);
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID && link != null &&
player.canPlayerEdit(x, y, z, side, stack))

View File

@@ -1,6 +1,7 @@
package StevenDimDoors.mod_pocketDim;
import java.io.File;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
@@ -18,12 +19,10 @@ import net.minecraftforge.common.MinecraftForge;
import StevenDimDoors.mod_pocketDim.blocks.BlockDimWall;
import StevenDimDoors.mod_pocketDim.blocks.BlockDimWallPerm;
import StevenDimDoors.mod_pocketDim.blocks.BlockDoorGold;
import StevenDimDoors.mod_pocketDim.blocks.BlockDoorQuartz;
import StevenDimDoors.mod_pocketDim.blocks.BlockGoldDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.BlockLimbo;
import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.blocks.DimensionalDoor;
import StevenDimDoors.mod_pocketDim.blocks.PersonalDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.TransTrapdoor;
import StevenDimDoors.mod_pocketDim.blocks.TransientDoor;
import StevenDimDoors.mod_pocketDim.blocks.UnstableDoor;
@@ -31,6 +30,7 @@ import StevenDimDoors.mod_pocketDim.blocks.WarpDoor;
import StevenDimDoors.mod_pocketDim.commands.CommandCreateDungeonRift;
import StevenDimDoors.mod_pocketDim.commands.CommandCreatePocket;
import StevenDimDoors.mod_pocketDim.commands.CommandCreateRandomRift;
import StevenDimDoors.mod_pocketDim.commands.CommandDeleteAllLinks;
import StevenDimDoors.mod_pocketDim.commands.CommandDeleteRifts;
import StevenDimDoors.mod_pocketDim.commands.CommandExportDungeon;
import StevenDimDoors.mod_pocketDim.commands.CommandListDungeons;
@@ -42,12 +42,9 @@ import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.helpers.ChunkLoaderHelper;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.items.ItemBlockDimWall;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
import StevenDimDoors.mod_pocketDim.items.ItemGoldDimDoor;
import StevenDimDoors.mod_pocketDim.items.ItemGoldDoor;
import StevenDimDoors.mod_pocketDim.items.ItemPersonalDoor;
import StevenDimDoors.mod_pocketDim.items.ItemQuartzDoor;
import StevenDimDoors.mod_pocketDim.items.ItemRiftBlade;
import StevenDimDoors.mod_pocketDim.items.ItemRiftSignature;
import StevenDimDoors.mod_pocketDim.items.ItemStabilizedRiftSignature;
@@ -56,24 +53,25 @@ import StevenDimDoors.mod_pocketDim.items.ItemUnstableDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWorldThread;
import StevenDimDoors.mod_pocketDim.items.itemRiftRemover;
import StevenDimDoors.mod_pocketDim.ticking.CommonTickHandler;
import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler;
import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecay;
import StevenDimDoors.mod_pocketDim.ticking.MobMonolith;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
import StevenDimDoors.mod_pocketDim.ticking.ServerTickHandler;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor;
import StevenDimDoors.mod_pocketDim.util.DDLogger;
import StevenDimDoors.mod_pocketDim.world.BiomeGenLimbo;
import StevenDimDoors.mod_pocketDim.world.BiomeGenPocket;
import StevenDimDoors.mod_pocketDim.world.DDBiomeGenBase;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PersonalPocketProvider;
import StevenDimDoors.mod_pocketDim.world.PocketProvider;
import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator;
import StevenDimDoors.mod_pocketDimClient.ClientPacketHandler;
import StevenDimDoors.mod_pocketDimClient.ClientTickHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
@@ -101,21 +99,16 @@ serverPacketHandlerSpec =
@SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class))
public class mod_pocketDim
{
public static final String version = "@VERSION@";
public static final String version = "1.6.4-R2.2.3";
public static final String modid = "dimdoors";
//TODO need a place to stick all these constants
public static final int NETHER_DIMENSION_ID = -1;
//need to clean up
@SidedProxy(clientSide = "StevenDimDoors.mod_pocketDimClient.ClientProxy", serverSide = "StevenDimDoors.mod_pocketDim.CommonProxy")
public static CommonProxy proxy;
@Instance(mod_pocketDim.modid)
public static mod_pocketDim instance;
@Instance("PocketDimensions")
public static mod_pocketDim instance = new mod_pocketDim();
public static Block quartzDoor;
public static Block personalDimDoor;
public static Block transientDoor;
public static Block warpDoor;
public static Block goldenDoor;
@@ -139,10 +132,7 @@ public class mod_pocketDim
public static Item itemRiftSignature;
public static Item itemStableFabric;
public static Item itemUnstableDoor;
public static Item itemDDKey;
public static Item itemQuartzDoor;
public static Item itemPersonalDoor;
public static Item itemStabilizedRiftSignature;
public static Item itemStabilizedLinkSignature;
public static BiomeGenBase limboBiome;
public static BiomeGenBase pocketBiome;
@@ -152,13 +142,9 @@ public class mod_pocketDim
public static DDProperties properties;
public static DDWorldProperties worldProperties;
public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later.
public static RiftRegenerator riftRegenerator;
public static FastRiftRegenerator fastRiftRegenerator;
public static GatewayGenerator gatewayGenerator;
public static DeathTracker deathTracker;
private static ServerTickHandler serverTickHandler;
private static LimboDecayScheduler limboDecayScheduler;
private static LimboDecay limboDecay;
private static EventHookContainer hooks;
//TODO this is a temporary workaround for saving data
private String currrentSaveRootDirectory;
@@ -181,13 +167,14 @@ public class mod_pocketDim
@EventHandler
public void onPreInitialization(FMLPreInitializationEvent event)
{
instance = this;
//This should be the FIRST thing that gets done.
String path = event.getSuggestedConfigurationFile().getAbsolutePath().replace(modid, "DimDoors");
properties = DDProperties.initialize(new File(path));
//Now do other stuff
hooks = new EventHookContainer(properties);
EventHookContainer hooks = new EventHookContainer(properties);
MinecraftForge.EVENT_BUS.register(hooks);
MinecraftForge.TERRAIN_GEN_BUS.register(hooks);
}
@@ -195,34 +182,31 @@ public class mod_pocketDim
@EventHandler
public void onInitialization(FMLInitializationEvent event)
{
// Initialize ServerTickHandler instance
serverTickHandler = new ServerTickHandler();
TickRegistry.registerTickHandler(serverTickHandler, Side.SERVER);
CommonTickHandler commonTickHandler = new CommonTickHandler();
TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT);
TickRegistry.registerTickHandler(commonTickHandler, Side.SERVER);
// Initialize LimboDecay instance: required for BlockLimbo
limboDecay = new LimboDecay(properties);
//MonolithSpawner should be initialized before any provider instances are created
//Register the other regular tick receivers as well
spawner = new CustomLimboPopulator(commonTickHandler, properties);
new RiftRegenerator(commonTickHandler); //No need to store the reference
LimboDecay decay = new LimboDecay(commonTickHandler, properties);
fastRiftRegenerator = new FastRiftRegenerator(commonTickHandler);
// Initialize blocks and items
transientDoor = new TransientDoor(properties.TransientDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("transientDoor");
goldenDimensionalDoor = new BlockGoldDimDoor(properties.GoldenDimensionalDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorGold");
quartzDoor = new BlockDoorQuartz(properties.QuartzDoorID, Material.rock).setHardness(0.1F).setUnlocalizedName("doorQuartz");
personalDimDoor = new PersonalDimDoor(properties.PersonalDimDoorID, Material.rock,properties).setHardness(0.1F).setUnlocalizedName("dimDoorPersonal");
goldenDoor = new BlockDoorGold(properties.GoldenDoorID, Material.iron).setHardness(0.1F).setUnlocalizedName("doorGold");
blockDimWall = new BlockDimWall(properties.FabricBlockID, 0, Material.iron).setLightValue(1.0F).setHardness(0.1F).setUnlocalizedName("blockDimWall");
blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm");
warpDoor = new WarpDoor(properties.WarpDoorID, Material.wood, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp");
blockRift = (BlockRift) (new BlockRift(properties.RiftBlockID, 0, Material.air, properties).setHardness(1.0F) .setUnlocalizedName("rift"));
blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, limboDecay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F);
blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, decay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F);
unstableDoor = (new UnstableDoor(properties.UnstableDoorID, Material.iron, properties).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) );
dimensionalDoor = (DimensionalDoor) (new DimensionalDoor(properties.DimensionalDoorID, Material.iron, properties).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor"));
transTrapdoor = (TransTrapdoor) (new TransTrapdoor(properties.TransTrapdoorID, Material.wood).setHardness(1.0F) .setUnlocalizedName("dimHatch"));
itemDDKey = (new ItemDDKey(properties.DDKeyItemID)).setUnlocalizedName("itemDDKey");
itemQuartzDoor = (new ItemQuartzDoor(properties.QuartzDoorID, Material.rock)).setUnlocalizedName("itemQuartzDoor");
itemPersonalDoor = (new ItemPersonalDoor(properties.PersonalDimDoorID, Material.rock, (ItemDoor)this.itemQuartzDoor)).setUnlocalizedName("itemQuartzDimDoor");
itemGoldenDoor = (new ItemGoldDoor(properties.GoldenDoorItemID, Material.wood)).setUnlocalizedName("itemGoldDoor");
itemGoldenDoor = (new ItemGoldDoor(properties.GoldenDoorID, Material.wood)).setUnlocalizedName("itemGoldDoor");
itemGoldenDimensionalDoor = (new ItemGoldDimDoor(properties.GoldenDimensionalDoorItemID, Material.iron, (ItemDoor)this.itemGoldenDoor)).setUnlocalizedName("itemGoldDimDoor");
itemDimensionalDoor = (ItemDimensionalDoor) (new ItemDimensionalDoor(properties.DimensionalDoorItemID, Material.iron, (ItemDoor)Item.doorIron)).setUnlocalizedName("itemDimDoor");
itemWarpDoor = (new ItemWarpDoor(properties.WarpDoorItemID, Material.wood,(ItemDoor)Item.doorWood)).setUnlocalizedName("itemDimDoorWarp");
@@ -231,7 +215,7 @@ public class mod_pocketDim
itemStableFabric = (new ItemStableFabric(properties.StableFabricItemID, 0)).setUnlocalizedName("itemStableFabric");
itemUnstableDoor = (new ItemUnstableDoor(properties.UnstableDoorItemID, Material.iron, null)).setUnlocalizedName("itemChaosDoor");
itemRiftBlade = (new ItemRiftBlade(properties.RiftBladeItemID, properties)).setUnlocalizedName("ItemRiftBlade");
itemStabilizedRiftSignature = (new ItemStabilizedRiftSignature(properties.StabilizedRiftSignatureItemID)).setUnlocalizedName("itemStabilizedRiftSig");
itemStabilizedLinkSignature = (new ItemStabilizedRiftSignature(properties.StabilizedRiftSignatureItemID)).setUnlocalizedName("itemStabilizedRiftSig");
itemWorldThread = (new ItemWorldThread(properties.WorldThreadItemID)).setUnlocalizedName("itemWorldThread");
// Check if other biomes have been registered with the same IDs we want. If so, crash Minecraft
@@ -242,8 +226,6 @@ public class mod_pocketDim
mod_pocketDim.limboBiome = (new BiomeGenLimbo(properties.LimboBiomeID));
mod_pocketDim.pocketBiome = (new BiomeGenPocket(properties.PocketBiomeID));
GameRegistry.registerBlock(quartzDoor, "Quartz Door");
GameRegistry.registerBlock(personalDimDoor, "Personal Dimensional Door");
GameRegistry.registerBlock(goldenDoor, "Golden Door");
GameRegistry.registerBlock(goldenDimensionalDoor, "Golden Dimensional Door");
GameRegistry.registerBlock(unstableDoor, "Unstable Door");
@@ -261,8 +243,6 @@ public class mod_pocketDim
throw new IllegalStateException("There is a provider ID conflict between PocketProvider from Dimensional Doors and another provider type. Fix your configuration!");
if (!DimensionManager.registerProviderType(properties.LimboProviderID, LimboProvider.class, false))
throw new IllegalStateException("There is a provider ID conflict between LimboProvider from Dimensional Doors and another provider type. Fix your configuration!");
if (!DimensionManager.registerProviderType(properties.PersonalPocketProviderID, PersonalPocketProvider.class, false))
throw new IllegalStateException("There is a provider ID conflict between PersonalPocketProvider from Dimensional Doors and another provider type. Fix your configuration!");
DimensionManager.registerDimension(properties.LimboDimensionID, properties.LimboProviderID);
@@ -282,24 +262,19 @@ public class mod_pocketDim
LanguageRegistry.addName(itemRiftSignature, "Rift Signature");
LanguageRegistry.addName(itemGoldenDoor, "Golden Door");
LanguageRegistry.addName(itemGoldenDimensionalDoor, "Golden Dimensional Door");
LanguageRegistry.addName(itemStabilizedRiftSignature, "Stabilized Rift Signature");
LanguageRegistry.addName(itemStabilizedLinkSignature, "Stabilized Rift Signature");
LanguageRegistry.addName(itemRiftRemover, "Rift Remover");
LanguageRegistry.addName(itemStableFabric, "Stable Fabric");
LanguageRegistry.addName(itemUnstableDoor, "Unstable Door");
LanguageRegistry.addName(itemDimensionalDoor, "Dimensional Door");
LanguageRegistry.addName(itemRiftBlade, "Rift Blade");
LanguageRegistry.addName(itemWorldThread, "World Thread");
LanguageRegistry.addName(itemDDKey, "Rift Key");
LanguageRegistry.addName(itemQuartzDoor, "Quartz Door");
LanguageRegistry.addName(itemPersonalDoor, "Personal Dimensional Door");
/**
* Add names for multiblock inventory item
*/
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 0), "Fabric of Reality");
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 1), "Ancient Fabric");
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 2), "Altered Fabric");
LanguageRegistry.instance().addStringLocalization("itemGroup.dimDoorsCustomTab", "en_US", "Dimensional Doors Items");
@@ -311,12 +286,9 @@ public class mod_pocketDim
EntityRegistry.registerModEntity(MobMonolith.class, "Monolith", properties.MonolithEntityID, this, 70, 1, true);
EntityList.IDtoClassMapping.put(properties.MonolithEntityID, MobMonolith.class);
EntityList.entityEggs.put(properties.MonolithEntityID, new EntityEggInfo(properties.MonolithEntityID, 0, 0xffffff));
LanguageRegistry.instance().addStringLocalization("entity.dimdoors.Monolith.name", "Monolith");
LanguageRegistry.instance().addStringLocalization("entity.DimDoors.Obelisk.name", "Monolith");
CraftingManager.registerRecipes(properties);
CraftingManager.registerDispenserBehaviors();
GameRegistry.registerCraftingHandler(new CraftingManager());
DungeonHelper.initialize();
gatewayGenerator = new GatewayGenerator(properties);
GameRegistry.registerWorldGenerator(mod_pocketDim.gatewayGenerator);
@@ -345,14 +317,7 @@ public class mod_pocketDim
deathTracker.writeToFile();
deathTracker = null;
worldProperties = null;
currrentSaveRootDirectory = null;
// Unregister all tick receivers from serverTickHandler to avoid leaking
// scheduled tasks between single-player game sessions
serverTickHandler.unregisterReceivers();
spawner = null;
riftRegenerator = null;
limboDecayScheduler = null;
this.currrentSaveRootDirectory=null;
}
catch (Exception e)
{
@@ -370,14 +335,6 @@ public class mod_pocketDim
// Initialize a new DeathTracker
deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt");
// Register regular tick receivers
// CustomLimboPopulator should be initialized before any provider instances are created
spawner = new CustomLimboPopulator(serverTickHandler, properties);
riftRegenerator = new RiftRegenerator(serverTickHandler, blockRift);
limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay);
hooks.setSessionFields(worldProperties, riftRegenerator);
}
@EventHandler
@@ -388,14 +345,19 @@ public class mod_pocketDim
event.registerServerCommand( CommandCreateDungeonRift.instance() );
event.registerServerCommand( CommandListDungeons.instance() );
event.registerServerCommand( CommandCreateRandomRift.instance() );
event.registerServerCommand( CommandDeleteAllLinks.instance() );
//CommandDeleteDimensionData.instance().register(event);
event.registerServerCommand( CommandDeleteRifts.instance() );
event.registerServerCommand( CommandExportDungeon.instance() );
//CommandPrintDimensionData.instance().register(event);
//CommandPruneDimensions.instance().register(event);
event.registerServerCommand( CommandCreatePocket.instance() );
event.registerServerCommand( CommandTeleportPlayer.instance() );
try
{
ChunkLoaderHelper.loadForcedChunkWorlds(event);
ChunkLoaderHelper.loadChunkForcedWorlds(event);
}
catch (Exception e)
{

View File

@@ -7,13 +7,12 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
@@ -21,6 +20,7 @@ import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.util.DDLogger;
import StevenDimDoors.mod_pocketDim.util.FileFilters;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import com.google.common.io.Files;
public class DDSaveHandler
@@ -59,15 +59,6 @@ public class DDSaveHandler
PocketManager.createAndRegisterBlacklist(blacklist);
}
// Load the personal pockets mapping
File personalPocketMap = new File(basePath+"personalPockets.txt");
HashMap<String, Integer> ppMap = new HashMap<String, Integer>();
if(personalPocketMap.exists())
{
PersonalPocketMappingProcessor ppMappingProcessor = new PersonalPocketMappingProcessor();
ppMap = readPersonalPocketsMapping(personalPocketMap,ppMappingProcessor);
}
// List any dimension data files and read each dimension
DimDataProcessor reader = new DimDataProcessor();
HashMap<Integer, PackedDimData> packedDims = new HashMap<Integer, PackedDimData>();
@@ -91,17 +82,7 @@ public class DDSaveHandler
{
linksToUnpack.addAll(packedDim.Links);
}
unpackDimData(packedDims);
unpackLinkData(linksToUnpack);
HashMap<String, NewDimData> personalPocketsMap = new HashMap<String, NewDimData>();
for(Entry<String, Integer> pair : ppMap.entrySet())
{
personalPocketsMap.put(pair.getKey(), PocketManager.getDimensionData(pair.getValue()));
}
PocketManager.setPersonalPocketsMapping(personalPocketsMap);
return true;
return unpackDimData(packedDims) && unpackLinkData(linksToUnpack);
}
/**
@@ -158,7 +139,7 @@ public class DDSaveHandler
}
if(isMissing)
{
packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, DimensionType.getTypeFromIndex(packedDim.DimensionType), packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails));
packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails));
packedDims.put(packedDim.ID, packedDim);
}
return children;
@@ -176,12 +157,12 @@ public class DDSaveHandler
{
ArrayList<Integer> fosterChildren = new ArrayList<Integer>();
fosterChildren.add(packedDim.ID);
DimensionType type = DimensionType.getTypeFromIndex(packedDim.DimensionType);
//fix pockets without parents
if(!packedDims.containsKey(packedDim.ParentID))
{
//Fix the orphan by changing its root to its parent, re-connecting it to the list
packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation,type, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails));
packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails));
packedDims.put(packedDim.ID, packedDim);
}
//fix pockets whose parents have forgotten about them
@@ -190,7 +171,7 @@ public class DDSaveHandler
{
//find the root, and fix it by adding the orphan's ID to its children
fosterChildren.addAll(fosterParent.ChildIDs);
fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, type, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails));
fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, fosterParent.IsDungeon, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails));
packedDims.put(fosterParent.ID, fosterParent);
}
@@ -209,14 +190,18 @@ public class DDSaveHandler
if(packedLink.parent.equals(fakePoint))
{
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension());
LinkType linkType = LinkType.getLinkTypeFromIndex(packedLink.tail.linkType);
int linkType = packedLink.tail.linkType;
if((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE)
{
linkType = LinkTypes.NORMAL;
}
DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation, packedLink.lock);
DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation);
Point4D destination = packedLink.tail.destination;
if(destination!=null)
{
PocketManager.createDimensionDataDangerously(destination.getDimension()).setLinkDestination(link, destination.getX(),destination.getY(),destination.getZ());
PocketManager.getDimensionData(destination.getDimension()).setDestination(link, destination.getX(),destination.getY(),destination.getZ());
}
unpackedLinks.add(packedLink);
}
@@ -228,10 +213,10 @@ public class DDSaveHandler
{
for(PackedLinkData packedLink : linksToUnpack)
{
NewDimData data = PocketManager.createDimensionDataDangerously(packedLink.source.getDimension());
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension());
if(data.getLink(packedLink.parent)!=null)
{
data.createChildLink(packedLink.source, data.getLink(packedLink.parent), packedLink.lock);
data.createChildLink(packedLink.source.getX(), packedLink.source.getY(), packedLink.source.getZ(), data.getLink(packedLink.parent));
}
unpackedLinks.add(packedLink);
}
@@ -285,9 +270,6 @@ public class DDSaveHandler
// Create and write the blackList
writeBlacklist(blacklist, savePath);
//create and write personal pocket mapping
writePersonalPocketMap(PocketManager.getPersonalPocketMapping(), savePath);
// Write the dimension save data
boolean succeeded = true;
DimDataProcessor writer = new DimDataProcessor();
@@ -330,32 +312,6 @@ public class DDSaveHandler
}
}
private static boolean writePersonalPocketMap(HashMap<String, NewDimData> hashMap, String savePath)
{
try
{
HashMap<String, Integer> ppMap = new HashMap<String, Integer>();
for(Entry<String, NewDimData> pair : hashMap.entrySet())
{
ppMap.put(pair.getKey(), pair.getValue().id());
}
PersonalPocketMappingProcessor writer = new PersonalPocketMappingProcessor();
File tempFile = new File(savePath + "/personalPockets.tmp");
File saveFile = new File(savePath + "/personalPockets.txt");
writer.writeToFile(tempFile, ppMap);
saveFile.delete();
tempFile.renameTo(saveFile);
return true;
}
catch (Exception e)
{
System.err.println("Could not save personal pockets mapping. The following error occurred:");
printException(e, true);
return false;
}
}
private static boolean writeDimension(IPackable<PackedDimData> dimension, DimDataProcessor writer, String basePath, String backupPath)
{
try
@@ -422,6 +378,7 @@ public class DDSaveHandler
public static List<Integer> readBlacklist(File blacklistFile, BlacklistProcessor reader)
{
try
{
return reader.readFromFile(blacklistFile);
@@ -431,18 +388,6 @@ public class DDSaveHandler
e.printStackTrace();
return null;
}
}
public static HashMap<String,Integer> readPersonalPocketsMapping(File ppMap, PersonalPocketMappingProcessor reader)
{
try
{
return reader.readFromFile(ppMap);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
}

View File

@@ -4,53 +4,33 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.HashMap;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
import StevenDimDoors.mod_pocketDim.util.JSONValidator;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
{
public final String JSON_VERSION_PROPERTY_NAME = "SAVE_DATA_VERSION_ID_INSTANCE";
private HashMap<Integer, JsonObject> SAVE_DATA_SCHEMA;
private static final JsonParser jsonParser = new JsonParser();
public static final String BASE_SCHEMA_PATH = "/assets/dimdoors/text/";
//TODO dont load the schemas every time
public DimDataProcessor()
{
SAVE_DATA_SCHEMA = new HashMap<Integer, JsonObject>();
//Load the old schema/s
SAVE_DATA_SCHEMA.put(982405775, loadSchema(BASE_SCHEMA_PATH+"Dim_Data_Schema_v982405775.json"));
//load the current schema
SAVE_DATA_SCHEMA.put(PackedDimData.SAVE_DATA_VERSION_ID, loadSchema(BASE_SCHEMA_PATH+"Dim_Data_Schema_v1-0-0.json"));
}
@Override
public PackedDimData readFromStream(InputStream inputStream)
throws ConfigurationProcessingException
{
try
{
//read in the json save file represeting a single dimension
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
PackedDimData data = this.readDimDataJson(reader);
PackedDimData data = this.createDImDataFromJson(reader);
reader.close();
return data;
}
catch (Exception e)
catch (IOException e)
{
e.printStackTrace();
throw new ConfigurationProcessingException("Could not read packedDimData");
@@ -62,132 +42,259 @@ public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
public void writeToStream(OutputStream outputStream, PackedDimData data)
throws ConfigurationProcessingException
{
//create a json object from a packedDimData instance
/** Print out dimData using the GSON built in serializer. I dont feel bad doing this because
* 1- We can read it
* 2- We are manually reading the data in.
* 3- The error messages tell us exactly where its failing, so its easy to fix
*/
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setPrettyPrinting();
Gson gson = gsonBuilder.create();
JsonElement ele = gson.toJsonTree(data);
Gson gson = gsonBuilder.setPrettyPrinting().create();
try
{
//ensure our json object corresponds to our schema
JSONValidator.validate(getSaveDataSchema(ele.getAsJsonObject()), ele);
outputStream.write(gson.toJson(ele).getBytes("UTF-8"));
outputStream.write(gson.toJson(data).getBytes("UTF-8"));
outputStream.close();
}
catch (Exception e)
catch (IOException e)
{
// not sure if this is kosher, we need it to explode, but not by throwing the IO exception.
throw new ConfigurationProcessingException("Could not access save data");
throw new ConfigurationProcessingException("Incorrectly formatted save data");
}
}
/**
* validates the save file against it's current version, then updates and validates it again if it needs it
* then it loads it
* Nightmare method that takes a JsonReader pointed at a serialized instance of PackedDimData
* @param reader
* @return
* @throws IOException
*/
public PackedDimData readDimDataJson(JsonReader reader) throws IOException
public PackedDimData createDImDataFromJson(JsonReader reader) throws IOException
{
//read the save file into a Json element
JsonElement ele = jsonParser.parse(reader);
int ID;
boolean IsDungeon;
boolean IsFilled;
int Depth;
int PackDepth;
int ParentID;
int RootID;
PackedDungeonData Dungeon = null;
Point3D Origin;
int Orientation;
List<Integer> ChildIDs;
List<PackedLinkData> Links;
List<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
//get the schema that corresponds to the save file's listed version number
JsonObject schema = this.getSaveDataSchema(ele.getAsJsonObject());
reader.beginObject();
//validate the save file against its schema
JSONValidator.validate(schema, ele);
reader.nextName();
if (reader.nextLong() != PackedDimData.SAVE_DATA_VERSION_ID)
{
throw new IOException("Save data version mismatch");
}
//handle updating old save data
ele = processSaveData(schema, ele.getAsJsonObject());
reader.nextName();
ID = reader.nextInt();
//convert the updated and verified json into an instance of PackedDimData
GsonBuilder gsonBuilder = new GsonBuilder();
return gsonBuilder.create().fromJson(ele, PackedDimData.class);
reader.nextName();
IsDungeon = reader.nextBoolean();
reader.nextName();
IsFilled = reader.nextBoolean();
reader.nextName();
Depth = reader.nextInt();
reader.nextName();
PackDepth = reader.nextInt();
reader.nextName();
ParentID=reader.nextInt();
reader.nextName();
RootID= reader.nextInt();
if(reader.nextName().equals("DungeonData"))
{
Dungeon = createDungeonDataFromJson(reader);
reader.nextName();
}
Origin = createPointFromJson(reader);
reader.nextName();
Orientation = reader.nextInt();
reader.nextName();
ChildIDs = this.createIntListFromJson(reader);
reader.nextName();
Links = this.createLinksListFromJson(reader);
return new PackedDimData(ID, Depth, PackDepth, ParentID, RootID, Orientation, IsDungeon, IsFilled, Dungeon, Origin, ChildIDs, Links, Tails);
}
/**
* Gets the schema that corresponds to a version of our save data
* @param obj
* @return
* @throws IOException
*/
public JsonObject getSaveDataSchema(JsonObject obj)
private Point3D createPointFromJson(JsonReader reader) throws IOException
{
JsonObject schema = this.SAVE_DATA_SCHEMA.get(obj.get(JSON_VERSION_PROPERTY_NAME).getAsInt());
reader.beginObject();
if(schema == null)
{
throw new IllegalStateException("Invalid save data version");
}
reader.nextName();
int x = reader.nextInt();
return schema;
reader.nextName();
int y = reader.nextInt();
reader.nextName();
int z = reader.nextInt();
reader.endObject();
return new Point3D(x,y,z);
}
/**
* Internally load the save data schema so we dont load them every single time we validate save data
* @param path
* @return
*/
private JsonObject loadSchema(String path)
private Point4D createPoint4DFromJson(JsonReader reader) throws IOException
{
InputStream in = this.getClass().getResourceAsStream(path);
JsonReader reader = new JsonReader(new InputStreamReader(in));
reader.beginObject();
JsonObject schema = jsonParser.parse(reader).getAsJsonObject();
try
{
reader.close();
in.close();
}
catch (IOException e)
{
System.err.println("Could not load Json Save Data definitions");
e.printStackTrace();
throw new IllegalStateException("Could not load Json Save Data definitions");
}
reader.nextName();
int x = reader.nextInt();
return schema;
reader.nextName();
int y = reader.nextInt();
reader.nextName();
int z = reader.nextInt();
reader.nextName();
int dimension = reader.nextInt();
reader.endObject();
return new Point4D(x,y,z,dimension);
}
/**
* I use this method to update old save data files to the new format before actually loading them.
* @return
*/
public JsonObject processSaveData(JsonObject schema, JsonObject save)
private List<Integer> createIntListFromJson(JsonReader reader) throws IOException
{
if(save.get(JSON_VERSION_PROPERTY_NAME).getAsInt()== 982405775)
List<Integer> list = new ArrayList<Integer>();
reader.beginArray();
while (reader.peek() != JsonToken.END_ARRAY)
{
DimensionType type;
list.add(reader.nextInt());
//see if the dim is a pocket
if(save.get("RootID").getAsInt() != save.get("ID").getAsInt())
{
if(save.get("IsDungeon").getAsBoolean())
{
type = DimensionType.DUNGEON;
}
else
{
type = DimensionType.POCKET;
}
}
else
{
type = DimensionType.ROOT;
}
}
reader.endArray();
return list;
}
save.remove("IsDungeon");
save.addProperty("DimensionType",type.index);
save.remove(this.JSON_VERSION_PROPERTY_NAME);
save.addProperty(this.JSON_VERSION_PROPERTY_NAME, PackedDimData.SAVE_DATA_VERSION_ID);
return processSaveData(this.getSaveDataSchema(save), save);
private List<PackedLinkData> createLinksListFromJson(JsonReader reader) throws IOException
{
List<PackedLinkData> list = new ArrayList<PackedLinkData>();
reader.beginArray();
while (reader.peek() != JsonToken.END_ARRAY)
{
list.add(createLinkDataFromJson(reader));
}
reader.endArray();
return list;
}
private PackedLinkData createLinkDataFromJson(JsonReader reader) throws IOException
{
Point4D source;
Point3D parent;
PackedLinkTail tail;
int orientation;
List<Point3D> children = new ArrayList<Point3D>();
reader.beginObject();
reader.nextName();
source = this.createPoint4DFromJson(reader);
reader.nextName();
parent = this.createPointFromJson(reader);
reader.nextName();
tail = this.createLinkTailFromJson(reader);
reader.nextName();
orientation = reader.nextInt();
reader.nextName();
reader.beginArray();
while (reader.peek() != JsonToken.END_ARRAY)
{
children.add(this.createPointFromJson(reader));
}
reader.endArray();
reader.endObject();
return new PackedLinkData(source, parent, tail, orientation, children);
}
private PackedDungeonData createDungeonDataFromJson(JsonReader reader) throws IOException
{
int Weight;
boolean IsOpen;
boolean IsInternal;
String SchematicPath;
String SchematicName;
String DungeonTypeName;
String DungeonPackName;
reader.beginObject();
@SuppressWarnings("unused")
JsonToken test = reader.peek();
if(reader.peek() == JsonToken.END_OBJECT)
{
return null;
}
JSONValidator.validate(this.getSaveDataSchema(save), save);
return save;
reader.nextName();
Weight=reader.nextInt();
reader.nextName();
IsOpen=reader.nextBoolean();
reader.nextName();
IsInternal=reader.nextBoolean();
reader.nextName();
SchematicPath=reader.nextString();
reader.nextName();
SchematicName=reader.nextString();
reader.nextName();
DungeonTypeName=reader.nextString();
reader.nextName();
DungeonPackName=reader.nextString();
reader.endObject();
return new PackedDungeonData(Weight, IsOpen, IsInternal, SchematicPath, SchematicName, DungeonTypeName, DungeonPackName);
}
private PackedLinkTail createLinkTailFromJson(JsonReader reader) throws IOException
{
Point4D destination = null;
int linkType;
reader.beginObject();
reader.nextName();
@SuppressWarnings("unused")
JsonToken test = reader.peek();
if (reader.peek() == JsonToken.BEGIN_OBJECT)
{
destination = this.createPoint4DFromJson(reader);
reader.nextName();
}
linkType = reader.nextInt();
reader.endObject();
return new PackedLinkTail(destination, linkType);
}
}

View File

@@ -2,16 +2,17 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import StevenDimDoors.mod_pocketDim.DimData;
import StevenDimDoors.mod_pocketDim.LinkData;
import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class OldSaveImporter
@@ -38,83 +39,35 @@ public class OldSaveImporter
return;
}
//build the child list
HashMap<Integer, ArrayList<Integer>> parentChildMapping = new HashMap<Integer, ArrayList<Integer>>();
for(DimData data : dimMap.values())
{
if(data.isPocket)
{
LinkData link = data.exitDimLink;
if(parentChildMapping.containsKey(link.destDimID))
{
parentChildMapping.get(link.destDimID).add(data.dimID);
}
else
{
parentChildMapping.put(link.destDimID, new ArrayList<Integer>());
parentChildMapping.get(link.destDimID).add(data.dimID);
}
parentChildMapping.remove(data.dimID);
}
}
for(DimData data : dimMap.values())
{
List<PackedLinkData> newPackedLinkData = new ArrayList<PackedLinkData>();
List<Integer> childDims;
if(parentChildMapping.containsKey(data.dimID))
{
childDims =parentChildMapping.get(data.dimID);
}
else
{
childDims = new ArrayList<Integer>();
}
List<Integer> childDims = new ArrayList<Integer>();
for(LinkData link : data.getLinksInDim())
{
Point4D source = new Point4D(link.locXCoord,link.locYCoord,link.locZCoord,link.locDimID);
Point4D destintion = new Point4D(link.destXCoord,link.destYCoord,link.destZCoord,link.destDimID);
PackedLinkTail tail = new PackedLinkTail(destintion, LinkType.NORMAL);
PackedLinkTail tail = new PackedLinkTail(destintion, link.linkOrientation);
List<Point3D> children = new ArrayList<Point3D>();
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children, null);
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children);
newPackedLinkData.add(newPackedLink);
allPackedLinks.add(newPackedLink);
}
PackedDimData dim;
DimensionType type;
if(data.isPocket)
{
if(data.dungeonGenerator!=null)
{
type = DimensionType.DUNGEON;
}
else
{
type = DimensionType.POCKET;
}
}
else
{
type = DimensionType.ROOT;
}
if(data.isPocket)
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
}
else
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.dimID, data.dimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
}
PackedDimData dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, data.dungeonGenerator!=null, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
newPackedDimData.put(dim.ID,dim);
DDSaveHandler.unpackDimData(newPackedDimData);
DDSaveHandler.unpackLinkData(allPackedLinks);
}
DDSaveHandler.unpackDimData(newPackedDimData);
DDSaveHandler.unpackLinkData(allPackedLinks);
}
}

View File

@@ -3,15 +3,14 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.util.List;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
public class PackedDimData
{
// These fields will be public since this is a simple data container
public final static int SAVE_DATA_VERSION_ID = 100;
public final static long SAVE_DATA_VERSION_ID = 982405775L;
public final long SAVE_DATA_VERSION_ID_INSTANCE = SAVE_DATA_VERSION_ID;
public final int ID;
public final int DimensionType;
public final boolean IsDungeon;
public final boolean IsFilled;
public final int Depth;
public final int PackDepth;
@@ -27,7 +26,7 @@ public class PackedDimData
// FIXME Missing dungeon data, not sure how to include it
public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, int orientation,
DimensionType type, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
boolean isDungeon, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
List<PackedLinkTail> tails)
{
ID = id;
@@ -36,7 +35,7 @@ public class PackedDimData
ParentID = parentID;
RootID = rootID;
Orientation = orientation;
DimensionType = type.index;
IsDungeon = isDungeon;
IsFilled = isFilled;
DungeonData = dungeonData;
Origin = origin;
@@ -50,6 +49,4 @@ public class PackedDimData
{
return "ID= "+this.ID;
}
}

View File

@@ -3,7 +3,6 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.util.List;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class PackedLinkData
@@ -13,15 +12,13 @@ public class PackedLinkData
public final PackedLinkTail tail;
public final int orientation;
public final List<Point3D> children;
public final DDLock lock;
public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children, DDLock lock)
public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children)
{
this.source=source;
this.parent=parent;
this.tail=tail;
this.orientation=orientation;
this.children=children;
this.lock = lock;
}
}

View File

@@ -1,6 +1,5 @@
package StevenDimDoors.mod_pocketDim.saving;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class PackedLinkTail
@@ -8,10 +7,10 @@ public class PackedLinkTail
public final Point4D destination;
public final int linkType;
public PackedLinkTail(Point4D destination, LinkType linkType)
public PackedLinkTail(Point4D destination, int linkType)
{
this.destination=destination;
this.linkType=linkType.index;
this.linkType=linkType;
}
}

View File

@@ -1,79 +0,0 @@
package StevenDimDoors.mod_pocketDim.saving;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
public class PersonalPocketMappingProcessor extends BaseConfigurationProcessor<HashMap<String, Integer>>
{
@Override
public HashMap<String, Integer> readFromStream(InputStream inputStream) throws ConfigurationProcessingException
{
try
{
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
HashMap<String, Integer> data = this.createPersonalPocketsMapFromJson(reader);
reader.close();
return data;
}
catch (IOException e)
{
e.printStackTrace();
throw new ConfigurationProcessingException("Could not read personal pocket mapping");
}
}
private HashMap<String, Integer> createPersonalPocketsMapFromJson(JsonReader reader) throws IOException
{
HashMap<String, Integer> ppMap;
ppMap = this.createMapFromJson(reader);
return ppMap;
}
private HashMap<String, Integer> createMapFromJson(JsonReader reader) throws IOException
{
HashMap<String, Integer> map = new HashMap<String, Integer>();
reader.beginObject();
while(reader.peek()!= JsonToken.END_OBJECT)
{
map.put(reader.nextName(), reader.nextInt());
}
reader.endObject();
return map;
}
@Override
public void writeToStream(OutputStream outputStream, HashMap<String, Integer> data) throws ConfigurationProcessingException
{
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.setPrettyPrinting().create();
try
{
outputStream.write(gson.toJson(data).getBytes("UTF-8"));
outputStream.close();
}
catch (IOException e)
{
// not sure if this is kosher, we need it to explode, but not by throwing the IO exception.
throw new ConfigurationProcessingException("Incorrectly formatted save data");
}
}
}

View File

@@ -70,8 +70,6 @@ public class BlockRotator
hasOrientations[mod_pocketDim.dimensionalDoor.blockID] = true;
hasOrientations[mod_pocketDim.warpDoor.blockID] = true;
hasOrientations[mod_pocketDim.goldenDimensionalDoor.blockID] = true;
hasOrientations[mod_pocketDim.personalDimDoor.blockID] = true;
}

View File

@@ -7,31 +7,26 @@ import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
public class ServerTickHandler implements ITickHandler, IRegularTickSender
public class CommonTickHandler implements ITickHandler, IRegularTickSender
{
private static final String PROFILING_LABEL = "Dimensional Doors: Server Tick";
private static final String PROFILING_LABEL = "Dimensional Doors: Common Tick";
private int tickCount = 0;
private ArrayList<RegularTickReceiverInfo> receivers;
public ServerTickHandler()
public CommonTickHandler()
{
this.receivers = new ArrayList<RegularTickReceiverInfo>();
}
@Override
public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart)
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart)
{
RegularTickReceiverInfo info = new RegularTickReceiverInfo(receiver, interval, onTickStart);
receivers.add(info);
}
@Override
public void unregisterReceivers()
{
receivers.clear();
}
@Override
public void tickStart(EnumSet<TickType> type, Object... tickData)
{

View File

@@ -1,5 +1,6 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -30,7 +31,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
{
this.properties = properties;
this.locations = new ConcurrentLinkedQueue<ChunkLocation>();
sender.registerReceiver(this, MONOLITH_SPAWNING_INTERVAL, false);
sender.registerForTicking(this, MONOLITH_SPAWNING_INTERVAL, false);
}
@Override
@@ -64,7 +65,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
limboWorld = PocketManager.loadDimension(properties.LimboDimensionID);
}
placeMonolithsInLimbo(limboWorld, location.ChunkX, location.ChunkZ);
mod_pocketDim.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ,
mod_pocketDim.instance.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ,
limboWorld, limboWorld.getChunkProvider(), limboWorld.getChunkProvider());
}
else

View File

@@ -0,0 +1,53 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class FastRiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 10; //Regenerate scheduled rifts every 10 ticks
private static Random random = new Random();
private ArrayList<Point4D> locationsToRegen = new ArrayList<Point4D>();
public FastRiftRegenerator(IRegularTickSender sender)
{
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
}
@Override
public void notifyTick()
{
regenerateScheduledRifts();
}
public void regenerateScheduledRifts()
{
if (!locationsToRegen.isEmpty())
{
List<Integer> loadedWorlds = (List<Integer>) Arrays.asList(DimensionManager.getIDs());
for (Point4D point: locationsToRegen)
{
if (loadedWorlds.contains(point.getDimension()) && PocketManager.getLink(point) != null)
{
World world = DimensionManager.getWorld(point.getDimension());
mod_pocketDim.blockRift.regenerateRift(world, point.getX(), point.getY(), point.getZ(), random);
}
}
locationsToRegen.clear();
}
}
public void registerRiftForRegen(int x, int y, int z, int dimID)
{
this.locationsToRegen.add(new Point4D(x, y, z, dimID));
}
}

View File

@@ -3,7 +3,6 @@ package StevenDimDoors.mod_pocketDim.ticking;
public interface IRegularTickSender {
public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart);
public void unregisterReceivers();
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart);
}

View File

@@ -1,4 +1,4 @@
package StevenDimDoors.mod_pocketDim.world;
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.Random;
@@ -13,12 +13,13 @@ import StevenDimDoors.mod_pocketDim.config.DDProperties;
* Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo
* naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes.
*/
public class LimboDecay {
public class LimboDecay implements IRegularTickReceiver {
private static final int MAX_DECAY_SPREAD_CHANCE = 100;
private static final int DECAY_SPREAD_CHANCE = 50;
private static final int CHUNK_SIZE = 16;
private static final int SECTION_HEIGHT = 16;
private static final int LIMBO_DECAY_INTERVAL = 10; //Apply spread decay every 10 ticks
//Provides a reversed list of the block IDs that blocks cycle through during decay.
private final int[] decaySequence;
@@ -27,7 +28,7 @@ public class LimboDecay {
private final DDProperties properties;
private final int[] blocksImmuneToDecay;
public LimboDecay(DDProperties properties)
public LimboDecay(IRegularTickSender tickSender, DDProperties properties)
{
decaySequence = new int[] {
properties.LimboBlockID,
@@ -50,6 +51,16 @@ public class LimboDecay {
this.properties = properties;
this.random = new Random();
tickSender.registerForTicking(this, LIMBO_DECAY_INTERVAL, false);
}
/**
* Applies fast Limbo decay periodically.
*/
@Override
public void notifyTick()
{
applyRandomFastDecay();
}
/**
@@ -77,7 +88,7 @@ public class LimboDecay {
* Picks random blocks from each active chunk in Limbo and, if decay is applicable, converts them directly to Unraveled Fabric.
* This decay method is designed to stop players from avoiding Limbo decay by building floating structures.
*/
public void applyRandomFastDecay()
private void applyRandomFastDecay()
{
int x, y, z;
int sectionY;

View File

@@ -1,28 +0,0 @@
package StevenDimDoors.mod_pocketDim.ticking;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
/**
* Handles scheduling of periodic fast Limbo decay operations.
*/
public class LimboDecayScheduler implements IRegularTickReceiver {
private static final int LIMBO_DECAY_INTERVAL = 10; //Apply fast decay every 10 ticks
private LimboDecay decay;
public LimboDecayScheduler(IRegularTickSender tickSender, LimboDecay decay)
{
this.decay = decay;
tickSender.registerReceiver(this, LIMBO_DECAY_INTERVAL, false);
}
/**
* Applies fast Limbo decay periodically.
*/
@Override
public void notifyTick()
{
decay.applyRandomFastDecay();
}
}

View File

@@ -2,16 +2,22 @@ package StevenDimDoors.mod_pocketDim.ticking;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.DataWatcher;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityFlying;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
@@ -21,31 +27,26 @@ import StevenDimDoors.mod_pocketDim.world.PocketProvider;
public class MobMonolith extends EntityFlying implements IMob
{
private static final short MAX_AGGRO = 250;
private static final short MAX_AGGRO_CAP = 100;
private static final short MIN_AGGRO_CAP = 25;
private static final int MAX_TEXTURE_STATE = 18;
private static final int MAX_SOUND_COOLDOWN = 200;
private static final int MAX_AGGRO_RANGE = 35;
private static final int AGGRO_WATCHER_INDEX = 16;
private static final float WIDTH = 3f;
private static final float HEIGHT = 3f;
private static final float EYE_HEIGHT = HEIGHT / 2;
public static final int MAX_AGGRO_RANGE = 35;
public static final int MAX_SOUND_COOLDOWN = 200;
public static final float MAX_AGGRO = 100;
public static final int TEXTURE_STATES = 18;
public float pitchLevel;
private short aggro = 0;
private int soundTime = 0;
private final short aggroCap;
public float aggro = 0;
private float soundTime = 0;
private byte textureState = 0;
private int aggroMax;
private static DDProperties properties = null;
public MobMonolith(World world)
public MobMonolith(World par1World)
{
super(world);
this.setSize(WIDTH, HEIGHT);
this.noClip = true;
this.aggroCap = (short) MathHelper.getRandomIntegerInRange(this.rand, MIN_AGGRO_CAP, MAX_AGGRO_CAP);
super(par1World);
this.setSize(3F, 3F);
this.noClip=true;
this.aggroMax = rand.nextInt(245)+200;
if (properties == null)
properties = DDProperties.instance();
}
@@ -59,19 +60,16 @@ public class MobMonolith extends EntityFlying implements IMob
@Override
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
{
if (par1DamageSource != DamageSource.inWall)
if (par1DamageSource == DamageSource.inWall)
{
this.aggro = MAX_AGGRO;
this.posY = posY + 1;
}
else
{
this.aggro = this.aggroMax;
}
return false;
}
@Override
public boolean canBreatheUnderwater()
{
return true;
}
@Override
public AxisAlignedBB getBoundingBox()
{
@@ -94,7 +92,7 @@ public class MobMonolith extends EntityFlying implements IMob
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(57005);
this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(10);
}
@Override
@@ -106,15 +104,22 @@ public class MobMonolith extends EntityFlying implements IMob
@Override
public float getEyeHeight()
{
return EYE_HEIGHT;
return this.height +2F;
}
public void setEntityPosition(Entity entity, double x, double y, double z)
{
entity.lastTickPosX = entity.prevPosX = entity.posX = x;
entity.lastTickPosY = entity.prevPosY = entity.posY = y + entity.yOffset;
entity.lastTickPosZ = entity.prevPosZ = entity.posZ = z;
entity.setPosition(x, y, z);
}
@Override
protected void entityInit()
{
super.entityInit();
// Add a short for the aggro level
this.dataWatcher.addObject(AGGRO_WATCHER_INDEX, Short.valueOf((short) 0));
this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
}
@Override
@@ -126,105 +131,73 @@ public class MobMonolith extends EntityFlying implements IMob
@Override
public void onEntityUpdate()
{
// Remove this Monolith if it's not in Limbo or in a pocket dimension
if (!(this.worldObj.provider instanceof LimboProvider || this.worldObj.provider instanceof PocketProvider))
{
this.setDead();
super.onEntityUpdate();
return;
}
super.onEntityUpdate();
// Check for players and update aggro levels even if there are no players in range
EntityPlayer player = this.worldObj.getClosestPlayerToEntity(this, MAX_AGGRO_RANGE);
boolean visibility = (player != null) ? player.canEntityBeSeen(this) : false;
this.updateAggroLevel(player, visibility);
EntityPlayer entityPlayer = this.worldObj.getClosestPlayerToEntity(this,MAX_AGGRO_RANGE);
// Change orientation and face a player if one is in range
if (player != null)
//need to always manage aggro level, even if player is out of range.
this.setAggroLevel(entityPlayer);
//these things only matter if the player is in range.
if (entityPlayer != null)
{
this.facePlayer(player);
if (!this.worldObj.isRemote && !(this.worldObj.provider instanceof LimboProvider))
this.faceEntity(entityPlayer, 1, 1);
this.playSounds(entityPlayer);
//teleport the player if the conditions are met
if (aggro >= MAX_AGGRO && !this.worldObj.isRemote && properties.MonolithTeleportationEnabled && !entityPlayer.capabilities.isCreativeMode)
{
// Play sounds on the server side, if the player isn't in Limbo.
// Limbo is excluded to avoid drowning out its background music.
// Also, since it's a large open area with many Monoliths, some
// of the sounds that would usually play for a moment would
// keep playing constantly and would get very annoying.
this.playSounds(player);
}
if (visibility)
{
// Only spawn particles on the client side and outside Limbo
if (this.worldObj.isRemote && !(this.worldObj.provider instanceof LimboProvider))
{
this.spawnParticles(player);
}
// Teleport the target player if various conditions are met
if (aggro >= MAX_AGGRO && !this.worldObj.isRemote &&
properties.MonolithTeleportationEnabled && !player.capabilities.isCreativeMode &&
!(this.worldObj.provider instanceof LimboProvider))
{
this.aggro = 0;
Point4D destination = LimboProvider.getLimboSkySpawn(player, properties);
DDTeleporter.teleportEntity(player, destination, false);
player.worldObj.playSoundAtEntity(player, mod_pocketDim.modid + ":crack", 13, 1);
}
Point4D destination = LimboProvider.getLimboSkySpawn(entityPlayer, properties);
DDTeleporter.teleportEntity(entityPlayer, destination, false);
this.aggro = 0;
entityPlayer.worldObj.playSoundAtEntity(entityPlayer,mod_pocketDim.modid+":crack",13, 1);
}
}
}
private void updateAggroLevel(EntityPlayer player, boolean visibility)
private void setAggroLevel(EntityPlayer player)
{
// If we're working on the server side, adjust aggro level
// If we're working on the client side, retrieve aggro level from dataWatcher
if (!this.worldObj.isRemote)
//aggro constantly decreases at a rate that varies with the current amount of aggro.
if(aggro > 0)
{
// Server side...
// Rapidly increase the aggro level if this Monolith can see the player
if (visibility)
this.aggro = this.aggro -(this.aggro/25);
}
if(player != null)
{
//monoliths increase aggro slightly if the player is near, but slowly and to a cap.
float distance = this.getDistanceToEntity(player);
aggro+= 1.5-(distance/this.MAX_AGGRO_RANGE);
//rapidly increase aggro if the monolith has line of sight to the player.
if(player.canEntityBeSeen(this))
{
if (this.worldObj.provider instanceof LimboProvider)
//prevent monoliths from teleporting the player in limbo
if(this.worldObj.provider instanceof LimboProvider)
{
aggro++;
aggro+=1.5;
}
else
{
// Aggro increases faster outside of Limbo
aggro += 3;
this.spawnParticles(player);
aggro+=3;
}
}
else
{
if (aggro > aggroCap)
{
// Decrease aggro over time
aggro--;
}
else if (player != null && (aggro < aggroCap))
{
// Increase aggro if a player is within range and aggro < aggroCap
aggro++;
}
}
// Clamp the aggro level
aggro = (short) MathHelper.clamp_int(aggro, 0, MAX_AGGRO);
this.dataWatcher.updateObject(AGGRO_WATCHER_INDEX, Short.valueOf(aggro));
}
else
{
// Client side...
aggro = this.dataWatcher.getWatchableObjectShort(AGGRO_WATCHER_INDEX);
}
}
public int getTextureState()
{
// Determine texture state from aggro progress
return MathHelper.clamp_int(MAX_TEXTURE_STATE * aggro / MAX_AGGRO, 0, MAX_TEXTURE_STATE);
//convert the aggro counter to one of the texture states, and set it.
this.textureState = (byte) ((this.TEXTURE_STATES/this.MAX_AGGRO)*this.aggro);
if(this.textureState>TEXTURE_STATES)
{
textureState = TEXTURE_STATES;
}
if (!this.worldObj.isRemote)
{
this.dataWatcher.updateObject(16, Byte.valueOf(this.textureState));
}
}
/**
@@ -233,29 +206,28 @@ public class MobMonolith extends EntityFlying implements IMob
*/
private void playSounds(EntityPlayer entityPlayer)
{
float aggroPercent = this.getAggroProgress();
if (this.soundTime <= 0)
float aggroPercent = (aggro/MAX_AGGRO);
if(this.soundTime<=0)
{
this.playSound(mod_pocketDim.modid + ":monk", 1F, 1F);
this.soundTime = 100;
this.playSound(mod_pocketDim.modid+":monk", 1F, 1F);
this.soundTime=100;
}
if ((aggroPercent > 0.70) && this.soundTime < 100)
if ((aggroPercent>.70)&&this.soundTime<100)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ, mod_pocketDim.modid + ":tearing", 1F, (float) (1 + this.rand.nextGaussian()));
this.soundTime = 100 + this.rand.nextInt(75);
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ,mod_pocketDim.modid+":tearing",1F, (float) (1+this.rand.nextGaussian()));
this.soundTime=100+this.rand.nextInt(75);
}
if ((aggroPercent > 0.80) && this.soundTime < 200)
if ((aggroPercent>.90)&&this.soundTime<200)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ, mod_pocketDim.modid + ":tearing", 7, 1F);
this.soundTime = 250;
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ,mod_pocketDim.modid+":tearing",7, 1F);
this.soundTime=250;
}
this.soundTime--;
}
private void spawnParticles(EntityPlayer player)
{
int count = 10 * aggro / MAX_AGGRO;
for (int i = 1; i < count; ++i)
for (int i = 1; i < (10*(aggro/MAX_AGGRO)); ++i)
{
player.worldObj.spawnParticle("portal", player.posX + (this.rand.nextDouble() - 0.5D) * this.width,
player.posY + this.rand.nextDouble() * player.height - 0.75D,
@@ -265,38 +237,43 @@ public class MobMonolith extends EntityFlying implements IMob
}
}
public float getAggroProgress()
@Override
public void faceEntity(Entity par1Entity, float par2, float par3)
{
return ((float) aggro) / MAX_AGGRO;
}
private void facePlayer(EntityPlayer player)
{
double d0 = player.posX - this.posX;
double d1 = player.posZ - this.posZ;
double d2 = (player.posY + player.getEyeHeight()) - (this.posY + this.getEyeHeight());
double d0 = par1Entity.posX - this.posX;
double d1 = par1Entity.posZ - this.posZ;
double d2 = (par1Entity.posY + par1Entity.getEyeHeight()) - (this.posY +this.getEyeHeight());
double d3 = MathHelper.sqrt_double(d0 * d0 + d1 * d1);
float f2 = (float)(Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
this.pitchLevel = (float) -((Math.atan(d2/d3) )* 180.0D / Math.PI);
this.pitchLevel = (float)-((Math.atan(d2/d3) )* 180.0D / Math.PI);
this.rotationYaw = f2;
this.rotationYawHead = f2;
this.renderYawOffset = this.rotationYaw;
this.rotationYawHead=f2;
this.renderYawOffset=this.rotationYaw;
}
@Override
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeEntityToNBT(par1NBTTagCompound);
par1NBTTagCompound.setFloat("soundTime", this.soundTime);
par1NBTTagCompound.setFloat("aggro", this.aggro);
par1NBTTagCompound.setInteger("aggroMax", this.aggroMax);
par1NBTTagCompound.setByte("textureState", this.textureState);
}
@Override
public void writeEntityToNBT(NBTTagCompound rootTag)
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeEntityToNBT(rootTag);
rootTag.setInteger("Aggro", this.aggro);
}
super.readEntityFromNBT(par1NBTTagCompound);
this.soundTime = par1NBTTagCompound.getFloat("soundTime");
@Override
public void readEntityFromNBT(NBTTagCompound rootTag)
{
super.readEntityFromNBT(rootTag);
// Load Monoliths with half aggro so they don't teleport players instantly
this.aggro = (short) (rootTag.getInteger("Aggro") / 2);
//make them load with half aggro so they dont instantly teleport players
this.aggro = par1NBTTagCompound.getFloat("aggro")/2;
this.aggroMax = par1NBTTagCompound.getInteger("aggroMax");
this.textureState = par1NBTTagCompound.getByte("textureState");
}
@Override
@@ -305,7 +282,7 @@ public class MobMonolith extends EntityFlying implements IMob
@SuppressWarnings("rawtypes")
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, AxisAlignedBB.getBoundingBox( this.posX-15, posY-4, this.posZ-15, this.posX+15, this.posY+15, this.posZ+15));
if (this.worldObj.provider.dimensionId == DDProperties.instance().LimboDimensionID)
if(this.worldObj.provider.dimensionId==DDProperties.instance().LimboDimensionID)
{
if(list.size()>0)
{
@@ -325,4 +302,9 @@ public class MobMonolith extends EntityFlying implements IMob
this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() &&
!this.worldObj.isAnyLiquid(this.boundingBox);
}
public DataWatcher getDataWatcher()
{
return this.dataWatcher;
}
}

View File

@@ -1,121 +1,56 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.PriorityQueue;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftRegenerator implements IRegularTickReceiver {
// Ranges of regeneration delays, in seconds
private static final int MIN_FAST_DELAY = 1;
private static final int MAX_FAST_DELAY = 3;
private static final int MIN_SLOW_DELAY = 5;
private static final int MAX_SLOW_DELAY = 15;
private static final int MIN_RESCHEDULE_DELAY = 4 * 60;
private static final int MAX_RESCHEDULE_DELAY = 6 * 60;
private static final int TICKS_PER_SECOND = 20;
private static final int RIFT_REGENERATION_INTERVAL = 1; // Check the regeneration queue every tick
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5;
private static Random random = new Random();
private long tickCount = 0;
private PriorityQueue<RiftTicket> ticketQueue;
private BlockRift blockRift;
public RiftRegenerator(IRegularTickSender sender, BlockRift blockRift)
public RiftRegenerator(IRegularTickSender sender)
{
this.ticketQueue = new PriorityQueue<RiftTicket>();
this.blockRift = blockRift;
sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false);
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
}
@Override
public void notifyTick()
{
processTicketQueue();
tickCount++;
regenerateRiftsInLoadedWorlds();
}
public void scheduleSlowRegeneration(DimLink link)
private static void regenerateRiftsInLoadedWorlds()
{
scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY);
// Regenerate rifts that have been replaced (not permanently removed) by players
// Only do this in dimensions that are currently loaded
List<Integer> loadedWorlds = (List<Integer>) Arrays.asList(DimensionManager.getIDs());
for (Integer dimensionID : loadedWorlds)
{
NewDimData dimension = PocketManager.getDimensionData(dimensionID);
if (dimension.linkCount() > 0)
{
World world = DimensionManager.getWorld(dimension.id());
if (world != null)
{
for (int count = 0; count < RIFTS_REGENERATED_PER_DIMENSION; count++)
{
DimLink link = dimension.getRandomLink();
Point4D source = link.source();
mod_pocketDim.blockRift.regenerateRift(world, source.getX(), source.getY(), source.getZ(), random);
}
}
}
}
}
public void scheduleSlowRegeneration(int x, int y, int z, World world)
{
scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_SLOW_DELAY, MAX_SLOW_DELAY);
}
public void scheduleFastRegeneration(int x, int y, int z, World world)
{
scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_FAST_DELAY, MAX_FAST_DELAY);
}
private void scheduleRegeneration(DimLink link, int minDelay, int maxDelay)
{
if (link != null)
{
int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND);
ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay));
}
}
private void processTicketQueue()
{
RiftTicket ticket;
while (!ticketQueue.isEmpty() && ticketQueue.peek().timestamp() <= tickCount)
{
ticket = ticketQueue.remove();
regenerateRift(ticket.location());
}
}
private void regenerateRift(Point4D location)
{
int x = location.getX();
int y = location.getY();
int z = location.getZ();
// Try to regenerate a rift, or possibly reschedule its regeneration.
// The world for the given location must be loaded.
World world = DimensionManager.getWorld(location.getDimension());
if (world == null)
return;
// There must be a link at the given location.
DimLink link = PocketManager.getLink(location);
if (link == null)
return;
// The chunk at the given location must be loaded.
// Note: ChunkProviderServer.chunkExists() returns whether a chunk is
// loaded, not whether it has already been created.
if (!world.getChunkProvider().chunkExists(x >> 4, z >> 4))
return;
// If the location is occupied by an immune DD block, then don't regenerate.
if (blockRift.isModBlockImmune(world, x, y, z))
return;
// If the location is occupied by an immune block, then reschedule.
if (blockRift.isBlockImmune(world, x, y, z))
{
scheduleRegeneration(link, MIN_RESCHEDULE_DELAY, MAX_RESCHEDULE_DELAY);
}
else
{
// All of the necessary conditions have been met. Restore the rift!
int blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, blockRift.blockID))
blockRift.dropWorldThread(blockID, world, x, y, z, random);
}
}
}

View File

@@ -1,40 +0,0 @@
package StevenDimDoors.mod_pocketDim.ticking;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftTicket implements Comparable<RiftTicket> {
private long timestamp;
private Point4D location;
public RiftTicket(Point4D location, long timestamp)
{
this.timestamp = timestamp;
this.location = location;
}
@Override
public int compareTo(RiftTicket other)
{
if (this.timestamp < other.timestamp)
{
return -1;
}
else if (this.timestamp > other.timestamp)
{
return 1;
}
return 0;
}
public long timestamp()
{
return timestamp;
}
public Point4D location()
{
return location;
}
}

Some files were not shown because too many files have changed in this diff Show More