Compare commits
120 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c7129914a | ||
|
|
60bc8090f2 | ||
|
|
20db828ac0 | ||
|
|
12a2a8eb0d | ||
|
|
e793493331 | ||
|
|
7f99801e1b | ||
|
|
8544aa17ee | ||
|
|
b20a0a74d2 | ||
|
|
fb1713ae0e | ||
|
|
eff7abcbbc | ||
|
|
2c7435585d | ||
|
|
349f162a7c | ||
|
|
107aa4b7f2 | ||
|
|
1bf1f4f78c | ||
|
|
29c8a09218 | ||
|
|
71e7fdaafc | ||
|
|
1f59dc17d9 | ||
|
|
79bd5102ba | ||
|
|
b197237dfd | ||
|
|
85ff28298e | ||
|
|
782c6d5e50 | ||
|
|
c00c65eeee | ||
|
|
c22479c0e8 | ||
|
|
8da0339c78 | ||
|
|
83998969f6 | ||
|
|
c4abae8fdd | ||
|
|
1106319f8c | ||
|
|
2904ec146d | ||
|
|
7d840ff895 | ||
|
|
52bae00dc6 | ||
|
|
dc55359aaf | ||
|
|
58d5f6dd14 | ||
|
|
b40141f99d | ||
|
|
06cf72f9f7 | ||
|
|
100fa38c52 | ||
|
|
17a770eaf0 | ||
|
|
16f0a8303a | ||
|
|
1e3b32a15c | ||
|
|
4d53ae5f6a | ||
|
|
d3860119e9 | ||
|
|
f64768ed16 | ||
|
|
c1e58c25cc | ||
|
|
805e9dd040 | ||
|
|
972a67de76 | ||
|
|
592aabf627 | ||
|
|
b4a58f5c88 | ||
|
|
80bb87dac6 | ||
|
|
c5a77268fc | ||
|
|
262595ff4d | ||
|
|
c29db9b729 | ||
|
|
689df1ad6d | ||
|
|
ec290b0dc1 | ||
|
|
3d88e72ecb | ||
|
|
b2e086e7c1 | ||
|
|
e3665c09dd | ||
|
|
fb4643d7cf | ||
|
|
5ba58dc91b | ||
|
|
dea76b1a7e | ||
|
|
42568a1864 | ||
|
|
e40168954f | ||
|
|
59f335ac8c | ||
|
|
444b862b12 | ||
|
|
a0629b51a3 | ||
|
|
364ba11f81 | ||
|
|
96238d6b53 | ||
|
|
448890207f | ||
|
|
46f55b22d9 | ||
|
|
9baceb8e3c | ||
|
|
fe035f6677 | ||
|
|
4192270ef3 | ||
|
|
0029d9dac0 | ||
|
|
eff8379325 | ||
|
|
96d84ed2fa | ||
|
|
0f3d40ba60 | ||
|
|
794310bd98 | ||
|
|
a4d0f39390 | ||
|
|
e4e84644ac | ||
|
|
660ff4255e | ||
|
|
1410d4b251 | ||
|
|
161da193ad | ||
|
|
4d39d13703 | ||
|
|
18666f58b1 | ||
|
|
9e720cb458 | ||
|
|
968653e4ab | ||
|
|
eeb5f9aea1 | ||
|
|
117ed69bf7 | ||
|
|
0d53f6c029 | ||
|
|
dccb12116d | ||
|
|
e8fa928c50 | ||
|
|
f9331e4f2d | ||
|
|
7da3b7fc62 | ||
|
|
77241e6f90 | ||
|
|
844950b39e | ||
|
|
16d7bfcda6 | ||
|
|
d8fecd07b3 | ||
|
|
86cfcdeee8 | ||
|
|
3f6e32dcbf | ||
|
|
3fcc55b5e1 | ||
|
|
ef860e295e | ||
|
|
8f9dfea947 | ||
|
|
ac9b3d73e8 | ||
|
|
8d1028ccb5 | ||
|
|
d020dd384b | ||
|
|
8562456203 | ||
|
|
af77f8b2dc | ||
|
|
3a2c87cce9 | ||
|
|
03ab75b80c | ||
|
|
f4efa7dca2 | ||
|
|
79edf1004b | ||
|
|
aab818d948 | ||
|
|
68f2654000 | ||
|
|
f427e66f6e | ||
|
|
472704fe51 | ||
|
|
928adab4cf | ||
|
|
ef2e9cc561 | ||
|
|
7cabf75128 | ||
|
|
9003d924ea | ||
|
|
b15a8af299 | ||
|
|
19be17fa44 | ||
|
|
871d2ff1c2 |
15
build.gradle
15
build.gradle
@@ -13,14 +13,15 @@ buildscript {
|
||||
|
||||
apply plugin: 'forge'
|
||||
|
||||
|
||||
|
||||
version = "2.2.3-" + System.getenv("BUILD_NUMBER")
|
||||
group= "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
version = "2.2.4-" + 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'
|
||||
@@ -28,15 +29,15 @@ sourceCompatibility = '1.6'
|
||||
|
||||
processResources
|
||||
{
|
||||
// replace stuff in mcmod.info, nothing else
|
||||
// Replace stuff $version and $mcversion in mcmod.info
|
||||
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, thats not the mcmod.info
|
||||
// Copy everything else
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
}
|
||||
|
||||
@@ -165,8 +165,8 @@ public class DirectedGraph<U, V>
|
||||
{
|
||||
Edge<U, V> innerEdge = (Edge<U, V>) edge;
|
||||
|
||||
// Check that this edge actually belongs to this graph instance.
|
||||
// Accepting foreign edges could corrupt the graph's internal state.
|
||||
// Check that this node actually belongs to this graph instance.
|
||||
// Accepting foreign nodes could corrupt the graph's internal state.
|
||||
if (innerEdge.graphEntry.owner() != edges)
|
||||
{
|
||||
throw new IllegalArgumentException("The specified edge does not belong to this graph.");
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,215 +1,63 @@
|
||||
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, DDProperties properties)
|
||||
public static void generate(World world, int x, int y, int z, Random random)
|
||||
{
|
||||
// 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.getLayout(), world, offset);
|
||||
carveDoorways(design.getLayout(), world, offset, decay, random);
|
||||
buildRooms(design.getRoomGraph(), world, offset);
|
||||
carveDoorways(design.getRoomGraph(), world, offset, decay, random);
|
||||
|
||||
//placeDoors(design, world, offset);
|
||||
|
||||
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 = 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++;
|
||||
}
|
||||
}
|
||||
//final int DECAY_BOX_SIZE = 8
|
||||
}
|
||||
|
||||
private static boolean markDecayArea(int x, int y, int z, int DECAY_BOX_SIZE, PartitionNode<RoomData> root)
|
||||
private static void buildRooms(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world, Point3D offset)
|
||||
{
|
||||
// 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())
|
||||
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
|
||||
{
|
||||
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();
|
||||
PartitionNode room = node.data();
|
||||
buildBox(world, offset, room.minCorner(), room.maxCorner(), Block.stoneBrick.blockID, 0);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
private static void carveDoorways(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world,
|
||||
Point3D offset, SphereDecayOperation decay, Random random)
|
||||
{
|
||||
char axis;
|
||||
Point3D lower;
|
||||
DoorwayData doorway;
|
||||
|
||||
for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
|
||||
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
|
||||
{
|
||||
for (IEdge<RoomData, DoorwayData> passage : node.outbound())
|
||||
for (IEdge<PartitionNode, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,8 +68,6 @@ public class MazeBuilder
|
||||
final int MIN_DOUBLE_DOOR_SPAN = 10;
|
||||
|
||||
int gap;
|
||||
int rx;
|
||||
int rz;
|
||||
switch (axis)
|
||||
{
|
||||
case DoorwayData.X_AXIS:
|
||||
@@ -286,10 +132,9 @@ public class MazeBuilder
|
||||
{
|
||||
gap = 6;
|
||||
}
|
||||
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);
|
||||
decay.apply(world,
|
||||
x + random.nextInt(width - gap - 1) + 1, y - 1,
|
||||
z + random.nextInt(length - gap - 1) + 1, gap, 4, gap);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -321,18 +166,6 @@ 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)
|
||||
{
|
||||
@@ -356,15 +189,15 @@ public class MazeBuilder
|
||||
}
|
||||
for (x = minX; x <= maxX; x++)
|
||||
{
|
||||
for (y = minY + 1; y < maxY; y++)
|
||||
for (y = minY; y <= maxY; y++)
|
||||
{
|
||||
setBlockDirectly(world, x, y, minZ, blockID, metadata);
|
||||
setBlockDirectly(world, x, y, maxZ, blockID, metadata);
|
||||
}
|
||||
}
|
||||
for (z = minZ + 1; z < maxZ; z++)
|
||||
for (z = minZ; z <= maxZ; z++)
|
||||
{
|
||||
for (y = minY + 1; y < maxY; y++)
|
||||
for (y = minY; y <= maxY; y++)
|
||||
{
|
||||
setBlockDirectly(world, minX, y, z, blockID, metadata);
|
||||
setBlockDirectly(world, maxX, y, z, blockID, metadata);
|
||||
|
||||
@@ -4,23 +4,37 @@ import java.util.ArrayList;
|
||||
|
||||
public class MazeDesign
|
||||
{
|
||||
private PartitionNode<RoomData> root;
|
||||
private DirectedGraph<RoomData, DoorwayData> layout;
|
||||
private PartitionNode root;
|
||||
private DirectedGraph<PartitionNode, DoorwayData> rooms;
|
||||
private ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores;
|
||||
private ArrayList<BoundingBox> protectedAreas;
|
||||
|
||||
public MazeDesign(PartitionNode<RoomData> root, DirectedGraph<RoomData, DoorwayData> layout)
|
||||
public MazeDesign(PartitionNode root, DirectedGraph<PartitionNode, DoorwayData> rooms,
|
||||
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores)
|
||||
{
|
||||
this.root = root;
|
||||
this.layout = layout;
|
||||
this.rooms = rooms;
|
||||
this.cores = cores;
|
||||
}
|
||||
|
||||
public PartitionNode<RoomData> getRootPartition()
|
||||
public PartitionNode getRootPartition()
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
public DirectedGraph<RoomData, DoorwayData> getLayout()
|
||||
public DirectedGraph<PartitionNode, DoorwayData> getRoomGraph()
|
||||
{
|
||||
return layout;
|
||||
return rooms;
|
||||
}
|
||||
|
||||
public ArrayList<IGraphNode<PartitionNode, DoorwayData>> getCoreNodes()
|
||||
{
|
||||
return cores;
|
||||
}
|
||||
|
||||
public ArrayList<BoundingBox> getProtectedAreas()
|
||||
{
|
||||
return protectedAreas;
|
||||
}
|
||||
|
||||
public int width()
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package StevenDimDoors.experimental;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
@@ -26,46 +25,54 @@ public class MazeDesigner
|
||||
public static MazeDesign generate(Random random)
|
||||
{
|
||||
// Construct a random binary space partitioning of our maze volume
|
||||
PartitionNode<RoomData> root = partitionRooms(MAZE_WIDTH, MAZE_HEIGHT, MAZE_LENGTH, SPLIT_COUNT, random);
|
||||
PartitionNode root = partitionRooms(MAZE_WIDTH, MAZE_HEIGHT, MAZE_LENGTH, SPLIT_COUNT, random);
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
// 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<RoomData, DoorwayData> layout = createRoomGraph(root, rooms, random);
|
||||
DirectedGraph<PartitionNode, DoorwayData> rooms = createRoomGraph(root, partitions, random);
|
||||
|
||||
// Cut out random subgraphs from the adjacency graph
|
||||
ArrayList<RoomData> cores = createMazeSections(layout, random);
|
||||
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = createMazeSections(rooms, random);
|
||||
|
||||
// Remove unnecessary passages through floors/ceilings and some from the walls
|
||||
for (RoomData core : cores)
|
||||
for (IGraphNode<PartitionNode, DoorwayData> core : cores)
|
||||
{
|
||||
pruneDoorways(core.getLayoutNode(), layout, random);
|
||||
pruneDoorways(core, rooms, random);
|
||||
}
|
||||
|
||||
// Set up the placement of dimensional doors within the maze
|
||||
createMazeLinks(layout, cores, random);
|
||||
|
||||
return new MazeDesign(root, layout);
|
||||
return new MazeDesign(root, rooms, cores);
|
||||
}
|
||||
|
||||
private static void attachRooms(PartitionNode<RoomData> node, ArrayList<RoomData> partitions)
|
||||
private static void listRoomPartitions(PartitionNode node, ArrayList<PartitionNode> partitions)
|
||||
{
|
||||
if (node.isLeaf())
|
||||
{
|
||||
partitions.add(new RoomData(node));
|
||||
partitions.add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
attachRooms(node.leftChild(), partitions);
|
||||
attachRooms(node.rightChild(), partitions);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,25 +140,35 @@ public class MazeDesigner
|
||||
}
|
||||
}
|
||||
|
||||
private static DirectedGraph<RoomData, DoorwayData> createRoomGraph(PartitionNode<RoomData> root, ArrayList<RoomData> rooms, Random random)
|
||||
private static DirectedGraph<PartitionNode, DoorwayData> createRoomGraph(PartitionNode root, ArrayList<PartitionNode> partitions, Random random)
|
||||
{
|
||||
DirectedGraph<RoomData, DoorwayData> layout = new DirectedGraph<RoomData, DoorwayData>();
|
||||
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);
|
||||
|
||||
// Add all rooms to a graph
|
||||
for (RoomData room : rooms)
|
||||
// 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)
|
||||
{
|
||||
room.addToLayout(layout);
|
||||
}
|
||||
// Add edges for each room
|
||||
for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
|
||||
{
|
||||
findDoorways(node.data(), root, layout);
|
||||
}
|
||||
return layout;
|
||||
roomsToGraph.put(partition, roomGraph.addNode(partition));
|
||||
}
|
||||
|
||||
private static void findDoorways(RoomData room, PartitionNode<RoomData> root,
|
||||
DirectedGraph<RoomData, DoorwayData> layout)
|
||||
// Add edges for each room
|
||||
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
|
||||
{
|
||||
findDoorways(node, root, roomsToGraph, roomGraph);
|
||||
}
|
||||
|
||||
return roomGraph;
|
||||
}
|
||||
|
||||
private static void findDoorways(IGraphNode<PartitionNode, DoorwayData> roomNode, PartitionNode root,
|
||||
HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>> roomsToGraph,
|
||||
DirectedGraph<PartitionNode, DoorwayData> roomGraph)
|
||||
{
|
||||
// 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
|
||||
@@ -169,7 +186,7 @@ public class MazeDesigner
|
||||
// there will always be a way to walk from any room to any other room.
|
||||
|
||||
boolean[][] detected;
|
||||
PartitionNode<RoomData> adjacent;
|
||||
PartitionNode adjacent;
|
||||
|
||||
int a, b, c;
|
||||
int p, q, r;
|
||||
@@ -178,10 +195,11 @@ public class MazeDesigner
|
||||
Point3D otherMin;
|
||||
Point3D otherMax;
|
||||
DoorwayData doorway;
|
||||
IGraphNode<PartitionNode, DoorwayData> adjacentNode;
|
||||
|
||||
PartitionNode partition = room.getPartitionNode();
|
||||
Point3D minCorner = partition.minCorner();
|
||||
Point3D maxCorner = partition.maxCorner();
|
||||
PartitionNode room = roomNode.data();
|
||||
Point3D minCorner = room.minCorner();
|
||||
Point3D maxCorner = room.maxCorner();
|
||||
|
||||
int minX = minCorner.getX();
|
||||
int minY = minCorner.getY();
|
||||
@@ -191,9 +209,9 @@ public class MazeDesigner
|
||||
int maxY = maxCorner.getY();
|
||||
int maxZ = maxCorner.getZ();
|
||||
|
||||
int width = partition.width();
|
||||
int height = partition.height();
|
||||
int length = partition.length();
|
||||
int width = room.width();
|
||||
int height = room.height();
|
||||
int length = room.length();
|
||||
|
||||
if (maxZ < root.maxCorner().getZ())
|
||||
{
|
||||
@@ -229,7 +247,8 @@ public class MazeDesigner
|
||||
otherMin = new Point3D(minXI, minYI, maxZ);
|
||||
otherMax = new Point3D(maxXI, maxYI, maxZ + 1);
|
||||
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Z_AXIS);
|
||||
layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
|
||||
adjacentNode = roomsToGraph.get(adjacent);
|
||||
roomGraph.addEdge(roomNode, adjacentNode, doorway);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -276,7 +295,8 @@ public class MazeDesigner
|
||||
otherMin = new Point3D(maxX, minYI, minZI);
|
||||
otherMax = new Point3D(maxX + 1, maxYI, maxZI);
|
||||
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.X_AXIS);
|
||||
layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
|
||||
adjacentNode = roomsToGraph.get(adjacent);
|
||||
roomGraph.addEdge(roomNode, adjacentNode, doorway);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -323,7 +343,8 @@ public class MazeDesigner
|
||||
otherMin = new Point3D(minXI, maxY, minZI);
|
||||
otherMax = new Point3D(maxXI, maxY + 1, maxZI);
|
||||
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Y_AXIS);
|
||||
layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
|
||||
adjacentNode = roomsToGraph.get(adjacent);
|
||||
roomGraph.addEdge(roomNode, adjacentNode, doorway);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -338,130 +359,108 @@ public class MazeDesigner
|
||||
//Done!
|
||||
}
|
||||
|
||||
private static ArrayList<RoomData> createMazeSections(DirectedGraph<RoomData, DoorwayData> layout, Random random)
|
||||
private static ArrayList<IGraphNode<PartitionNode, DoorwayData>> createMazeSections(DirectedGraph<PartitionNode, DoorwayData> roomGraph, 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!
|
||||
|
||||
// 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 MAX_DISTANCE = 2;
|
||||
final int MIN_SECTION_ROOMS = 5;
|
||||
final int MIN_SECTION_CAPACITY = 2;
|
||||
|
||||
int distance;
|
||||
int capacity;
|
||||
RoomData room;
|
||||
RoomData neighbor;
|
||||
boolean hasHoles;
|
||||
IGraphNode<RoomData, DoorwayData> roomNode;
|
||||
IGraphNode<PartitionNode, DoorwayData> current;
|
||||
IGraphNode<PartitionNode, DoorwayData> neighbor;
|
||||
|
||||
ArrayList<RoomData> cores = new ArrayList<RoomData>();
|
||||
ArrayList<RoomData> section = new ArrayList<RoomData>();
|
||||
ArrayList<IGraphNode<RoomData, DoorwayData>> nodes = new ArrayList<IGraphNode<RoomData, DoorwayData>>(layout.nodeCount());
|
||||
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>>();
|
||||
|
||||
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);
|
||||
}
|
||||
Queue<IGraphNode<PartitionNode, DoorwayData>> ordering = new LinkedList<IGraphNode<PartitionNode, DoorwayData>>();
|
||||
HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer> distances = new HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer>();
|
||||
|
||||
// Repeatedly generate sections until all nodes have been visited
|
||||
for (IGraphNode<RoomData, DoorwayData> node : nodes)
|
||||
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
|
||||
{
|
||||
// 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)
|
||||
// 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))
|
||||
{
|
||||
// Perform a breadth-first search to tag surrounding nodes with distances
|
||||
ordering.add(room);
|
||||
room.setDistance(0);
|
||||
distances.put(node, 0);
|
||||
ordering.add(node);
|
||||
section.clear();
|
||||
capacity = 0;
|
||||
|
||||
while (room != null && (room.getDistance() <= MAX_DISTANCE || capacity < 2))
|
||||
{
|
||||
ordering.remove();
|
||||
section.add(room);
|
||||
roomNode = room.getLayoutNode();
|
||||
distance = room.getDistance() + 1;
|
||||
hasHoles = false;
|
||||
|
||||
// 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())
|
||||
{
|
||||
neighbor = edge.head().data();
|
||||
if (neighbor.getDistance() < 0)
|
||||
{
|
||||
neighbor.setDistance(distance);
|
||||
ordering.add(neighbor);
|
||||
}
|
||||
if (edge.data().axis() == DoorwayData.Y_AXIS)
|
||||
{
|
||||
hasHoles = true;
|
||||
}
|
||||
}
|
||||
for (IEdge<RoomData, DoorwayData> edge : roomNode.outbound())
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
// 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())
|
||||
{
|
||||
ordering.remove().remove();
|
||||
}
|
||||
current = ordering.remove();
|
||||
distance = distances.get(current) + 1;
|
||||
|
||||
// Check if this section contains enough rooms and capacity for doors
|
||||
if (section.size() >= MIN_SECTION_ROOMS && capacity >= MIN_SECTION_CAPACITY)
|
||||
if (distance <= MAX_DISTANCE + 1)
|
||||
{
|
||||
cores.add(node.data());
|
||||
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();
|
||||
if (!distances.containsKey(neighbor))
|
||||
{
|
||||
distances.put(neighbor, distance);
|
||||
ordering.add(neighbor);
|
||||
}
|
||||
}
|
||||
for (IEdge<PartitionNode, DoorwayData> edge : current.outbound())
|
||||
{
|
||||
neighbor = edge.tail();
|
||||
if (!distances.containsKey(neighbor))
|
||||
{
|
||||
distances.put(neighbor, distance);
|
||||
ordering.add(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Discard the whole section
|
||||
for (RoomData target : section)
|
||||
removals.add(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
while (!ordering.isEmpty())
|
||||
{
|
||||
target.remove();
|
||||
removals.add(ordering.remove());
|
||||
}
|
||||
|
||||
// Check if this section contains enough rooms
|
||||
if (section.size() >= MIN_SECTION_ROOMS)
|
||||
{
|
||||
cores.add(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
removals.addAll(section);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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<RoomData, DoorwayData> core,
|
||||
DirectedGraph<RoomData, DoorwayData> layout, Random random)
|
||||
private static void pruneDoorways(IGraphNode<PartitionNode, DoorwayData> core,
|
||||
DirectedGraph<PartitionNode, DoorwayData> rooms, 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
|
||||
@@ -479,12 +478,12 @@ public class MazeDesigner
|
||||
// idea applies for the other doorways, plus some randomness.
|
||||
|
||||
// First, list all nodes in the subgraph
|
||||
IGraphNode<RoomData, DoorwayData> current;
|
||||
IGraphNode<RoomData, DoorwayData> neighbor;
|
||||
IGraphNode<PartitionNode, DoorwayData> current;
|
||||
IGraphNode<PartitionNode, DoorwayData> neighbor;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
ordering.add(core);
|
||||
components.makeSet(core);
|
||||
@@ -493,7 +492,7 @@ public class MazeDesigner
|
||||
current = ordering.pop();
|
||||
subgraph.add(current);
|
||||
|
||||
for (IEdge<RoomData, DoorwayData> edge : current.inbound())
|
||||
for (IEdge<PartitionNode, DoorwayData> edge : current.inbound())
|
||||
{
|
||||
neighbor = edge.head();
|
||||
if (components.makeSet(neighbor))
|
||||
@@ -501,7 +500,7 @@ public class MazeDesigner
|
||||
ordering.add(neighbor);
|
||||
}
|
||||
}
|
||||
for (IEdge<RoomData, DoorwayData> edge : current.outbound())
|
||||
for (IEdge<PartitionNode, DoorwayData> edge : current.outbound())
|
||||
{
|
||||
neighbor = edge.tail();
|
||||
if (components.makeSet(neighbor))
|
||||
@@ -511,17 +510,15 @@ public class MazeDesigner
|
||||
}
|
||||
}
|
||||
|
||||
// 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>>();
|
||||
// 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>>();
|
||||
|
||||
for (IGraphNode<RoomData, DoorwayData> room : subgraph)
|
||||
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
|
||||
{
|
||||
for (IEdge<RoomData, DoorwayData> passage : room.outbound())
|
||||
for (IEdge<PartitionNode, DoorwayData> passage : room.outbound())
|
||||
{
|
||||
if (passage.data().axis() != DoorwayData.Y_AXIS)
|
||||
{
|
||||
@@ -538,12 +535,11 @@ public class MazeDesigner
|
||||
Collections.shuffle(targets, random);
|
||||
|
||||
// Merge sets together and remove unnecessary doorways
|
||||
for (IEdge<RoomData, DoorwayData> passage : targets)
|
||||
for (IEdge<PartitionNode, DoorwayData> passage : targets)
|
||||
{
|
||||
if (!components.mergeSets(passage.head(), passage.tail()))
|
||||
{
|
||||
layout.removeEdge(passage);
|
||||
|
||||
rooms.removeEdge(passage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,13 +548,13 @@ public class MazeDesigner
|
||||
components.clear();
|
||||
targets.clear();
|
||||
|
||||
for (IGraphNode<RoomData, DoorwayData> room : subgraph)
|
||||
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
|
||||
{
|
||||
components.makeSet(room);
|
||||
}
|
||||
for (IGraphNode<RoomData, DoorwayData> room : subgraph)
|
||||
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
|
||||
{
|
||||
for (IEdge<RoomData, DoorwayData> passage : room.outbound())
|
||||
for (IEdge<PartitionNode, DoorwayData> passage : room.outbound())
|
||||
{
|
||||
if (passage.data().axis() == DoorwayData.Y_AXIS)
|
||||
{
|
||||
@@ -571,198 +567,13 @@ public class MazeDesigner
|
||||
}
|
||||
}
|
||||
Collections.shuffle(targets, random);
|
||||
for (IEdge<RoomData, DoorwayData> passage : targets)
|
||||
for (IEdge<PartitionNode, DoorwayData> passage : targets)
|
||||
{
|
||||
if (!components.mergeSets(passage.head(), passage.tail()) && random.nextBoolean())
|
||||
{
|
||||
layout.removeEdge(passage);
|
||||
rooms.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.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,11 @@ package StevenDimDoors.experimental;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||
|
||||
public class PartitionNode<T> extends BoundingBox
|
||||
public class PartitionNode 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)
|
||||
{
|
||||
@@ -123,14 +122,4 @@ public class PartitionNode<T> extends BoundingBox
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public void setData(T value)
|
||||
{
|
||||
this.data = value;
|
||||
}
|
||||
|
||||
public T getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
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;
|
||||
@@ -130,6 +133,20 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,17 +1,11 @@
|
||||
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;
|
||||
@@ -65,7 +59,8 @@ public class ConnectionHandler implements IConnectionHandler
|
||||
@Override
|
||||
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
|
||||
{
|
||||
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(0)));
|
||||
// Hax... please don't do this! >_<
|
||||
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionDataDangerously(0)));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,23 @@
|
||||
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
|
||||
public class CraftingManager implements ICraftingHandler
|
||||
{
|
||||
private CraftingManager() { }
|
||||
CraftingManager() { }
|
||||
|
||||
public static void registerRecipes(DDProperties properties)
|
||||
{
|
||||
@@ -18,19 +26,19 @@ public class CraftingManager
|
||||
switch (properties.WorldThreadRequirementLevel)
|
||||
{
|
||||
case 1:
|
||||
GameRegistry.addShapelessRecipe(new ItemStack(itemStableFabric, 1),
|
||||
GameRegistry.addShapelessRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
|
||||
Item.enderPearl, mod_pocketDim.itemWorldThread);
|
||||
break;
|
||||
case 2:
|
||||
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
|
||||
"yxy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
|
||||
break;
|
||||
case 3:
|
||||
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
|
||||
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
|
||||
break;
|
||||
default:
|
||||
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
|
||||
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
|
||||
break;
|
||||
}
|
||||
@@ -38,54 +46,125 @@ public class CraftingManager
|
||||
|
||||
if (properties.CraftingDimensionalDoorAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(itemDimensionalDoor, 1),
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDimensionalDoor, 1),
|
||||
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorIron);
|
||||
}
|
||||
if (properties.CraftingUnstableDoorAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(itemUnstableDoor, 1),
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemUnstableDoor, 1),
|
||||
"yxy", 'x', Item.eyeOfEnder, 'y', mod_pocketDim.itemDimensionalDoor);
|
||||
}
|
||||
if (properties.CraftingWarpDoorAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(itemWarpDoor, 1),
|
||||
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorWood);
|
||||
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemWarpDoor, 1),
|
||||
"yxy", 'x', Item.enderPearl, 'y', Item.doorWood);
|
||||
}
|
||||
if (properties.CraftingTransTrapdoorAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(transTrapdoor, 1),
|
||||
"y", "x", "y", 'x', mod_pocketDim.itemStableFabric, 'y', Block.trapdoor);
|
||||
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.transTrapdoor, 1),
|
||||
"y", "x", "y", 'x', Item.enderPearl, 'y', Block.trapdoor);
|
||||
}
|
||||
if (properties.CraftingRiftSignatureAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(itemRiftSignature, 1),
|
||||
" y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron);
|
||||
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftSignature, 1),
|
||||
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', Item.ingotIron);
|
||||
}
|
||||
if (properties.CraftingRiftRemoverAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(itemRiftRemover, 1),
|
||||
"yyy", "yxy", "yyy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotGold);
|
||||
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftRemover, 1),
|
||||
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', Item.ingotGold);
|
||||
}
|
||||
if (properties.CraftingRiftBladeAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(itemRiftBlade, 1),
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftBlade, 1),
|
||||
"x", "x", "y", 'x', mod_pocketDim.itemStableFabric, 'y', Item.blazeRod);
|
||||
}
|
||||
if (properties.CraftingStabilizedRiftSignatureAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedLinkSignature,1),
|
||||
" y ", "yxy", " y ", 'x', mod_pocketDim.itemRiftSignature, 'y', mod_pocketDim.itemStableFabric);
|
||||
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedRiftSignature, 1),
|
||||
" y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron);
|
||||
}
|
||||
if (properties.CraftingGoldenDimensionalDoorAllowed)
|
||||
{
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor,1),
|
||||
"yxy", 'x', mod_pocketDim.itemGoldenDoor, 'y', mod_pocketDim.itemStableFabric);
|
||||
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor, 1),
|
||||
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', mod_pocketDim.itemGoldenDoor);
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
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.ChunkCoordinates;
|
||||
import net.minecraft.util.DamageSource;
|
||||
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;
|
||||
@@ -19,12 +18,18 @@ 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;
|
||||
@@ -34,13 +39,26 @@ 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)
|
||||
{
|
||||
@@ -59,6 +77,10 @@ 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");
|
||||
@@ -75,7 +97,6 @@ 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);
|
||||
}
|
||||
@@ -85,21 +106,33 @@ 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 && stack.getItem() instanceof ItemDoor)
|
||||
if (stack != null)
|
||||
{
|
||||
if (mod_pocketDim.itemDimensionalDoor.tryToPlaceDoor(stack, event.entityPlayer, world,
|
||||
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,
|
||||
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
|
||||
@@ -137,7 +170,9 @@ public class EventHookContainer
|
||||
Entity entity = event.entity;
|
||||
|
||||
if (properties.LimboEnabled && properties.LimboReturnsInventoryEnabled &&
|
||||
entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider)
|
||||
entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
|
||||
{
|
||||
if(entity.worldObj.provider instanceof PocketProvider)
|
||||
{
|
||||
EntityPlayer player = (EntityPlayer) entity;
|
||||
mod_pocketDim.deathTracker.addUsername(player.username);
|
||||
@@ -145,6 +180,15 @@ public class EventHookContainer
|
||||
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;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -159,7 +203,7 @@ public class EventHookContainer
|
||||
|
||||
Entity entity = event.entity;
|
||||
|
||||
if (entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider)
|
||||
if (entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
|
||||
{
|
||||
EntityPlayer player = (EntityPlayer) entity;
|
||||
mod_pocketDim.deathTracker.addUsername(player.username);
|
||||
@@ -175,11 +219,23 @@ 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);
|
||||
}
|
||||
@@ -198,6 +254,25 @@ 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)
|
||||
|
||||
@@ -4,5 +4,6 @@ import net.minecraftforge.common.ForgeChunkManager.Ticket;
|
||||
|
||||
public interface IChunkLoader
|
||||
{
|
||||
public void forceChunkLoading(Ticket ticket,int x, int z);
|
||||
public boolean isInitialized();
|
||||
public void initialize(Ticket ticket);
|
||||
}
|
||||
|
||||
@@ -12,5 +12,6 @@ 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -56,20 +56,6 @@ 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()
|
||||
{
|
||||
|
||||
@@ -39,6 +39,13 @@ 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>
|
||||
@@ -54,6 +61,12 @@ 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)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package StevenDimDoors.mod_pocketDim.blocks;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
import net.minecraft.block.ITileEntityProvider;
|
||||
@@ -11,7 +10,8 @@ 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.Item;
|
||||
import net.minecraft.item.ItemDoor;
|
||||
import net.minecraft.item.ItemStack;
|
||||
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.schematic.BlockRotator;
|
||||
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
|
||||
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)
|
||||
private Icon[] upperTextures;
|
||||
protected Icon[] upperTextures;
|
||||
@SideOnly(Side.CLIENT)
|
||||
private Icon[] lowerTextures;
|
||||
protected Icon[] lowerTextures;
|
||||
|
||||
public BaseDimDoor(int blockID, Material material, DDProperties properties)
|
||||
{
|
||||
@@ -74,6 +74,18 @@ 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);
|
||||
@@ -92,6 +104,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
|
||||
}
|
||||
|
||||
world.playAuxSFXAtEntity(player, MAGIC_CONSTANT, x, y, z, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -159,28 +172,26 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
|
||||
reversed = !reversed;
|
||||
}
|
||||
}
|
||||
|
||||
if (isUpperDoorBlock(fullMetadata))
|
||||
{
|
||||
return this.upperTextures[reversed ? 1 : 0];
|
||||
else
|
||||
}
|
||||
return this.lowerTextures[reversed ? 1 : 0];
|
||||
}
|
||||
else
|
||||
{
|
||||
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 = this.isDoorOnRift(world, x, y, z)&&this.isUpperDoorBlock(metadata);
|
||||
dimTile.openOrClosed = isDoorOnRift(world, x, y, z) && isUpperDoorBlock(metadata);
|
||||
dimTile.orientation = this.getFullMetadata(world, x, y, z) & 7;
|
||||
}
|
||||
return this;
|
||||
@@ -188,21 +199,34 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
|
||||
|
||||
public boolean isDoorOnRift(World world, int x, int y, int z)
|
||||
{
|
||||
if(this.isUpperDoorBlock( world.getBlockMetadata(x, y, z)))
|
||||
return this.getLink(world, x, y, z) != null;
|
||||
}
|
||||
|
||||
public DimLink getLink(World world, int x, int y, int z)
|
||||
{
|
||||
if(PocketManager.getLink(x, y, z, world.provider.dimensionId) != null||PocketManager.getLink(x, y-1, z, world.provider.dimensionId) != null)
|
||||
DimLink link= PocketManager.getLink(x, y, z, world.provider.dimensionId);
|
||||
if(link!=null)
|
||||
{
|
||||
return true;
|
||||
return link;
|
||||
}
|
||||
|
||||
if(isUpperDoorBlock( world.getBlockMetadata(x, y, z)))
|
||||
{
|
||||
link = PocketManager.getLink(x, y-1, z, world.provider.dimensionId);
|
||||
if(link!=null)
|
||||
{
|
||||
return link;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(PocketManager.getLink(x, y, z, world.provider.dimensionId) != null||PocketManager.getLink(x, y+1, z, world.provider.dimensionId) != null)
|
||||
link = PocketManager.getLink(x, y+1, z, world.provider.dimensionId);
|
||||
if(link != null)
|
||||
{
|
||||
return true;
|
||||
return link;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,14 +336,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.setBlock(x, y, z, 0);
|
||||
world.setBlockToAir(x, y, z);
|
||||
}
|
||||
|
||||
if (neighborID > 0 && neighborID != this.blockID)
|
||||
{
|
||||
this.onNeighborBlockChange(world, x, y - 1, z, neighborID);
|
||||
@@ -329,13 +353,13 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
|
||||
{
|
||||
if (world.getBlockId(x, y + 1, z) != this.blockID)
|
||||
{
|
||||
world.setBlock(x, y, z, 0);
|
||||
world.setBlockToAir(x, y, z);
|
||||
if (!world.isRemote)
|
||||
{
|
||||
this.dropBlockAsItem(world, x, y, z, metadata, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(this.getLockStatus(world, x, y, z)<=1)
|
||||
{
|
||||
boolean powered = world.isBlockIndirectlyGettingPowered(x, y, z) || world.isBlockIndirectlyGettingPowered(x, y + 1, z);
|
||||
if ((powered || neighborID > 0 && Block.blocksList[neighborID].canProvidePower()) && neighborID != this.blockID)
|
||||
@@ -351,31 +375,20 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
|
||||
*/
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public int idPicked(World par1World, int par2, int par3, int par4)
|
||||
public int idPicked(World world, int x, int y, int z)
|
||||
{
|
||||
return this.getDrops();
|
||||
return this.getDoorItem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the items to drop on destruction.
|
||||
*/
|
||||
@Override
|
||||
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)
|
||||
{
|
||||
@@ -429,16 +442,77 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isUpperDoorBlock(int metadata)
|
||||
public boolean isUpperDoorBlock(int metadata)
|
||||
{
|
||||
return (metadata & 8) != 0;
|
||||
}
|
||||
|
||||
public static boolean isDoorOpen(int metadata)
|
||||
public 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,
|
||||
@@ -455,4 +529,18 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,10 @@ 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;
|
||||
|
||||
@@ -23,7 +25,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[2];
|
||||
private Icon[] blockIcon = new Icon[3];
|
||||
|
||||
public BlockDimWall(int blockID, int j, Material par2Material)
|
||||
{
|
||||
@@ -34,7 +36,7 @@ public class BlockDimWall extends Block
|
||||
@Override
|
||||
public float getBlockHardness(World world, int x, int y, int z)
|
||||
{
|
||||
if (world.getBlockMetadata(x, y, z) == 0)
|
||||
if (world.getBlockMetadata(x, y, z) != 1)
|
||||
{
|
||||
return this.blockHardness;
|
||||
}
|
||||
@@ -47,7 +49,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) == 0)
|
||||
if (world.getBlockMetadata(x, y, z) != 1)
|
||||
{
|
||||
return super.getExplosionResistance(entity, world, x, y, z, explosionX, explosionY, explosionZ);
|
||||
}
|
||||
@@ -57,25 +59,41 @@ 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)
|
||||
{
|
||||
return (par2 != 1) ? blockIcon[0] : blockIcon[1];
|
||||
switch(par2)
|
||||
{
|
||||
case 0:
|
||||
return blockIcon[0];
|
||||
case 1:
|
||||
return blockIcon[1];
|
||||
case 2:
|
||||
return blockIcon[2];
|
||||
default:
|
||||
return blockIcon[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(int metadata)
|
||||
{
|
||||
//Return 0 to avoid dropping Ancient Fabric even if the player somehow manages to break it
|
||||
return 0;
|
||||
return metadata == 1 ? 0 : metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,11 +101,12 @@ public class BlockDimWall extends Block
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void getSubBlocks(int unknown, CreativeTabs tab, List subItems)
|
||||
{
|
||||
for (int ix = 0; ix < 2; ix++)
|
||||
for (int ix = 0; ix < 3; ix++)
|
||||
{
|
||||
subItems.add(new ItemStack(this, 1, ix));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {}
|
||||
|
||||
@@ -110,7 +129,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) == 0)
|
||||
if (entityPlayer.getCurrentEquippedItem() != null && world.getBlockMetadata(x, y, z) != 1)
|
||||
{
|
||||
Item playerEquip = entityPlayer.getCurrentEquippedItem().getItem();
|
||||
|
||||
|
||||
@@ -2,123 +2,34 @@ 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons(IconRegister iconRegister)
|
||||
protected String getTextureName()
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold;
|
||||
@@ -25,15 +25,21 @@ public class BlockGoldDimDoor extends BaseDimDoor
|
||||
{
|
||||
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
|
||||
{
|
||||
NewDimData dimension = PocketManager.getDimensionData(world);
|
||||
NewDimData dimension = PocketManager.createDimensionData(world);
|
||||
DimLink link = dimension.getLink(x, y, z);
|
||||
if (link == null)
|
||||
{
|
||||
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z));
|
||||
dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDoorItem()
|
||||
{
|
||||
return mod_pocketDim.itemGoldenDimensionalDoor.itemID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrops()
|
||||
{
|
||||
|
||||
@@ -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.ticking.LimboDecay;
|
||||
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
|
||||
@@ -47,14 +47,28 @@ 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;
|
||||
private final ArrayList<Integer> blocksImmuneToRift; // List of Vanilla blocks immune to rifts
|
||||
private final ArrayList<Integer> modBlocksImmuneToRift; // List of DD blocks immune to rifts
|
||||
|
||||
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);
|
||||
@@ -65,7 +79,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);
|
||||
@@ -85,9 +99,6 @@ 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()
|
||||
{
|
||||
@@ -113,10 +124,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;
|
||||
@@ -220,7 +231,7 @@ public class BlockRift extends Block implements ITileEntityProvider
|
||||
return targets;
|
||||
}
|
||||
|
||||
private void dropWorldThread(int blockID, World world, int x, int y, int z, Random random)
|
||||
public 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 ||
|
||||
@@ -232,7 +243,7 @@ public class BlockRift extends Block implements ITileEntityProvider
|
||||
}
|
||||
}
|
||||
|
||||
private void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points)
|
||||
private static 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),
|
||||
@@ -252,16 +263,6 @@ 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;
|
||||
@@ -413,6 +414,15 @@ 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)];
|
||||
@@ -424,7 +434,21 @@ 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 || blocksImmuneToRift.contains(block.blockID));
|
||||
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 false;
|
||||
}
|
||||
@@ -446,4 +470,18 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,15 @@ 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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
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);
|
||||
@@ -23,14 +22,21 @@ public class DimensionalDoor extends BaseDimDoor
|
||||
{
|
||||
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
|
||||
{
|
||||
NewDimData dimension = PocketManager.getDimensionData(world);
|
||||
NewDimData dimension = PocketManager.createDimensionData(world);
|
||||
DimLink link = dimension.getLink(x, y, z);
|
||||
if (link == null)
|
||||
{
|
||||
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z));
|
||||
dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDoorItem()
|
||||
{
|
||||
return mod_pocketDim.itemDimensionalDoor.itemID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrops()
|
||||
{
|
||||
|
||||
@@ -6,11 +6,39 @@ 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);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,23 +2,28 @@ 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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
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
|
||||
{
|
||||
|
||||
@@ -41,18 +46,66 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,14 +114,6 @@ 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
|
||||
@@ -77,35 +122,37 @@ 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.getDimensionData(world);
|
||||
NewDimData dimension = PocketManager.createDimensionData(world);
|
||||
DimLink link = dimension.getLink(x, y, z);
|
||||
if (link == null && dimension.isPocketDimension())
|
||||
{
|
||||
dimension.createLink(x, y, z, LinkTypes.UNSAFE_EXIT,0);
|
||||
dimension.createLink(x, y, z, LinkType.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 getDrops();
|
||||
return this.getDrops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDoorItem()
|
||||
{
|
||||
return mod_pocketDim.transTrapdoor.blockID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,4 +173,24 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
|
||||
@@ -64,15 +64,21 @@ public class TransientDoor extends BaseDimDoor
|
||||
{
|
||||
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
|
||||
{
|
||||
NewDimData dimension = PocketManager.getDimensionData(world);
|
||||
NewDimData dimension = PocketManager.createDimensionData(world);
|
||||
DimLink link = dimension.getLink(x, y, z);
|
||||
if (link == null && dimension.isPocketDimension())
|
||||
{
|
||||
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
|
||||
dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDoorItem()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrops()
|
||||
{
|
||||
|
||||
@@ -3,8 +3,9 @@ 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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
|
||||
@@ -21,9 +22,16 @@ 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, LinkTypes.RANDOM,world.getBlockMetadata(x, y - 1, z));
|
||||
dimension.createLink(x, y, z, LinkType.RANDOM,world.getBlockMetadata(x, y - 1, z));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDoorItem()
|
||||
{
|
||||
return mod_pocketDim.itemUnstableDoor.itemID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrops()
|
||||
{
|
||||
|
||||
@@ -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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
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,15 +22,21 @@ public class WarpDoor extends BaseDimDoor
|
||||
{
|
||||
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
|
||||
{
|
||||
NewDimData dimension = PocketManager.getDimensionData(world);
|
||||
NewDimData dimension = PocketManager.createDimensionData(world);
|
||||
DimLink link = dimension.getLink(x, y, z);
|
||||
if (link == null && dimension.isPocketDimension())
|
||||
{
|
||||
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
|
||||
dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDoorItem()
|
||||
{
|
||||
return mod_pocketDim.itemWarpDoor.itemID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrops()
|
||||
{
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
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;
|
||||
@@ -38,10 +36,6 @@ 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;
|
||||
@@ -68,7 +62,8 @@ public class CommandCreateDungeonRift extends DDCommandBase
|
||||
if (result != null)
|
||||
{
|
||||
dimension = PocketManager.getDimensionData(sender.worldObj);
|
||||
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
|
||||
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
|
||||
|
||||
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
|
||||
{
|
||||
// Create a rift to our selected dungeon and notify the player
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package StevenDimDoors.mod_pocketDim.commands;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
|
||||
|
||||
@@ -23,11 +22,6 @@ public class CommandCreatePocket extends DDCommandBase
|
||||
|
||||
@Override
|
||||
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
|
||||
{
|
||||
//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)
|
||||
{
|
||||
if (command.length > 0)
|
||||
{
|
||||
@@ -42,8 +36,8 @@ public class CommandCreatePocket extends DDCommandBase
|
||||
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."));
|
||||
}
|
||||
sendChat(sender, "Created a door to a pocket dimension. Please build your dungeon there.");
|
||||
|
||||
return DDCommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
||||
@@ -39,10 +39,6 @@ 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;
|
||||
@@ -58,7 +54,8 @@ public class CommandCreateRandomRift extends DDCommandBase
|
||||
if (command.length == 0)
|
||||
{
|
||||
dimension = PocketManager.getDimensionData(sender.worldObj);
|
||||
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
|
||||
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
|
||||
|
||||
sender.worldObj.setBlock(x, y + 1, z,mod_pocketDim.blockRift.blockID, 0, 3);
|
||||
sendChat(sender, "Created a rift to a random dungeon.");
|
||||
}
|
||||
@@ -74,7 +71,8 @@ public class CommandCreateRandomRift extends DDCommandBase
|
||||
if (result != null)
|
||||
{
|
||||
dimension = PocketManager.getDimensionData(sender.worldObj);
|
||||
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
|
||||
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
|
||||
|
||||
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
|
||||
{
|
||||
// Create a rift to our selected dungeon and notify the player
|
||||
@@ -118,9 +116,6 @@ public class CommandCreateRandomRift extends DDCommandBase
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return matches.get( random.nextInt(matches.size()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,21 @@ 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-???", "???");
|
||||
super("dd-deleterifts", "[dimension number]");
|
||||
}
|
||||
|
||||
public static CommandDeleteRifts instance()
|
||||
@@ -31,47 +30,64 @@ public class CommandDeleteRifts extends DDCommandBase
|
||||
@Override
|
||||
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
|
||||
{
|
||||
int linksRemoved=0;
|
||||
int targetDim;
|
||||
boolean shouldGo= true;
|
||||
int linksRemoved = 0;
|
||||
int targetDimension;
|
||||
|
||||
if(command.length==1)
|
||||
if (command.length > 1)
|
||||
{
|
||||
targetDim = parseInt(sender, command[0]);
|
||||
return DDCommandResult.TOO_MANY_ARGUMENTS;
|
||||
}
|
||||
if (command.length == 0)
|
||||
{
|
||||
targetDimension = sender.worldObj.provider.dimensionId;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetDim=0;
|
||||
shouldGo=false;
|
||||
sendChat(sender,("Error-Invalid argument, delete_all_links <targetDimID>"));
|
||||
try
|
||||
{
|
||||
targetDimension = Integer.parseInt(command[0]);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return DDCommandResult.INVALID_DIMENSION_ID;
|
||||
}
|
||||
}
|
||||
|
||||
if(shouldGo)
|
||||
World world = PocketManager.loadDimension(targetDimension);
|
||||
if (world == null)
|
||||
{
|
||||
return DDCommandResult.UNREGISTERED_DIMENSION;
|
||||
}
|
||||
|
||||
NewDimData dim = PocketManager.getDimensionData(targetDim);
|
||||
ArrayList<DimLink> linksInDim = dim.getAllLinks();
|
||||
|
||||
for (DimLink link : linksInDim)
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
Point4D location;
|
||||
NewDimData dimension = PocketManager.createDimensionData(world);
|
||||
ArrayList<DimLink> links = dimension.getAllLinks();
|
||||
for (DimLink link : links)
|
||||
{
|
||||
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))
|
||||
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++;
|
||||
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.
|
||||
|
||||
|
||||
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++;
|
||||
}
|
||||
sendChat(sender,("Removed " + linksRemoved + " links."));
|
||||
|
||||
}
|
||||
return DDCommandResult.SUCCESS; //TEMPORARY HACK
|
||||
sendChat(sender, "Removed " + linksRemoved + " links.");
|
||||
return DDCommandResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ 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;
|
||||
@@ -60,25 +59,15 @@ public class CommandExportDungeon extends DDCommandBase
|
||||
//Export the schematic
|
||||
return exportDungeon(sender, command[0]);
|
||||
}
|
||||
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 user must have used the 3-argument version of this command
|
||||
//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
|
||||
|
||||
@@ -100,8 +89,7 @@ public class CommandExportDungeon extends DDCommandBase
|
||||
{
|
||||
return exportDungeon(sender, join(command, "_", 0, 3));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//Validate the weight argument
|
||||
try
|
||||
{
|
||||
@@ -112,16 +100,12 @@ public class CommandExportDungeon extends DDCommandBase
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
DDProperties properties = DDProperties.instance();
|
||||
@@ -137,11 +121,8 @@ public class CommandExportDungeon extends DDCommandBase
|
||||
dungeonHelper.registerDungeon(exportPath, dungeonHelper.getDungeonPack("ruins"), false, true);
|
||||
return DDCommandResult.SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DDCommandResult("Error: Failed to save dungeon schematic!");
|
||||
}
|
||||
}
|
||||
|
||||
private static String join(String[] source, String delimiter, int start, int end)
|
||||
{
|
||||
|
||||
@@ -31,10 +31,6 @@ 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;
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package StevenDimDoors.mod_pocketDim.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import java.util.HashSet;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import StevenDimDoors.mod_pocketDim.core.DimLink;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.DimensionType;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class CommandResetDungeons extends DDCommandBase
|
||||
{
|
||||
private static CommandResetDungeons instance = null;
|
||||
@@ -31,61 +29,78 @@ 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_FEW_ARGUMENTS;
|
||||
return DDCommandResult.TOO_MANY_ARGUMENTS;
|
||||
}
|
||||
|
||||
int dungeonCount = 0;
|
||||
int id;
|
||||
int resetCount = 0;
|
||||
ArrayList<Integer> dimsToDelete = new ArrayList<Integer>();
|
||||
ArrayList<Integer> dimsToFix = new ArrayList<Integer>();
|
||||
int dungeonCount = 0;
|
||||
HashSet<Integer> deletedDimensions = new HashSet<Integer>();
|
||||
ArrayList<NewDimData> loadedDungeons = new ArrayList<NewDimData>();
|
||||
|
||||
for (NewDimData data : PocketManager.getDimensions())
|
||||
// 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())
|
||||
{
|
||||
|
||||
if(DimensionManager.getWorld(data.id())==null&&data.isDungeon())
|
||||
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)
|
||||
{
|
||||
dungeonCount++;
|
||||
id = dimension.id();
|
||||
if (PocketManager.deletePocket(dimension, true))
|
||||
{
|
||||
resetCount++;
|
||||
dungeonCount++;
|
||||
dimsToDelete.add(data.id());
|
||||
deletedDimensions.add(id);
|
||||
}
|
||||
else if(data.isDungeon())
|
||||
else
|
||||
{
|
||||
dimsToFix.add(data.id());
|
||||
dungeonCount++;
|
||||
for(DimLink link : data.links())
|
||||
{
|
||||
if(link.linkType()==LinkTypes.REVERSE)
|
||||
{
|
||||
data.createLink(link.source(), LinkTypes.DUNGEON_EXIT, link.orientation());
|
||||
loadedDungeons.add(dimension);
|
||||
}
|
||||
if(link.linkType()==LinkTypes.DUNGEON)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Modify the loaded dungeons to prevent bugs
|
||||
for (NewDimData dungeon : loadedDungeons)
|
||||
{
|
||||
data.createLink(link.source(), LinkTypes.DUNGEON, link.orientation());
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Integer dimID:dimsToDelete)
|
||||
{
|
||||
PocketManager.deletePocket(PocketManager.getDimensionData(dimID), true);
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
// Notify the user of the results
|
||||
sendChat(sender,("Reset complete. " + resetCount + " out of " + dungeonCount + " dungeons were reset."));
|
||||
return DDCommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
@@ -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 ID> <X Coord> <Y Coord> <Z Coord>","<Player Name> <Dimension ID>"} );
|
||||
super("dd-tp", new String[] {
|
||||
"<player name> <dimension number>",
|
||||
"<player name> <x> <y> <z>",
|
||||
"<player name> <dimension number> <x> <y> <z>"} );
|
||||
}
|
||||
|
||||
public static CommandTeleportPlayer instance()
|
||||
@@ -28,110 +28,119 @@ 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)
|
||||
{
|
||||
EntityPlayer targetPlayer = sender;
|
||||
int dimDestinationID = sender.worldObj.provider.dimensionId;
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
World world;
|
||||
int dimensionID;
|
||||
Point4D destination;
|
||||
NewDimData dimension;
|
||||
boolean checkOrientation;
|
||||
EntityPlayer targetPlayer;
|
||||
|
||||
if(command.length == 5)
|
||||
if (command.length < 2)
|
||||
{
|
||||
for(int i= 1; i <5;i++)
|
||||
return DDCommandResult.TOO_FEW_ARGUMENTS;
|
||||
}
|
||||
if (command.length > 5)
|
||||
{
|
||||
if(!isInteger(command[i]))
|
||||
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]))
|
||||
{
|
||||
return DDCommandResult.INVALID_ARGUMENTS;
|
||||
}
|
||||
}
|
||||
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player
|
||||
// Check if the target player is logged in
|
||||
targetPlayer = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(command[0]);
|
||||
if (targetPlayer == null)
|
||||
{
|
||||
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]);
|
||||
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)
|
||||
{
|
||||
return DDCommandResult.UNREGISTERED_DIMENSION;
|
||||
}
|
||||
}
|
||||
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;
|
||||
dimensionID = targetPlayer.worldObj.provider.dimensionId;
|
||||
world = targetPlayer.worldObj;
|
||||
}
|
||||
|
||||
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 == 2 && isInteger(command[1]))
|
||||
// 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)
|
||||
{
|
||||
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player
|
||||
// Check if the destination is a pocket dimension
|
||||
dimension = PocketManager.createDimensionData(world);
|
||||
if (dimension.isPocketDimension())
|
||||
{
|
||||
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]);
|
||||
// The destination is a pocket dimension.
|
||||
// Teleport the player to its original entrance (the origin).
|
||||
destination = dimension.origin();
|
||||
checkOrientation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DDCommandResult.INVALID_ARGUMENTS;
|
||||
// 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);
|
||||
}
|
||||
dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string
|
||||
|
||||
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
|
||||
}
|
||||
else if (command.length == 4)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
return DDCommandResult.INVALID_ARGUMENTS;
|
||||
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);
|
||||
}
|
||||
// Teleport!
|
||||
DDTeleporter.teleportEntity(targetPlayer, destination, checkOrientation);
|
||||
return DDCommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
public boolean isInteger( String input )
|
||||
private static boolean isInteger(String input)
|
||||
{
|
||||
try
|
||||
{
|
||||
Integer.parseInt( input );
|
||||
Integer.parseInt(input);
|
||||
return true;
|
||||
}
|
||||
catch(Exception e )
|
||||
catch(Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,6 @@ 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
|
||||
@@ -96,13 +95,15 @@ 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
|
||||
*/
|
||||
public int compareTo(ICommand par1ICommand)
|
||||
@Override
|
||||
public int compareTo(ICommand command)
|
||||
{
|
||||
return this.getCommandName().compareTo(par1ICommand.getCommandName());
|
||||
return this.getCommandName().compareTo(command.getCommandName());
|
||||
}
|
||||
|
||||
public int compareTo(Object par1Obj)
|
||||
@Override
|
||||
public int compareTo(Object other)
|
||||
{
|
||||
return this.compareTo((ICommand)par1Obj);
|
||||
return this.compareTo((ICommand) other);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ 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 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 int CUSTOM_ERROR_CODE = -1;
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ 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
|
||||
@@ -46,7 +49,9 @@ 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
|
||||
@@ -57,6 +62,7 @@ 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;
|
||||
|
||||
@@ -75,6 +81,9 @@ 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
|
||||
@@ -147,6 +156,9 @@ 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 " +
|
||||
@@ -192,6 +204,8 @@ 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();
|
||||
@@ -204,6 +218,9 @@ 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();
|
||||
@@ -213,6 +230,7 @@ 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);
|
||||
|
||||
@@ -9,7 +9,6 @@ public class DDWorldProperties
|
||||
/**
|
||||
* World Generation Settings
|
||||
*/
|
||||
|
||||
public final DimensionFilter RiftClusterDimensions;
|
||||
public final DimensionFilter RiftGatewayDimensions;
|
||||
|
||||
@@ -17,7 +16,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";
|
||||
@@ -44,6 +43,12 @@ 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();
|
||||
}
|
||||
|
||||
|
||||
169
src/main/java/StevenDimDoors/mod_pocketDim/core/DDLock.java
Normal file
169
src/main/java/StevenDimDoors/mod_pocketDim/core/DDLock.java
Normal file
@@ -0,0 +1,169 @@
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ 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;
|
||||
@@ -23,9 +22,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;
|
||||
@@ -52,59 +51,49 @@ public class DDTeleporter
|
||||
|
||||
private DDTeleporter() { }
|
||||
|
||||
/**Checks if the destination supplied is valid, ie, filled by any non-replaceable block.
|
||||
*
|
||||
* @param entity
|
||||
* @param world
|
||||
* @param destination
|
||||
* @param properties
|
||||
* @return
|
||||
/**
|
||||
* Checks if the destination supplied is safe (i.e. filled by any replaceable or non-opaque blocks)
|
||||
*/
|
||||
private static boolean checkDestination(Entity entity, WorldServer world, Point4D destination,DDProperties properties)
|
||||
private static boolean checkDestination(WorldServer world, Point4D destination, int orientation)
|
||||
{
|
||||
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(MathHelper.floor_double(x - 0.5), y - 1, MathHelper.floor_double(z + 0.5));
|
||||
point = new Point3D(x - 1, y - 1, z);
|
||||
break;
|
||||
case 1:
|
||||
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z - 0.5));
|
||||
point = new Point3D(x, y - 1, z - 1);
|
||||
break;
|
||||
case 2:
|
||||
point = new Point3D(MathHelper.floor_double(x + 1.5), y - 1, MathHelper.floor_double(z + 0.5));
|
||||
point = new Point3D(x + 1, y - 1, z);
|
||||
break;
|
||||
case 3:
|
||||
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z + 1.5));
|
||||
point = new Point3D(x, y - 1, z + 1);
|
||||
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;
|
||||
}
|
||||
@@ -126,39 +115,15 @@ public class DDTeleporter
|
||||
}
|
||||
else
|
||||
{
|
||||
//Teleport the entity to the precise destination point
|
||||
// Teleport the entity to the precise destination point
|
||||
orientation = -1;
|
||||
}
|
||||
|
||||
if (!checkDestination(entity, world, destination, properties))
|
||||
{
|
||||
if (entity instanceof EntityPlayerMP)
|
||||
if (entity instanceof EntityPlayer)
|
||||
{
|
||||
EntityPlayer player = (EntityPlayer) entity;
|
||||
player.rotationYaw = (orientation * 90) + 90;
|
||||
switch (orientation)
|
||||
if (checkDestination(world, destination, 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;
|
||||
switch (orientation)
|
||||
{
|
||||
case 0:
|
||||
@@ -178,6 +143,11 @@ public class DDTeleporter
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
|
||||
}
|
||||
}
|
||||
else if (entity instanceof EntityMinecart)
|
||||
{
|
||||
entity.motionX = 0;
|
||||
@@ -201,7 +171,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;
|
||||
@@ -251,15 +221,14 @@ public class DDTeleporter
|
||||
}
|
||||
|
||||
//Check if the block below that point is actually a door
|
||||
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)
|
||||
Block block = Block.blocksList[world.getBlockId(door.getX(), door.getY() - 1, door.getZ())];
|
||||
if (block==null || !(block instanceof IDimDoor))
|
||||
{
|
||||
//Return the pocket's orientation instead
|
||||
return PocketManager.getDimensionData(door.getDimension()).orientation();
|
||||
return PocketManager.createDimensionData(world).orientation();
|
||||
}
|
||||
|
||||
|
||||
//Return the orientation portion of its metadata
|
||||
return world.getBlockMetadata(door.getX(), door.getY() - 1, door.getZ()) & 3;
|
||||
}
|
||||
@@ -324,7 +293,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.getDimensionData(destination.getDimension())));
|
||||
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionData(newWorld)));
|
||||
|
||||
// Set the new dimension and inform the client that it's moving to a new world.
|
||||
player.dimension = destination.getDimension();
|
||||
@@ -458,11 +427,11 @@ public class DDTeleporter
|
||||
return;
|
||||
}
|
||||
|
||||
if (!initializeDestination(link, DDProperties.instance(),door))
|
||||
if (!initializeDestination(link, DDProperties.instance(),entity,door))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (link.linkType() == LinkTypes.RANDOM)
|
||||
if (link.linkType() == LinkType.RANDOM)
|
||||
{
|
||||
Point4D randomDestination = getRandomDestination();
|
||||
if (randomDestination != null)
|
||||
@@ -474,18 +443,43 @@ public class DDTeleporter
|
||||
else
|
||||
{
|
||||
buildExitDoor(door, link, DDProperties.instance());
|
||||
entity = teleportEntity(entity, link.destination(), link.linkType() != LinkTypes.UNSAFE_EXIT);
|
||||
entity = teleportEntity(entity, link.destination(), link.linkType() != LinkType.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, Block door)
|
||||
private static boolean initializeDestination(DimLink link, DDProperties properties, Entity entity, Block door)
|
||||
{
|
||||
if (link.hasDestination())
|
||||
if (link.hasDestination()&&link.linkType()!=LinkType.PERSONAL)
|
||||
{
|
||||
if(PocketManager.isBlackListed(link.destination().getDimension()))
|
||||
if (PocketManager.isBlackListed(link.destination().getDimension()))
|
||||
{
|
||||
link=PocketManager.getDimensionData(link.source().getDimension()).createLink(link.link.point,LinkTypes.SAFE_EXIT,link.link.orientation);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -496,25 +490,50 @@ public class DDTeleporter
|
||||
// Check the destination type and respond accordingly
|
||||
switch (link.linkType())
|
||||
{
|
||||
case LinkTypes.DUNGEON:
|
||||
case DUNGEON:
|
||||
return PocketBuilder.generateNewDungeonPocket(link, properties);
|
||||
case LinkTypes.POCKET:
|
||||
return PocketBuilder.generateNewPocket(link, properties,door);
|
||||
case LinkTypes.SAFE_EXIT:
|
||||
case POCKET:
|
||||
return PocketBuilder.generateNewPocket(link, properties, door, DimensionType.POCKET);
|
||||
case PERSONAL:
|
||||
return setupPersonalLink(link, properties, entity, door);
|
||||
case SAFE_EXIT:
|
||||
return generateSafeExit(link, properties);
|
||||
case LinkTypes.DUNGEON_EXIT:
|
||||
case DUNGEON_EXIT:
|
||||
return generateDungeonExit(link, properties);
|
||||
case LinkTypes.UNSAFE_EXIT:
|
||||
case UNSAFE_EXIT:
|
||||
return generateUnsafeExit(link);
|
||||
case LinkTypes.NORMAL:
|
||||
case LinkTypes.REVERSE:
|
||||
case LinkTypes.RANDOM:
|
||||
case NORMAL:
|
||||
case REVERSE:
|
||||
case 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
|
||||
@@ -532,7 +551,7 @@ public class DDTeleporter
|
||||
{
|
||||
for (DimLink link : dimension.getAllLinks())
|
||||
{
|
||||
if (link.linkType() != LinkTypes.RANDOM)
|
||||
if (link.linkType() != LinkType.RANDOM)
|
||||
{
|
||||
matches.add(link.source());
|
||||
}
|
||||
@@ -544,11 +563,8 @@ public class DDTeleporter
|
||||
{
|
||||
return matches.get( random.nextInt(matches.size()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean generateUnsafeExit(DimLink link)
|
||||
{
|
||||
@@ -561,7 +577,8 @@ 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.link.point.getDimension());
|
||||
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
|
||||
|
||||
if (current.isPocketDimension())
|
||||
{
|
||||
Point4D source = link.source();
|
||||
@@ -574,7 +591,7 @@ public class DDTeleporter
|
||||
Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ());
|
||||
if (destination != null)
|
||||
{
|
||||
current.root().setDestination(link, destination.getX(), destination.getY(), destination.getZ());
|
||||
current.root().setLinkDestination(link, destination.getX(), destination.getY(), destination.getZ());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -585,7 +602,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.link.point.getZ());
|
||||
TileEntity doorTE = startWorld.getBlockTileEntity(link.source().getX(), link.source().getY(), link.point.getZ());
|
||||
if(doorTE instanceof TileEntityDimDoor)
|
||||
{
|
||||
if((TileEntityDimDoor.class.cast(doorTE).hasGennedPair))
|
||||
@@ -615,9 +632,10 @@ public class DDTeleporter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean generateSafeExit(DimLink link, DDProperties properties)
|
||||
{
|
||||
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension());
|
||||
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
|
||||
return generateSafeExit(current.root(), link, properties);
|
||||
}
|
||||
|
||||
@@ -628,7 +646,8 @@ 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.link.point.getDimension());
|
||||
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
|
||||
|
||||
ArrayList<NewDimData> roots = PocketManager.getRootDimensions();
|
||||
int shiftChance = START_ROOT_SHIFT_CHANCE + ROOT_SHIFT_CHANCE_PER_LEVEL * (current.packDepth() - 1);
|
||||
|
||||
@@ -636,11 +655,11 @@ public class DDTeleporter
|
||||
{
|
||||
if (current.root().id() != OVERWORLD_DIMENSION_ID && random.nextInt(MAX_OVERWORLD_EXIT_CHANCE) < OVERWORLD_EXIT_CHANCE)
|
||||
{
|
||||
return generateSafeExit(PocketManager.getDimensionData(OVERWORLD_DIMENSION_ID), link, properties);
|
||||
return generateSafeExit(PocketManager.createDimensionDataDangerously(OVERWORLD_DIMENSION_ID), link, properties);
|
||||
}
|
||||
if (current.root().id() != NETHER_DIMENSION_ID && random.nextInt(MAX_NETHER_EXIT_CHANCE) < NETHER_EXIT_CHANCE)
|
||||
{
|
||||
return generateSafeExit(PocketManager.getDimensionData(NETHER_DIMENSION_ID), link, properties);
|
||||
return generateSafeExit(PocketManager.createDimensionDataDangerously(NETHER_DIMENSION_ID), link, properties);
|
||||
}
|
||||
for (int attempts = 0; attempts < 10; attempts++)
|
||||
{
|
||||
@@ -744,16 +763,17 @@ 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, LinkTypes.REVERSE,orientation);
|
||||
sourceDim.setDestination(reverse, source.getX(), source.getY(), source.getZ());
|
||||
DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkType.REVERSE,orientation);
|
||||
|
||||
sourceDim.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
|
||||
|
||||
// Set up the warp door at the destination
|
||||
orientation = BlockRotator.transformMetadata(orientation, 2, properties.WarpDoorID);
|
||||
ItemDimensionalDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor);
|
||||
ItemDoor.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.setDestination(link, x, y + 2, z);
|
||||
destinationDim.setLinkDestination(link, x, y + 2, z);
|
||||
}
|
||||
|
||||
return (destination != null);
|
||||
|
||||
@@ -2,73 +2,99 @@ 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 ClientLinkData link;
|
||||
protected Point4D point;
|
||||
protected int orientation;
|
||||
protected DDLock lock;
|
||||
protected DimLink parent;
|
||||
protected LinkTail tail;
|
||||
protected List<DimLink> children;
|
||||
|
||||
protected DimLink(ClientLinkData link, DimLink parent)
|
||||
protected DimLink(Point4D point, int orientation, DDLock lock, DimLink parent)
|
||||
{
|
||||
|
||||
if (parent.link.point.getDimension() != link.point.getDimension())
|
||||
if (parent.point.getDimension() != 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.link = link;
|
||||
this.point = point;
|
||||
this.tail = parent.tail;
|
||||
this.orientation = orientation;
|
||||
this.children = new LinkedList<DimLink>();
|
||||
parent.children.add(this);
|
||||
}
|
||||
|
||||
protected DimLink(ClientLinkData link, int linkType)
|
||||
protected DimLink(Point4D point, int orientation, DDLock lock, LinkType 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.link = link;
|
||||
this.point = point;
|
||||
this.orientation = orientation;
|
||||
this.tail = new LinkTail(linkType, null);
|
||||
this.children = new LinkedList<DimLink>();
|
||||
}
|
||||
|
||||
public Point4D source()
|
||||
{
|
||||
return link.point;
|
||||
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);
|
||||
}
|
||||
|
||||
public int orientation()
|
||||
{
|
||||
return link.orientation;
|
||||
}
|
||||
|
||||
public ClientLinkData link()
|
||||
{
|
||||
return link;
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public Point4D destination()
|
||||
{
|
||||
return tail.getDestination();
|
||||
}
|
||||
|
||||
public int getDestinationOrientation()
|
||||
{
|
||||
DimLink link = PocketManager.getLink(this.destination().getX(), this.destination().getY(), this.destination().getZ(), this.destination().getDimension());
|
||||
if(link !=null)
|
||||
DimLink destinationLink = PocketManager.getLink(tail.getDestination());
|
||||
if (destinationLink != null)
|
||||
{
|
||||
return link.orientation();
|
||||
return destinationLink.orientation();
|
||||
}
|
||||
return (this.orientation()+2)%4;
|
||||
return (orientation + 2) % 4;
|
||||
}
|
||||
|
||||
public boolean hasDestination()
|
||||
{
|
||||
return (tail.getDestination() != null);
|
||||
@@ -89,13 +115,65 @@ public abstract class DimLink
|
||||
return parent;
|
||||
}
|
||||
|
||||
public int linkType()
|
||||
public LinkType 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 link.point + " -> " + (hasDestination() ? destination() : "");
|
||||
return point + " -> " + (hasDestination() ? destination() : "()");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,5 @@ package StevenDimDoors.mod_pocketDim.core;
|
||||
|
||||
public interface IDimRegistrationCallback
|
||||
{
|
||||
public NewDimData registerDimension(int dimensionID, int rootID);
|
||||
public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
class LinkTail
|
||||
{
|
||||
private Point4D destination;
|
||||
private int linkType;
|
||||
private LinkType linkType;
|
||||
|
||||
public LinkTail(int linkType, Point4D destination)
|
||||
public LinkTail(LinkType linkType, Point4D destination)
|
||||
{
|
||||
this.linkType = linkType;
|
||||
this.destination = destination;
|
||||
@@ -21,12 +21,11 @@ class LinkTail
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public int getLinkType() {
|
||||
public LinkType getLinkType() {
|
||||
return linkType;
|
||||
}
|
||||
|
||||
public void setLinkType(int linkType) {
|
||||
public void setLinkType(LinkType linkType) {
|
||||
this.linkType = linkType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,32 +1,42 @@
|
||||
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
|
||||
public abstract class NewDimData implements IPackable<PackedDimData>
|
||||
{
|
||||
private static class InnerDimLink extends DimLink
|
||||
{
|
||||
public InnerDimLink(Point4D source, DimLink parent, int orientation)
|
||||
public InnerDimLink(Point4D source, DimLink parent, int orientation, DDLock lock)
|
||||
{
|
||||
super(new ClientLinkData(source, orientation), parent);
|
||||
super(source, orientation, lock, parent);
|
||||
}
|
||||
|
||||
public InnerDimLink(Point4D source, int linkType, int orientation)
|
||||
public InnerDimLink(Point4D source, LinkType linkType, int orientation, DDLock lock)
|
||||
{
|
||||
super(new ClientLinkData(source, orientation), linkType);
|
||||
super(source, orientation, lock, linkType);
|
||||
}
|
||||
|
||||
public void setDestination(int x, int y, int z, NewDimData dimension)
|
||||
@@ -34,26 +44,6 @@ public abstract class NewDimData
|
||||
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)
|
||||
@@ -65,7 +55,7 @@ public abstract class NewDimData
|
||||
//Ignore this request silently
|
||||
return false;
|
||||
}
|
||||
if (nextParent.link.point.getDimension() != link.point.getDimension())
|
||||
if (nextParent.point.getDimension() != 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.");
|
||||
@@ -88,11 +78,11 @@ public abstract class NewDimData
|
||||
parent = nextParent;
|
||||
tail = nextParent.tail;
|
||||
nextParent.children.add(this);
|
||||
this.link.orientation=orientation;
|
||||
this.orientation=orientation;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void overwrite(int linkType, int orientation)
|
||||
public void overwrite(LinkType linkType, int orientation)
|
||||
{
|
||||
//Release children
|
||||
for (DimLink child : children)
|
||||
@@ -111,19 +101,54 @@ public abstract class NewDimData
|
||||
parent = null;
|
||||
tail = new LinkTail(linkType, null);
|
||||
//Set new orientation
|
||||
this.link.orientation=orientation;
|
||||
this.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;
|
||||
@@ -133,18 +158,16 @@ public abstract class NewDimData
|
||||
protected boolean modified;
|
||||
public IUpdateWatcher<ClientLinkData> linkWatcher;
|
||||
|
||||
protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon,
|
||||
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)
|
||||
{
|
||||
// The isPocket flag is redundant. It's meant as an integrity safeguard.
|
||||
if (isPocket && (parent == null))
|
||||
if (type != DimensionType.ROOT && (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
|
||||
@@ -152,12 +175,13 @@ public abstract class NewDimData
|
||||
this.children = new ArrayList<NewDimData>();
|
||||
this.parent = parent;
|
||||
this.packDepth = 0;
|
||||
this.isDungeon = isDungeon;
|
||||
this.type = type;
|
||||
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
|
||||
@@ -176,7 +200,7 @@ public abstract class NewDimData
|
||||
}
|
||||
}
|
||||
|
||||
protected NewDimData(int id, NewDimData root)
|
||||
protected NewDimData(int id, NewDimData root, DimensionType type)
|
||||
{
|
||||
// This constructor is meant for client-side code only
|
||||
if (root == null)
|
||||
@@ -190,7 +214,7 @@ public abstract class NewDimData
|
||||
this.children = new ArrayList<NewDimData>();
|
||||
this.parent = null;
|
||||
this.packDepth = 0;
|
||||
this.isDungeon = false;
|
||||
this.type = type;
|
||||
this.isFilled = false;
|
||||
this.orientation = 0;
|
||||
this.origin = null;
|
||||
@@ -198,28 +222,26 @@ public abstract class NewDimData
|
||||
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)
|
||||
{
|
||||
//TODO: Rewrite this later to use an octtree
|
||||
|
||||
//Sanity check...
|
||||
// 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 > 1, so we ignore the rift
|
||||
//that called this function and any adjacent rifts.
|
||||
|
||||
DimLink nearest = null;
|
||||
// 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;
|
||||
|
||||
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++)
|
||||
@@ -231,7 +253,7 @@ public abstract class NewDimData
|
||||
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;
|
||||
@@ -247,23 +269,19 @@ public abstract class NewDimData
|
||||
|
||||
public ArrayList<DimLink> findRiftsInRange(World world, int range, int x, int y, int z)
|
||||
{
|
||||
ArrayList<DimLink> links = new ArrayList<DimLink>();
|
||||
//TODO: Rewrite this later to use an octtree
|
||||
|
||||
//Sanity check...
|
||||
// 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 > 1, so we ignore the rift
|
||||
//that called this function and any adjacent rifts.
|
||||
|
||||
DimLink link;
|
||||
|
||||
int distance;
|
||||
// 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;
|
||||
DimLink link;
|
||||
DDProperties properties = DDProperties.instance();
|
||||
ArrayList<DimLink> links = new ArrayList<DimLink>();
|
||||
|
||||
for (i = -range; i <= range; i++)
|
||||
{
|
||||
@@ -274,7 +292,7 @@ public abstract class NewDimData
|
||||
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);
|
||||
@@ -292,20 +310,33 @@ public abstract class NewDimData
|
||||
return Math.abs(i) + Math.abs(j) + Math.abs(k);
|
||||
}
|
||||
|
||||
public DimLink createLink(int x, int y, int z, int linkType, int orientation)
|
||||
public DimLink createLink(int x, int y, int z, LinkType linkType, int orientation)
|
||||
{
|
||||
return createLink(new Point4D(x, y, z, id), linkType, orientation);
|
||||
return createLink(new Point4D(x, y, z, id), linkType, orientation, null);
|
||||
}
|
||||
|
||||
public DimLink createLink(Point4D source, int linkType, int orientation)
|
||||
public DimLink createLink(Point4D source, LinkType linkType, int orientation, DDLock locked)
|
||||
{
|
||||
//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);
|
||||
link = new InnerDimLink(source, linkType, orientation, locked);
|
||||
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
|
||||
{
|
||||
@@ -314,44 +345,59 @@ public abstract class NewDimData
|
||||
modified = true;
|
||||
|
||||
//Link created!
|
||||
if (linkType != LinkTypes.CLIENT_SIDE)
|
||||
if (linkType != LinkType.CLIENT)
|
||||
|
||||
{
|
||||
linkWatcher.onCreated(link.link);
|
||||
linkWatcher.onCreated(new ClientLinkData(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.link.orientation);
|
||||
link = new InnerDimLink(source, parent, parent.orientation, locked);
|
||||
linkMapping.put(source, link);
|
||||
linkList.add(link);
|
||||
|
||||
//Link created!
|
||||
linkWatcher.onCreated(link.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));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (link.overwrite(parent, parent.link.orientation))
|
||||
if (link.overwrite((InnerDimLink) parent, parent.orientation))
|
||||
{
|
||||
//Link created!
|
||||
linkWatcher.onCreated(link.link);
|
||||
linkWatcher.onCreated(new ClientLinkData(link));
|
||||
}
|
||||
}
|
||||
modified = true;
|
||||
@@ -368,8 +414,20 @@ public abstract class NewDimData
|
||||
if (target != null)
|
||||
{
|
||||
linkList.remove(target);
|
||||
//Raise deletion event
|
||||
linkWatcher.onDeleted(target.link);
|
||||
|
||||
// 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));
|
||||
target.clear();
|
||||
modified = true;
|
||||
}
|
||||
@@ -378,7 +436,10 @@ public abstract class NewDimData
|
||||
|
||||
public boolean deleteLink(int x, int y, int z)
|
||||
{
|
||||
Point4D location = new Point4D(x, y, z, id);
|
||||
return this.deleteLink(this.getLink(x, y, z));
|
||||
}
|
||||
public boolean deleteLink(Point4D location)
|
||||
{
|
||||
return this.deleteLink(this.getLink(location));
|
||||
}
|
||||
|
||||
@@ -390,7 +451,7 @@ public abstract class NewDimData
|
||||
|
||||
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)
|
||||
@@ -413,11 +474,10 @@ public abstract class NewDimData
|
||||
return (root != this);
|
||||
}
|
||||
|
||||
public boolean isDungeon()
|
||||
public DimensionType type()
|
||||
{
|
||||
return isDungeon;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public boolean isFilled()
|
||||
{
|
||||
return isFilled;
|
||||
@@ -491,7 +551,7 @@ public abstract class NewDimData
|
||||
|
||||
public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon)
|
||||
{
|
||||
if (!isDungeon)
|
||||
if (this.type != DimensionType.DUNGEON)
|
||||
{
|
||||
throw new IllegalStateException("Cannot invoke initializeDungeon() on a non-dungeon dimension.");
|
||||
}
|
||||
@@ -503,7 +563,7 @@ public abstract class NewDimData
|
||||
{
|
||||
throw new IllegalArgumentException("orientation must be between 0 and 3, inclusive.");
|
||||
}
|
||||
setDestination(incoming, originX, originY, originZ);
|
||||
setLinkDestination(incoming, originX, originY, originZ);
|
||||
this.origin = incoming.destination();
|
||||
this.orientation = orientation;
|
||||
this.dungeon = dungeon;
|
||||
@@ -516,11 +576,42 @@ public abstract class NewDimData
|
||||
*/
|
||||
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)
|
||||
@@ -549,11 +640,8 @@ public abstract class NewDimData
|
||||
{
|
||||
return parent.packDepth + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void initializePocket(int originX, int originY, int originZ, int orientation, DimLink incoming)
|
||||
{
|
||||
@@ -566,19 +654,47 @@ public abstract class NewDimData
|
||||
throw new IllegalStateException("The dimension has already been initialized.");
|
||||
}
|
||||
|
||||
setDestination(incoming, originX, originY, originZ);
|
||||
setLinkDestination(incoming, originX, originY, originZ);
|
||||
this.origin = incoming.destination();
|
||||
this.orientation = orientation;
|
||||
this.modified = true;
|
||||
}
|
||||
|
||||
public void setDestination(DimLink incoming, int x, int y, int z)
|
||||
public void setLinkDestination(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())
|
||||
@@ -589,10 +705,17 @@ public abstract class NewDimData
|
||||
{
|
||||
return linkList.get(random.nextInt(linkList.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
return chunkLinks;
|
||||
}
|
||||
return new ArrayList<InnerDimLink>(0);
|
||||
}
|
||||
|
||||
public boolean isModified()
|
||||
@@ -605,6 +728,101 @@ public abstract class NewDimData
|
||||
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;
|
||||
|
||||
@@ -7,32 +7,26 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
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.
|
||||
@@ -41,120 +35,25 @@ import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy;
|
||||
*/
|
||||
public class PocketManager
|
||||
{
|
||||
private static class InnerDimData extends NewDimData implements IPackable<PackedDimData>
|
||||
private static class InnerDimData extends NewDimData
|
||||
{
|
||||
// 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, boolean isPocket, boolean isDungeon,
|
||||
public InnerDimData(int id, InnerDimData parent, DimensionType type,
|
||||
IUpdateWatcher<ClientLinkData> linkWatcher)
|
||||
{
|
||||
super(id, parent, isPocket, isDungeon, linkWatcher);
|
||||
super(id, parent, type, linkWatcher);
|
||||
}
|
||||
|
||||
public InnerDimData(int id, InnerDimData root)
|
||||
public InnerDimData(int id, NewDimData root, DimensionType type)
|
||||
{
|
||||
// This constructor is meant for client-side code only
|
||||
super(id, root);
|
||||
super(id, root, type);
|
||||
}
|
||||
|
||||
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>
|
||||
@@ -164,7 +63,7 @@ public class PocketManager
|
||||
{
|
||||
Point4D source = link.point;
|
||||
NewDimData dimension = getDimensionData(source.getDimension());
|
||||
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE,link.orientation);
|
||||
dimension.createLink(source, LinkType.CLIENT, 0, link.lock);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,6 +73,16 @@ public class PocketManager
|
||||
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>
|
||||
@@ -181,7 +90,7 @@ public class PocketManager
|
||||
@Override
|
||||
public void onCreated(ClientDimData data)
|
||||
{
|
||||
registerClientDimension(data.ID, data.RootID);
|
||||
registerClientDimension(data.ID, data.rootID, data.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -189,6 +98,12 @@ 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
|
||||
@@ -199,9 +114,9 @@ public class PocketManager
|
||||
// exposing a private constructor ONLY to a very specific trusted class.
|
||||
|
||||
@Override
|
||||
public NewDimData registerDimension(int dimensionID, int rootID)
|
||||
public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type)
|
||||
{
|
||||
return registerClientDimension(dimensionID, rootID);
|
||||
return registerClientDimension(dimensionID, rootID, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,6 +138,9 @@ 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;
|
||||
@@ -247,6 +165,8 @@ 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())
|
||||
{
|
||||
@@ -258,7 +178,8 @@ public class PocketManager
|
||||
}
|
||||
//Register Limbo
|
||||
DDProperties properties = DDProperties.instance();
|
||||
registerDimension(properties.LimboDimensionID, null, false, false);
|
||||
registerDimension(properties.LimboDimensionID, null, DimensionType.ROOT);
|
||||
|
||||
|
||||
loadInternal();
|
||||
|
||||
@@ -271,12 +192,16 @@ 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, false, false, linkWatcher);
|
||||
dimData = new InnerDimData(packedData.ID, null, type, linkWatcher);
|
||||
dimData.root=dimData;
|
||||
dimData.parent=dimData;
|
||||
dimData.depth=packedData.Depth;
|
||||
@@ -288,10 +213,10 @@ public class PocketManager
|
||||
else //register children
|
||||
{
|
||||
InnerDimData test = PocketManager.dimensionData.get(packedData.ParentID);
|
||||
dimData = new InnerDimData(packedData.ID, test,true, packedData.IsDungeon, linkWatcher);
|
||||
dimData = new InnerDimData(packedData.ID, test, type, linkWatcher);
|
||||
dimData.isFilled=packedData.IsFilled;
|
||||
dimData.origin = new Point4D(packedData.Origin.getX(),packedData.Origin.getY(),packedData.Origin.getZ(),packedData.ID);
|
||||
dimData.root=PocketManager.getDimensionData(packedData.RootID);
|
||||
dimData.root = PocketManager.createDimensionData(packedData.RootID);
|
||||
|
||||
if(packedData.DungeonData!=null)
|
||||
{
|
||||
@@ -315,44 +240,48 @@ public class PocketManager
|
||||
{
|
||||
if (deleteFolder)
|
||||
{
|
||||
deleteDimensionFiles(target);
|
||||
deleteDimensionFiles(dimension);
|
||||
}
|
||||
// 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.id);
|
||||
deleteDimensionData(dimension);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean deleteDimensionFiles(NewDimData target)
|
||||
{
|
||||
InnerDimData dimension = (InnerDimData) target;
|
||||
if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null)
|
||||
private static void deleteDimensionFiles(InnerDimData dimension)
|
||||
{
|
||||
// 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();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean deleteDimensionData(int dimensionID)
|
||||
private static void deleteDimensionData(InnerDimData dimension)
|
||||
{
|
||||
if (dimensionData.containsKey(dimensionID) && DimensionManager.getWorld(dimensionID) == null)
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
// This should never happen. A simple sanity check.
|
||||
throw new IllegalArgumentException("The specified dimension is not listed with PocketManager.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerPockets(DDProperties properties)
|
||||
@@ -362,9 +291,16 @@ public class PocketManager
|
||||
if (dimension.isPocketDimension())
|
||||
{
|
||||
try
|
||||
{
|
||||
if(personalPocketsMapping.containsValue(dimension))
|
||||
{
|
||||
DimensionManager.registerDimension(dimension.id(), properties.PersonalPocketProviderID);
|
||||
}
|
||||
else
|
||||
{
|
||||
DimensionManager.registerDimension(dimension.id(), properties.PocketProviderID);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Could not register pocket dimension #" + dimension.id() + ". Probably caused by a version update/save data corruption/other mods.");
|
||||
@@ -410,8 +346,6 @@ public class PocketManager
|
||||
*/
|
||||
private static void loadInternal()
|
||||
{
|
||||
//System.out.println(!FMLCommonHandler.instance().getSide().isClient());
|
||||
|
||||
File saveDir = DimensionManager.getCurrentSaveRootDirectory();
|
||||
if (saveDir != null)
|
||||
{
|
||||
@@ -424,7 +358,8 @@ public class PocketManager
|
||||
{
|
||||
System.out.println("Importing old DD save data...");
|
||||
OldSaveImporter.importOldSave(oldSaveData);
|
||||
oldSaveData.delete();
|
||||
|
||||
oldSaveData.renameTo(new File(oldSaveData.getAbsolutePath()+"_IMPORTED"));
|
||||
|
||||
System.out.println("Import Succesful!");
|
||||
}
|
||||
@@ -478,6 +413,11 @@ public class PocketManager
|
||||
|
||||
public static WorldServer loadDimension(int id)
|
||||
{
|
||||
if (!DimensionManager.isDimensionRegistered(id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
WorldServer world = DimensionManager.getWorld(id);
|
||||
if (world == null)
|
||||
{
|
||||
@@ -494,10 +434,17 @@ public class PocketManager
|
||||
|
||||
public static NewDimData registerDimension(World world)
|
||||
{
|
||||
return registerDimension(world.provider.dimensionId, null, false, false);
|
||||
return registerDimension(world.provider.dimensionId, null, DimensionType.ROOT);
|
||||
}
|
||||
|
||||
public static NewDimData registerPocket(NewDimData parent, boolean isDungeon)
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
@@ -506,9 +453,40 @@ public class PocketManager
|
||||
|
||||
DDProperties properties = DDProperties.instance();
|
||||
int dimensionID = DimensionManager.getNextFreeDimId();
|
||||
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
|
||||
return registerDimension(dimensionID, (InnerDimData) parent, true, isDungeon);
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static NewDimData registerPocket(NewDimData parent, DimensionType type)
|
||||
{
|
||||
return registerPocket(parent, type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a dimension with DD but NOT with forge.
|
||||
* @param dimensionID
|
||||
@@ -517,7 +495,7 @@ public class PocketManager
|
||||
* @param isDungeon
|
||||
* @return
|
||||
*/
|
||||
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, boolean isPocket, boolean isDungeon)
|
||||
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, DimensionType type)
|
||||
{
|
||||
if (dimensionData.containsKey(dimensionID))
|
||||
{
|
||||
@@ -527,7 +505,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, isPocket, isDungeon, linkWatcher);
|
||||
InnerDimData dimension = new InnerDimData(dimensionID, parent, type, linkWatcher);
|
||||
dimensionData.put(dimensionID, dimension);
|
||||
if (!dimension.isPocketDimension())
|
||||
{
|
||||
@@ -539,16 +517,17 @@ public class PocketManager
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private static NewDimData registerClientDimension(int dimensionID, int rootID)
|
||||
{
|
||||
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
|
||||
private static NewDimData registerClientDimension(int dimensionID, int rootID, DimensionType type)
|
||||
|
||||
// SenseiKiwi: I'm a little worried about how getDimensionData will raise
|
||||
{
|
||||
// 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.
|
||||
|
||||
// SenseiKiwi: I'm a little worried about how createDimensionData will raise
|
||||
// an event when it creates any root dimensions... Needs checking later.
|
||||
|
||||
InnerDimData root = (InnerDimData) getDimensionData(rootID);
|
||||
InnerDimData root = (InnerDimData) createDimensionData(rootID);
|
||||
InnerDimData dimension;
|
||||
|
||||
if (rootID != dimensionID)
|
||||
@@ -556,7 +535,7 @@ public class PocketManager
|
||||
dimension = dimensionData.get(dimensionID);
|
||||
if (dimension == null)
|
||||
{
|
||||
dimension = new InnerDimData(dimensionID, root);
|
||||
dimension = new InnerDimData(dimensionID, root, type);
|
||||
dimensionData.put(dimension.id(), dimension);
|
||||
}
|
||||
}
|
||||
@@ -564,7 +543,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.
|
||||
@@ -576,29 +555,39 @@ public class PocketManager
|
||||
return dimension;
|
||||
}
|
||||
|
||||
public static NewDimData getDimensionData(World world)
|
||||
{
|
||||
return getDimensionData(world.provider.dimensionId);
|
||||
}
|
||||
|
||||
public static NewDimData getDimensionData(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.
|
||||
//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.
|
||||
|
||||
//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;
|
||||
return PocketManager.dimensionData.get(dimensionID);
|
||||
}
|
||||
|
||||
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.
|
||||
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, false, false);
|
||||
dimension = registerDimension(dimensionID, null, DimensionType.ROOT);
|
||||
}
|
||||
return dimension;
|
||||
}
|
||||
@@ -624,6 +613,7 @@ public class PocketManager
|
||||
|
||||
unregisterPockets();
|
||||
dimensionData = null;
|
||||
personalPocketsMapping = null;
|
||||
rootDimensions = null;
|
||||
isLoaded = false;
|
||||
isConnected = false;
|
||||
@@ -646,11 +636,8 @@ public class PocketManager
|
||||
{
|
||||
return dimension.getLink(x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBlackListed(int dimensionID)
|
||||
{
|
||||
@@ -715,9 +702,6 @@ public class PocketManager
|
||||
load();
|
||||
Compactor.readDimensions(input, new DimRegistrationCallback());
|
||||
|
||||
// Register pocket dimensions
|
||||
DDProperties properties = DDProperties.instance();
|
||||
|
||||
isLoaded = true;
|
||||
isLoading = false;
|
||||
isConnected = true;
|
||||
@@ -727,4 +711,29 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ 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;
|
||||
@@ -20,7 +19,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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
|
||||
@@ -162,7 +161,7 @@ public class DungeonSchematic extends Schematic {
|
||||
applyFilter(standardizer);
|
||||
}
|
||||
|
||||
private Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties)
|
||||
private static 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>();
|
||||
@@ -247,7 +246,7 @@ public class DungeonSchematic extends Schematic {
|
||||
world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag));
|
||||
}
|
||||
|
||||
setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter);
|
||||
setUpDungeon(PocketManager.createDimensionData(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)
|
||||
@@ -322,10 +321,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(), LinkTypes.REVERSE, orientation);
|
||||
DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkType.REVERSE, orientation);
|
||||
Point4D destination = entryLink.source();
|
||||
NewDimData prevDim = PocketManager.getDimensionData(destination.getDimension());
|
||||
prevDim.setDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
|
||||
prevDim.setLinkDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
|
||||
initDoorTileEntity(world, pocketCenter);
|
||||
}
|
||||
|
||||
@@ -335,7 +334,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(), LinkTypes.DUNGEON_EXIT, orientation);
|
||||
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.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;
|
||||
@@ -356,7 +355,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(), LinkTypes.DUNGEON, orientation);
|
||||
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON, orientation);
|
||||
initDoorTileEntity(world, location);
|
||||
}
|
||||
|
||||
|
||||
@@ -298,4 +298,9 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,4 +45,9 @@ public class DungeonType implements Comparable<DungeonType>
|
||||
final int prime = 2039;
|
||||
return prime * ID;
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.Name+" owned by "+this.Owner;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,91 @@
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
{
|
||||
ForgeChunkManager.releaseTicket(ticket);
|
||||
}
|
||||
else
|
||||
{
|
||||
IChunkLoader tile = (IChunkLoader) world.getBlockTileEntity(goldDimDoorX, goldDimDoorY, goldDimDoorZ);
|
||||
tile.forceChunkLoading(ticket,goldDimDoorX,goldDimDoorZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadChunkForcedWorlds(FMLServerStartingEvent event)
|
||||
public static Ticket createTicket(int x, int y, int z, World world)
|
||||
{
|
||||
for(NewDimData data : PocketManager.getDimensions())
|
||||
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++)
|
||||
{
|
||||
ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(chunkX, chunkZ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadForcedChunkWorlds(FMLServerStartingEvent event)
|
||||
{
|
||||
for (NewDimData data : PocketManager.getDimensions())
|
||||
{
|
||||
if(data.isPocketDimension())
|
||||
{
|
||||
|
||||
@@ -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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
|
||||
@@ -68,19 +68,20 @@ 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);
|
||||
callback.registerDimension(rootID, rootID, type);
|
||||
}
|
||||
// Don't check if (id != rootID) - we want to retrieve the reference anyway
|
||||
NewDimData dimension = callback.registerDimension(id, rootID);
|
||||
NewDimData dimension = callback.registerDimension(id, rootID, type);
|
||||
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(), LinkTypes.CLIENT_SIDE,link.orientation);
|
||||
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.CLIENT,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,31 +2,33 @@ package StevenDimDoors.mod_pocketDim.helpers;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
public class DeleteFolder
|
||||
{
|
||||
public static boolean deleteFolder(File file)
|
||||
public static boolean deleteFolder(File directory)
|
||||
{
|
||||
try
|
||||
{
|
||||
File[] files = file.listFiles();
|
||||
|
||||
if(files==null)
|
||||
File[] contents = directory.listFiles();
|
||||
if (contents != null)
|
||||
{
|
||||
file.delete();
|
||||
return true;
|
||||
}
|
||||
for(File inFile : files)
|
||||
for (File entry : contents)
|
||||
{
|
||||
DeleteFolder.deleteFolder(inFile);
|
||||
if (entry.isDirectory())
|
||||
{
|
||||
deleteFolder(entry);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
entry.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
return directory.delete();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -16,13 +16,12 @@ 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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
||||
@@ -46,7 +45,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 = "/mods/DimDoors/text/How_to_add_dungeons.txt";
|
||||
private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/assets/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";
|
||||
|
||||
@@ -264,7 +263,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, LinkTypes.POCKET, 3);
|
||||
DimLink link = dimension.createLink(x, y + 1, z, LinkType.POCKET, 3);
|
||||
|
||||
//Place a Warp Door linked to that pocket
|
||||
ItemDimensionalDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.warpDoor);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package StevenDimDoors.mod_pocketDim.helpers;
|
||||
|
||||
public class PersonalPocketHelper
|
||||
{
|
||||
|
||||
}
|
||||
@@ -214,13 +214,10 @@ public class yCoordHelper
|
||||
for (int dx = -1; dx <= 1; dx++)
|
||||
{
|
||||
for (int dz = -1; dz <= 1; dz++)
|
||||
{
|
||||
if (!provider.chunkExists(chunkX + dx, chunkZ + dz))
|
||||
{
|
||||
provider.loadChunk(chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ 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;
|
||||
@@ -23,9 +24,9 @@ import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
|
||||
|
||||
public abstract class BaseItemDoor extends ItemDoor
|
||||
{
|
||||
// maps non-dimensional door items to their corresponding dimensional door
|
||||
// item
|
||||
private static HashMap<ItemDoor, BaseItemDoor> vanillaDoorMapping = new HashMap<ItemDoor, BaseItemDoor>();
|
||||
// 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>();
|
||||
private static DDProperties properties = null;
|
||||
|
||||
/**
|
||||
@@ -34,7 +35,7 @@ public abstract class BaseItemDoor extends ItemDoor
|
||||
* @param material
|
||||
* @param door
|
||||
*/
|
||||
public BaseItemDoor(int itemID, Material material, ItemDoor door)
|
||||
public BaseItemDoor(int itemID, Material material, ItemDoor vanillaDoor)
|
||||
{
|
||||
super(itemID, material);
|
||||
this.setMaxStackSize(64);
|
||||
@@ -42,9 +43,10 @@ public abstract class BaseItemDoor extends ItemDoor
|
||||
if (properties == null)
|
||||
properties = DDProperties.instance();
|
||||
|
||||
if(door!=null)
|
||||
doorItemMapping.put(this, this);
|
||||
if (vanillaDoor != null)
|
||||
{
|
||||
vanillaDoorMapping.put(door, this);
|
||||
doorItemMapping.put(vanillaDoor, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +66,7 @@ public abstract class BaseItemDoor extends ItemDoor
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract BaseDimDoor getDoortoItemMapping();
|
||||
protected abstract BaseDimDoor getDoorBlock();
|
||||
|
||||
/**
|
||||
* Overriden here to remove vanilla block placement functionality from
|
||||
@@ -73,23 +75,12 @@ 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 block, called in EventHookContainer
|
||||
* Tries to place a door as a dimensional door
|
||||
*
|
||||
* @param doorBlock
|
||||
* @param stack
|
||||
* @param player
|
||||
* @param world
|
||||
@@ -97,8 +88,6 @@ 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)
|
||||
@@ -107,15 +96,20 @@ public abstract class BaseItemDoor extends ItemDoor
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(stack.getItem() instanceof ItemDoor))
|
||||
// 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)
|
||||
{
|
||||
throw new IllegalArgumentException("The itemstack must correspond to some type of door");
|
||||
return false;
|
||||
}
|
||||
if (BaseItemDoor.placeDoorOnBlock(getDoorToPlace(stack.getItem()), stack, player, world, x, y, z, side))
|
||||
BaseDimDoor doorBlock = mappedItem.getDoorBlock();
|
||||
if (BaseItemDoor.placeDoorOnBlock(doorBlock, stack, player, world, x, y, z, side))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return BaseItemDoor.placeDoorOnRift(getDoorToPlace(stack.getItem()), world, player, stack);
|
||||
return BaseItemDoor.placeDoorOnRift(doorBlock, world, player, stack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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"};
|
||||
private final static String[] subNames = {"Fabric of Reality", "Ancient Fabric" , "Altered Fabric"};
|
||||
|
||||
public ItemBlockDimWall(int par1)
|
||||
{
|
||||
|
||||
213
src/main/java/StevenDimDoors/mod_pocketDim/items/ItemDDKey.java
Normal file
213
src/main/java/StevenDimDoors/mod_pocketDim/items/ItemDDKey.java
Normal file
@@ -0,0 +1,213 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class ItemDimensionalDoor extends BaseItemDoor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseDimDoor getDoortoItemMapping()
|
||||
protected BaseDimDoor getDoorBlock()
|
||||
{
|
||||
return (BaseDimDoor) mod_pocketDim.dimensionalDoor;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class ItemGoldDimDoor extends BaseItemDoor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseDimDoor getDoortoItemMapping()
|
||||
protected BaseDimDoor getDoorBlock()
|
||||
{
|
||||
return (BaseDimDoor) mod_pocketDim.goldenDimensionalDoor;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public class ItemGoldDoor extends ItemDoor
|
||||
public ItemGoldDoor(int par1, Material par2Material)
|
||||
{
|
||||
super(par1, par2Material);
|
||||
this.setMaxStackSize(16);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
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;
|
||||
@@ -14,7 +13,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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
@@ -34,12 +33,13 @@ public class ItemRiftSignature extends Item
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public boolean hasEffect(ItemStack stack)
|
||||
public boolean hasEffect(ItemStack stack, int pass)
|
||||
{
|
||||
//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,50 +60,47 @@ public class ItemRiftSignature extends Item
|
||||
return false;
|
||||
}
|
||||
|
||||
y += 2; //Increase y by 2 to place the rift at head level
|
||||
if (!player.canPlayerEdit(x, y, z, side, stack))
|
||||
//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))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
|
||||
Point4DOrientation source = getSource(stack);
|
||||
int orientation = MathHelper.floor_double((double) ((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
|
||||
int orientation = MathHelper.floor_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());
|
||||
|
||||
//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);
|
||||
}
|
||||
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 source point, but check if its world is loaded first
|
||||
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.
|
||||
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());
|
||||
|
||||
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.getDimensionData(world));
|
||||
setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world));
|
||||
mod_pocketDim.sendChat(player,("Location Stored in Rift Signature"));
|
||||
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftStart", 0.6f, 1);
|
||||
}
|
||||
@@ -113,6 +110,7 @@ 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)
|
||||
@@ -140,26 +138,28 @@ public class ItemRiftSignature extends Item
|
||||
*/
|
||||
public static int adjustYForSpecialBlocks(World world, int x, int y, int z)
|
||||
{
|
||||
y=y-2;//get the block the player actually clicked on
|
||||
Block block = Block.blocksList[world.getBlockId(x, y, z)];
|
||||
if(block==null)
|
||||
int targetY = y - 2; // Get the block the player actually clicked on
|
||||
Block block = Block.blocksList[world.getBlockId(x, targetY, z)];
|
||||
if (block == null)
|
||||
{
|
||||
return y+2;
|
||||
return targetY + 2;
|
||||
}
|
||||
if(block.isBlockReplaceable(world, x, y, z))
|
||||
if (block.isBlockReplaceable(world, x, targetY, z))
|
||||
{
|
||||
return y+1;//move block placement down (-2+1) one so its directly over things like snow
|
||||
return targetY + 1; // Move block placement down (-2+1) one so its directly over things like snow
|
||||
}
|
||||
if(block instanceof BaseDimDoor)
|
||||
if (block instanceof BaseDimDoor)
|
||||
{
|
||||
if(world.getBlockId(x, y-1, z)==block.blockID&&world.getBlockMetadata(x, y, z)==8)
|
||||
if (((BaseDimDoor) block).isUpperDoorBlock(world.getBlockMetadata(x, targetY, z)))
|
||||
{
|
||||
return y;//move rift placement down two so its in the right place on the door.
|
||||
return targetY; // Move rift placement down two so its in the right place on the door.
|
||||
}
|
||||
return y+1;
|
||||
// Move rift placement down one so its in the right place on the door.
|
||||
return targetY + 1;
|
||||
}
|
||||
return y+2;
|
||||
return targetY + 2;
|
||||
}
|
||||
|
||||
public static void setSource(ItemStack itemStack, int x, int y, int z, int orientation, NewDimData dimension)
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
@@ -200,11 +200,12 @@ public class ItemRiftSignature extends Item
|
||||
Integer orientation = tag.getInteger("orientation");
|
||||
Integer dimID = tag.getInteger("linkDimID");
|
||||
|
||||
if (x != null && y != null && z != null && dimID != null)
|
||||
if (x != null && y != null && z != null && orientation != 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;
|
||||
@@ -214,10 +215,11 @@ 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()
|
||||
@@ -239,10 +241,16 @@ public class ItemRiftSignature extends Item
|
||||
{
|
||||
return point.getDimension();
|
||||
}
|
||||
|
||||
int getOrientation()
|
||||
{
|
||||
return orientation;
|
||||
}
|
||||
|
||||
Point4D getPoint()
|
||||
{
|
||||
return point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
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;
|
||||
@@ -11,10 +10,9 @@ 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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
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;
|
||||
|
||||
@@ -40,69 +38,124 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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))
|
||||
// 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))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Point4DOrientation source = getSource(stack);
|
||||
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
|
||||
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
|
||||
|
||||
// Check if the Stabilized Rift Signature has been initialized
|
||||
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
|
||||
Point4DOrientation source = getSource(stack);
|
||||
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))
|
||||
|
||||
// Yes, it's initialized.
|
||||
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.
|
||||
// Those benign redirection operations will be handled for free.
|
||||
|
||||
if (reverse != null && source.getPoint().equals(reverse.destination()))
|
||||
{
|
||||
mod_pocketDim.sendChat(player, "You don't have any Stable Fabric!");
|
||||
// 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;
|
||||
}
|
||||
|
||||
//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());
|
||||
// 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
|
||||
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z))
|
||||
{
|
||||
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
|
||||
// Try placing a rift at the destination point
|
||||
mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
|
||||
}
|
||||
|
||||
//Try placing a rift at the source point, but check if its world is loaded first
|
||||
// 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());
|
||||
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)
|
||||
{
|
||||
player.inventory.consumeInventoryItem(mod_pocketDim.itemStableFabric.itemID);
|
||||
}
|
||||
mod_pocketDim.sendChat(player,"Rift Created");
|
||||
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftEnd", 0.6f, 1);
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
//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);
|
||||
// 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);
|
||||
}
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -25,7 +25,7 @@ public class ItemUnstableDoor extends BaseItemDoor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseDimDoor getDoortoItemMapping()
|
||||
protected BaseDimDoor getDoorBlock()
|
||||
{
|
||||
return (BaseDimDoor) mod_pocketDim.unstableDoor;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class ItemWarpDoor extends BaseItemDoor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseDimDoor getDoortoItemMapping()
|
||||
protected BaseDimDoor getDoorBlock()
|
||||
{
|
||||
return (BaseDimDoor) mod_pocketDim.warpDoor;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class itemRiftRemover extends Item
|
||||
int hx = hit.blockX;
|
||||
int hy = hit.blockY;
|
||||
int hz = hit.blockZ;
|
||||
NewDimData dimension = PocketManager.getDimensionData(world);
|
||||
NewDimData dimension = PocketManager.createDimensionData(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.getDimensionData(world);
|
||||
NewDimData dimension = PocketManager.createDimensionData(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))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package StevenDimDoors.mod_pocketDim;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
@@ -19,10 +18,12 @@ 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;
|
||||
@@ -30,7 +31,6 @@ 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,9 +42,12 @@ 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;
|
||||
@@ -53,25 +56,24 @@ 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.FastRiftRegenerator;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.LimboDecay;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler;
|
||||
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;
|
||||
@@ -99,16 +101,21 @@ serverPacketHandlerSpec =
|
||||
@SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class))
|
||||
public class mod_pocketDim
|
||||
{
|
||||
public static final String version = "1.6.4-R2.2.3";
|
||||
public static final String version = "@VERSION@";
|
||||
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("PocketDimensions")
|
||||
public static mod_pocketDim instance = new mod_pocketDim();
|
||||
@Instance(mod_pocketDim.modid)
|
||||
public static mod_pocketDim instance;
|
||||
|
||||
public static Block quartzDoor;
|
||||
public static Block personalDimDoor;
|
||||
public static Block transientDoor;
|
||||
public static Block warpDoor;
|
||||
public static Block goldenDoor;
|
||||
@@ -132,7 +139,10 @@ public class mod_pocketDim
|
||||
public static Item itemRiftSignature;
|
||||
public static Item itemStableFabric;
|
||||
public static Item itemUnstableDoor;
|
||||
public static Item itemStabilizedLinkSignature;
|
||||
public static Item itemDDKey;
|
||||
public static Item itemQuartzDoor;
|
||||
public static Item itemPersonalDoor;
|
||||
public static Item itemStabilizedRiftSignature;
|
||||
|
||||
public static BiomeGenBase limboBiome;
|
||||
public static BiomeGenBase pocketBiome;
|
||||
@@ -142,9 +152,13 @@ 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 FastRiftRegenerator fastRiftRegenerator;
|
||||
public static RiftRegenerator riftRegenerator;
|
||||
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;
|
||||
@@ -167,14 +181,13 @@ 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
|
||||
EventHookContainer hooks = new EventHookContainer(properties);
|
||||
hooks = new EventHookContainer(properties);
|
||||
MinecraftForge.EVENT_BUS.register(hooks);
|
||||
MinecraftForge.TERRAIN_GEN_BUS.register(hooks);
|
||||
}
|
||||
@@ -182,31 +195,34 @@ public class mod_pocketDim
|
||||
@EventHandler
|
||||
public void onInitialization(FMLInitializationEvent event)
|
||||
{
|
||||
CommonTickHandler commonTickHandler = new CommonTickHandler();
|
||||
TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT);
|
||||
TickRegistry.registerTickHandler(commonTickHandler, Side.SERVER);
|
||||
// Initialize ServerTickHandler instance
|
||||
serverTickHandler = new ServerTickHandler();
|
||||
TickRegistry.registerTickHandler(serverTickHandler, Side.SERVER);
|
||||
|
||||
//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 LimboDecay instance: required for BlockLimbo
|
||||
limboDecay = new LimboDecay(properties);
|
||||
|
||||
// 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, decay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F);
|
||||
blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, limboDecay).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"));
|
||||
|
||||
itemGoldenDoor = (new ItemGoldDoor(properties.GoldenDoorID, Material.wood)).setUnlocalizedName("itemGoldDoor");
|
||||
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");
|
||||
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");
|
||||
@@ -215,7 +231,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");
|
||||
itemStabilizedLinkSignature = (new ItemStabilizedRiftSignature(properties.StabilizedRiftSignatureItemID)).setUnlocalizedName("itemStabilizedRiftSig");
|
||||
itemStabilizedRiftSignature = (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
|
||||
@@ -226,6 +242,8 @@ 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");
|
||||
@@ -243,6 +261,8 @@ 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);
|
||||
|
||||
@@ -262,19 +282,24 @@ public class mod_pocketDim
|
||||
LanguageRegistry.addName(itemRiftSignature, "Rift Signature");
|
||||
LanguageRegistry.addName(itemGoldenDoor, "Golden Door");
|
||||
LanguageRegistry.addName(itemGoldenDimensionalDoor, "Golden Dimensional Door");
|
||||
LanguageRegistry.addName(itemStabilizedLinkSignature, "Stabilized Rift Signature");
|
||||
LanguageRegistry.addName(itemStabilizedRiftSignature, "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");
|
||||
|
||||
@@ -286,9 +311,12 @@ 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.Obelisk.name", "Monolith");
|
||||
LanguageRegistry.instance().addStringLocalization("entity.dimdoors.Monolith.name", "Monolith");
|
||||
|
||||
CraftingManager.registerRecipes(properties);
|
||||
CraftingManager.registerDispenserBehaviors();
|
||||
GameRegistry.registerCraftingHandler(new CraftingManager());
|
||||
|
||||
DungeonHelper.initialize();
|
||||
gatewayGenerator = new GatewayGenerator(properties);
|
||||
GameRegistry.registerWorldGenerator(mod_pocketDim.gatewayGenerator);
|
||||
@@ -317,7 +345,14 @@ public class mod_pocketDim
|
||||
deathTracker.writeToFile();
|
||||
deathTracker = null;
|
||||
worldProperties = null;
|
||||
this.currrentSaveRootDirectory=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;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -335,6 +370,14 @@ 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
|
||||
@@ -345,19 +388,14 @@ 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.loadChunkForcedWorlds(event);
|
||||
ChunkLoaderHelper.loadForcedChunkWorlds(event);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -7,12 +7,13 @@ 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.LinkTypes;
|
||||
import StevenDimDoors.mod_pocketDim.core.DimensionType;
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
||||
@@ -20,7 +21,6 @@ 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,6 +59,15 @@ 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>();
|
||||
@@ -82,7 +91,17 @@ public class DDSaveHandler
|
||||
{
|
||||
linksToUnpack.addAll(packedDim.Links);
|
||||
}
|
||||
return unpackDimData(packedDims) && unpackLinkData(linksToUnpack);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +158,7 @@ public class DDSaveHandler
|
||||
}
|
||||
if(isMissing)
|
||||
{
|
||||
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));
|
||||
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));
|
||||
packedDims.put(packedDim.ID, packedDim);
|
||||
}
|
||||
return children;
|
||||
@@ -157,12 +176,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, packedDim.IsDungeon, 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,type, 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
|
||||
@@ -171,7 +190,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, fosterParent.IsDungeon, 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, type, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails));
|
||||
packedDims.put(fosterParent.ID, fosterParent);
|
||||
}
|
||||
|
||||
@@ -190,18 +209,14 @@ public class DDSaveHandler
|
||||
if(packedLink.parent.equals(fakePoint))
|
||||
{
|
||||
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension());
|
||||
int linkType = packedLink.tail.linkType;
|
||||
LinkType linkType = LinkType.getLinkTypeFromIndex(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);
|
||||
DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation, packedLink.lock);
|
||||
Point4D destination = packedLink.tail.destination;
|
||||
if(destination!=null)
|
||||
{
|
||||
PocketManager.getDimensionData(destination.getDimension()).setDestination(link, destination.getX(),destination.getY(),destination.getZ());
|
||||
PocketManager.createDimensionDataDangerously(destination.getDimension()).setLinkDestination(link, destination.getX(),destination.getY(),destination.getZ());
|
||||
}
|
||||
unpackedLinks.add(packedLink);
|
||||
}
|
||||
@@ -213,10 +228,10 @@ public class DDSaveHandler
|
||||
{
|
||||
for(PackedLinkData packedLink : linksToUnpack)
|
||||
{
|
||||
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension());
|
||||
NewDimData data = PocketManager.createDimensionDataDangerously(packedLink.source.getDimension());
|
||||
if(data.getLink(packedLink.parent)!=null)
|
||||
{
|
||||
data.createChildLink(packedLink.source.getX(), packedLink.source.getY(), packedLink.source.getZ(), data.getLink(packedLink.parent));
|
||||
data.createChildLink(packedLink.source, data.getLink(packedLink.parent), packedLink.lock);
|
||||
}
|
||||
unpackedLinks.add(packedLink);
|
||||
}
|
||||
@@ -270,6 +285,9 @@ 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();
|
||||
@@ -312,6 +330,32 @@ 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
|
||||
@@ -378,7 +422,6 @@ public class DDSaveHandler
|
||||
|
||||
public static List<Integer> readBlacklist(File blacklistFile, BlacklistProcessor reader)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
return reader.readFromFile(blacklistFile);
|
||||
@@ -388,6 +431,18 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,33 +4,53 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
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.Point3D;
|
||||
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.Point4D;
|
||||
import StevenDimDoors.mod_pocketDim.util.JSONValidator;
|
||||
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;
|
||||
|
||||
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.createDImDataFromJson(reader);
|
||||
PackedDimData data = this.readDimDataJson(reader);
|
||||
reader.close();
|
||||
return data;
|
||||
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
throw new ConfigurationProcessingException("Could not read packedDimData");
|
||||
@@ -42,259 +62,132 @@ public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
|
||||
public void writeToStream(OutputStream outputStream, PackedDimData data)
|
||||
throws ConfigurationProcessingException
|
||||
{
|
||||
/** 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
|
||||
*/
|
||||
|
||||
//create a json object from a packedDimData instance
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
Gson gson = gsonBuilder.setPrettyPrinting().create();
|
||||
gsonBuilder.setPrettyPrinting();
|
||||
Gson gson = gsonBuilder.create();
|
||||
JsonElement ele = gson.toJsonTree(data);
|
||||
|
||||
try
|
||||
{
|
||||
outputStream.write(gson.toJson(data).getBytes("UTF-8"));
|
||||
//ensure our json object corresponds to our schema
|
||||
JSONValidator.validate(getSaveDataSchema(ele.getAsJsonObject()), ele);
|
||||
outputStream.write(gson.toJson(ele).getBytes("UTF-8"));
|
||||
outputStream.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (Exception 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");
|
||||
throw new ConfigurationProcessingException("Could not access save data");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nightmare method that takes a JsonReader pointed at a serialized instance of PackedDimData
|
||||
* validates the save file against it's current version, then updates and validates it again if it needs it
|
||||
* then it loads it
|
||||
* @param reader
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public PackedDimData createDImDataFromJson(JsonReader reader) throws IOException
|
||||
public PackedDimData readDimDataJson(JsonReader reader) throws IOException
|
||||
{
|
||||
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>();
|
||||
//read the save file into a Json element
|
||||
JsonElement ele = jsonParser.parse(reader);
|
||||
|
||||
reader.beginObject();
|
||||
//get the schema that corresponds to the save file's listed version number
|
||||
JsonObject schema = this.getSaveDataSchema(ele.getAsJsonObject());
|
||||
|
||||
reader.nextName();
|
||||
if (reader.nextLong() != PackedDimData.SAVE_DATA_VERSION_ID)
|
||||
{
|
||||
throw new IOException("Save data version mismatch");
|
||||
//validate the save file against its schema
|
||||
JSONValidator.validate(schema, ele);
|
||||
|
||||
//handle updating old save data
|
||||
ele = processSaveData(schema, ele.getAsJsonObject());
|
||||
|
||||
//convert the updated and verified json into an instance of PackedDimData
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
return gsonBuilder.create().fromJson(ele, PackedDimData.class);
|
||||
}
|
||||
|
||||
reader.nextName();
|
||||
ID = reader.nextInt();
|
||||
|
||||
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"))
|
||||
/**
|
||||
* Gets the schema that corresponds to a version of our save data
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public JsonObject getSaveDataSchema(JsonObject obj)
|
||||
{
|
||||
Dungeon = createDungeonDataFromJson(reader);
|
||||
reader.nextName();
|
||||
JsonObject schema = this.SAVE_DATA_SCHEMA.get(obj.get(JSON_VERSION_PROPERTY_NAME).getAsInt());
|
||||
|
||||
if(schema == null)
|
||||
{
|
||||
throw new IllegalStateException("Invalid save data version");
|
||||
}
|
||||
|
||||
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);
|
||||
return schema;
|
||||
}
|
||||
|
||||
private Point3D createPointFromJson(JsonReader reader) throws IOException
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
reader.beginObject();
|
||||
InputStream in = this.getClass().getResourceAsStream(path);
|
||||
JsonReader reader = new JsonReader(new InputStreamReader(in));
|
||||
|
||||
reader.nextName();
|
||||
int x = reader.nextInt();
|
||||
|
||||
reader.nextName();
|
||||
int y = reader.nextInt();
|
||||
|
||||
reader.nextName();
|
||||
int z = reader.nextInt();
|
||||
|
||||
reader.endObject();
|
||||
|
||||
return new Point3D(x,y,z);
|
||||
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");
|
||||
}
|
||||
|
||||
private Point4D createPoint4DFromJson(JsonReader reader) throws IOException
|
||||
{
|
||||
reader.beginObject();
|
||||
|
||||
reader.nextName();
|
||||
int x = reader.nextInt();
|
||||
|
||||
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);
|
||||
return schema;
|
||||
}
|
||||
|
||||
private List<Integer> createIntListFromJson(JsonReader reader) throws IOException
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
List<Integer> list = new ArrayList<Integer>();
|
||||
reader.beginArray();
|
||||
|
||||
while (reader.peek() != JsonToken.END_ARRAY)
|
||||
if(save.get(JSON_VERSION_PROPERTY_NAME).getAsInt()== 982405775)
|
||||
{
|
||||
list.add(reader.nextInt());
|
||||
DimensionType type;
|
||||
|
||||
//see if the dim is a pocket
|
||||
if(save.get("RootID").getAsInt() != save.get("ID").getAsInt())
|
||||
{
|
||||
if(save.get("IsDungeon").getAsBoolean())
|
||||
{
|
||||
type = DimensionType.DUNGEON;
|
||||
}
|
||||
reader.endArray();
|
||||
return list;
|
||||
else
|
||||
{
|
||||
type = DimensionType.POCKET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
type = DimensionType.ROOT;
|
||||
}
|
||||
|
||||
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;
|
||||
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 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;
|
||||
}
|
||||
|
||||
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);
|
||||
JSONValidator.validate(this.getSaveDataSchema(save), save);
|
||||
return save;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,16 @@ 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.Point3D;
|
||||
|
||||
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.util.Point4D;
|
||||
|
||||
public class OldSaveImporter
|
||||
@@ -39,35 +38,83 @@ 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 = new ArrayList<Integer>();
|
||||
List<Integer> childDims;
|
||||
if(parentChildMapping.containsKey(data.dimID))
|
||||
{
|
||||
childDims =parentChildMapping.get(data.dimID);
|
||||
}
|
||||
else
|
||||
{
|
||||
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, link.linkOrientation);
|
||||
PackedLinkTail tail = new PackedLinkTail(destintion, LinkType.NORMAL);
|
||||
List<Point3D> children = new ArrayList<Point3D>();
|
||||
|
||||
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children);
|
||||
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children, null);
|
||||
|
||||
newPackedLinkData.add(newPackedLink);
|
||||
allPackedLinks.add(newPackedLink);
|
||||
|
||||
}
|
||||
PackedDimData dim;
|
||||
DimensionType type;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
newPackedDimData.put(dim.ID,dim);
|
||||
}
|
||||
|
||||
DDSaveHandler.unpackDimData(newPackedDimData);
|
||||
DDSaveHandler.unpackLinkData(allPackedLinks);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@ 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 long SAVE_DATA_VERSION_ID = 982405775L;
|
||||
public final static int SAVE_DATA_VERSION_ID = 100;
|
||||
public final long SAVE_DATA_VERSION_ID_INSTANCE = SAVE_DATA_VERSION_ID;
|
||||
public final int ID;
|
||||
public final boolean IsDungeon;
|
||||
public final int DimensionType;
|
||||
public final boolean IsFilled;
|
||||
public final int Depth;
|
||||
public final int PackDepth;
|
||||
@@ -26,7 +27,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,
|
||||
boolean isDungeon, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
|
||||
DimensionType type, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
|
||||
List<PackedLinkTail> tails)
|
||||
{
|
||||
ID = id;
|
||||
@@ -35,7 +36,7 @@ public class PackedDimData
|
||||
ParentID = parentID;
|
||||
RootID = rootID;
|
||||
Orientation = orientation;
|
||||
IsDungeon = isDungeon;
|
||||
DimensionType = type.index;
|
||||
IsFilled = isFilled;
|
||||
DungeonData = dungeonData;
|
||||
Origin = origin;
|
||||
@@ -49,4 +50,6 @@ public class PackedDimData
|
||||
{
|
||||
return "ID= "+this.ID;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ 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
|
||||
@@ -12,13 +13,15 @@ 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)
|
||||
public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children, DDLock lock)
|
||||
{
|
||||
this.source=source;
|
||||
this.parent=parent;
|
||||
this.tail=tail;
|
||||
this.orientation=orientation;
|
||||
this.children=children;
|
||||
this.lock = lock;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package StevenDimDoors.mod_pocketDim.saving;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.core.LinkType;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
|
||||
public class PackedLinkTail
|
||||
@@ -7,10 +8,10 @@ public class PackedLinkTail
|
||||
public final Point4D destination;
|
||||
public final int linkType;
|
||||
|
||||
public PackedLinkTail(Point4D destination, int linkType)
|
||||
public PackedLinkTail(Point4D destination, LinkType linkType)
|
||||
{
|
||||
this.destination=destination;
|
||||
this.linkType=linkType;
|
||||
this.linkType=linkType.index;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -70,6 +70,8 @@ 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package StevenDimDoors.mod_pocketDim.ticking;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
@@ -31,7 +30,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
|
||||
{
|
||||
this.properties = properties;
|
||||
this.locations = new ConcurrentLinkedQueue<ChunkLocation>();
|
||||
sender.registerForTicking(this, MONOLITH_SPAWNING_INTERVAL, false);
|
||||
sender.registerReceiver(this, MONOLITH_SPAWNING_INTERVAL, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,7 +64,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
|
||||
limboWorld = PocketManager.loadDimension(properties.LimboDimensionID);
|
||||
}
|
||||
placeMonolithsInLimbo(limboWorld, location.ChunkX, location.ChunkZ);
|
||||
mod_pocketDim.instance.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ,
|
||||
mod_pocketDim.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ,
|
||||
limboWorld, limboWorld.getChunkProvider(), limboWorld.getChunkProvider());
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.ticking;
|
||||
|
||||
public interface IRegularTickSender {
|
||||
|
||||
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart);
|
||||
public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart);
|
||||
public void unregisterReceivers();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,16 @@ 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;
|
||||
@@ -27,26 +21,31 @@ import StevenDimDoors.mod_pocketDim.world.PocketProvider;
|
||||
|
||||
public class MobMonolith extends EntityFlying implements IMob
|
||||
{
|
||||
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;
|
||||
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 float pitchLevel;
|
||||
|
||||
public float aggro = 0;
|
||||
private float soundTime = 0;
|
||||
private byte textureState = 0;
|
||||
|
||||
private int aggroMax;
|
||||
private short aggro = 0;
|
||||
private int soundTime = 0;
|
||||
private final short aggroCap;
|
||||
|
||||
private static DDProperties properties = null;
|
||||
|
||||
public MobMonolith(World par1World)
|
||||
public MobMonolith(World world)
|
||||
{
|
||||
super(par1World);
|
||||
this.setSize(3F, 3F);
|
||||
this.noClip=true;
|
||||
this.aggroMax = rand.nextInt(245)+200;
|
||||
super(world);
|
||||
this.setSize(WIDTH, HEIGHT);
|
||||
this.noClip = true;
|
||||
this.aggroCap = (short) MathHelper.getRandomIntegerInRange(this.rand, MIN_AGGRO_CAP, MAX_AGGRO_CAP);
|
||||
if (properties == null)
|
||||
properties = DDProperties.instance();
|
||||
}
|
||||
@@ -60,16 +59,19 @@ public class MobMonolith extends EntityFlying implements IMob
|
||||
@Override
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (par1DamageSource == DamageSource.inWall)
|
||||
if (par1DamageSource != DamageSource.inWall)
|
||||
{
|
||||
this.posY = posY + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.aggro = this.aggroMax;
|
||||
this.aggro = MAX_AGGRO;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBreatheUnderwater()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getBoundingBox()
|
||||
{
|
||||
@@ -92,7 +94,7 @@ public class MobMonolith extends EntityFlying implements IMob
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(10);
|
||||
this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(57005);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,22 +106,15 @@ public class MobMonolith extends EntityFlying implements IMob
|
||||
@Override
|
||||
public float getEyeHeight()
|
||||
{
|
||||
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);
|
||||
return EYE_HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
|
||||
// Add a short for the aggro level
|
||||
this.dataWatcher.addObject(AGGRO_WATCHER_INDEX, Short.valueOf((short) 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,73 +126,105 @@ 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();
|
||||
|
||||
EntityPlayer entityPlayer = this.worldObj.getClosestPlayerToEntity(this,MAX_AGGRO_RANGE);
|
||||
// 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);
|
||||
|
||||
//need to always manage aggro level, even if player is out of range.
|
||||
this.setAggroLevel(entityPlayer);
|
||||
// Change orientation and face a player if one is in range
|
||||
if (player != null)
|
||||
{
|
||||
this.facePlayer(player);
|
||||
if (!this.worldObj.isRemote && !(this.worldObj.provider instanceof LimboProvider))
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
//these things only matter if the player is in range.
|
||||
if (entityPlayer != null)
|
||||
if (visibility)
|
||||
{
|
||||
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)
|
||||
// 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))
|
||||
{
|
||||
Point4D destination = LimboProvider.getLimboSkySpawn(entityPlayer, properties);
|
||||
DDTeleporter.teleportEntity(entityPlayer, destination, false);
|
||||
this.aggro = 0;
|
||||
entityPlayer.worldObj.playSoundAtEntity(entityPlayer,mod_pocketDim.modid+":crack",13, 1);
|
||||
Point4D destination = LimboProvider.getLimboSkySpawn(player, properties);
|
||||
DDTeleporter.teleportEntity(player, destination, false);
|
||||
player.worldObj.playSoundAtEntity(player, mod_pocketDim.modid + ":crack", 13, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setAggroLevel(EntityPlayer player)
|
||||
private void updateAggroLevel(EntityPlayer player, boolean visibility)
|
||||
{
|
||||
//aggro constantly decreases at a rate that varies with the current amount of aggro.
|
||||
if(aggro > 0)
|
||||
// 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)
|
||||
{
|
||||
this.aggro = this.aggro -(this.aggro/25);
|
||||
}
|
||||
if(player != null)
|
||||
// Server side...
|
||||
// Rapidly increase the aggro level if this Monolith can see the player
|
||||
if (visibility)
|
||||
{
|
||||
//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+=1.5;
|
||||
aggro++;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.spawnParticles(player);
|
||||
aggro+=3;
|
||||
// Aggro increases faster outside of Limbo
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//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)
|
||||
public int getTextureState()
|
||||
{
|
||||
textureState = TEXTURE_STATES;
|
||||
}
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf(this.textureState));
|
||||
}
|
||||
// Determine texture state from aggro progress
|
||||
return MathHelper.clamp_int(MAX_TEXTURE_STATE * aggro / MAX_AGGRO, 0, MAX_TEXTURE_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,28 +233,29 @@ public class MobMonolith extends EntityFlying implements IMob
|
||||
*/
|
||||
private void playSounds(EntityPlayer entityPlayer)
|
||||
{
|
||||
float aggroPercent = (aggro/MAX_AGGRO);
|
||||
if(this.soundTime<=0)
|
||||
float aggroPercent = this.getAggroProgress();
|
||||
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>.70)&&this.soundTime<100)
|
||||
if ((aggroPercent > 0.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>.90)&&this.soundTime<200)
|
||||
if ((aggroPercent > 0.80) && 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)
|
||||
{
|
||||
for (int i = 1; i < (10*(aggro/MAX_AGGRO)); ++i)
|
||||
int count = 10 * aggro / MAX_AGGRO;
|
||||
for (int i = 1; i < count; ++i)
|
||||
{
|
||||
player.worldObj.spawnParticle("portal", player.posX + (this.rand.nextDouble() - 0.5D) * this.width,
|
||||
player.posY + this.rand.nextDouble() * player.height - 0.75D,
|
||||
@@ -237,43 +265,38 @@ public class MobMonolith extends EntityFlying implements IMob
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void faceEntity(Entity par1Entity, float par2, float par3)
|
||||
public float getAggroProgress()
|
||||
{
|
||||
double d0 = par1Entity.posX - this.posX;
|
||||
double d1 = par1Entity.posZ - this.posZ;
|
||||
double d2 = (par1Entity.posY + par1Entity.getEyeHeight()) - (this.posY +this.getEyeHeight());
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@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);
|
||||
this.rotationYawHead = f2;
|
||||
this.renderYawOffset = this.rotationYaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
public void writeEntityToNBT(NBTTagCompound rootTag)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.soundTime = par1NBTTagCompound.getFloat("soundTime");
|
||||
super.writeEntityToNBT(rootTag);
|
||||
rootTag.setInteger("Aggro", this.aggro);
|
||||
}
|
||||
|
||||
//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
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -282,7 +305,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)
|
||||
{
|
||||
@@ -302,9 +325,4 @@ 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;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +1,121 @@
|
||||
package StevenDimDoors.mod_pocketDim.ticking;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
||||
import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
|
||||
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 {
|
||||
|
||||
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks
|
||||
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5;
|
||||
// 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 Random random = new Random();
|
||||
|
||||
public RiftRegenerator(IRegularTickSender sender)
|
||||
private long tickCount = 0;
|
||||
private PriorityQueue<RiftTicket> ticketQueue;
|
||||
private BlockRift blockRift;
|
||||
|
||||
public RiftRegenerator(IRegularTickSender sender, BlockRift blockRift)
|
||||
{
|
||||
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
|
||||
this.ticketQueue = new PriorityQueue<RiftTicket>();
|
||||
this.blockRift = blockRift;
|
||||
sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyTick()
|
||||
{
|
||||
regenerateRiftsInLoadedWorlds();
|
||||
processTicketQueue();
|
||||
tickCount++;
|
||||
}
|
||||
|
||||
private static void regenerateRiftsInLoadedWorlds()
|
||||
public void scheduleSlowRegeneration(DimLink link)
|
||||
{
|
||||
// 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());
|
||||
scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY);
|
||||
}
|
||||
|
||||
if (world != null)
|
||||
public void scheduleSlowRegeneration(int x, int y, int z, World world)
|
||||
{
|
||||
for (int count = 0; count < RIFTS_REGENERATED_PER_DIMENSION; count++)
|
||||
scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_SLOW_DELAY, MAX_SLOW_DELAY);
|
||||
}
|
||||
|
||||
public void scheduleFastRegeneration(int x, int y, int z, World world)
|
||||
{
|
||||
DimLink link = dimension.getRandomLink();
|
||||
Point4D source = link.source();
|
||||
mod_pocketDim.blockRift.regenerateRift(world, source.getX(), source.getY(), source.getZ(), random);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,26 +7,31 @@ import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
|
||||
import cpw.mods.fml.common.ITickHandler;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
|
||||
public class CommonTickHandler implements ITickHandler, IRegularTickSender
|
||||
public class ServerTickHandler implements ITickHandler, IRegularTickSender
|
||||
{
|
||||
private static final String PROFILING_LABEL = "Dimensional Doors: Common Tick";
|
||||
private static final String PROFILING_LABEL = "Dimensional Doors: Server Tick";
|
||||
|
||||
private int tickCount = 0;
|
||||
private ArrayList<RegularTickReceiverInfo> receivers;
|
||||
|
||||
|
||||
public CommonTickHandler()
|
||||
public ServerTickHandler()
|
||||
{
|
||||
this.receivers = new ArrayList<RegularTickReceiverInfo>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart)
|
||||
public void registerReceiver(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)
|
||||
{
|
||||
@@ -0,0 +1,13 @@
|
||||
package StevenDimDoors.mod_pocketDim.tileentities;
|
||||
import java.util.Random;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public abstract class DDTileEntityBase extends TileEntity
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return an array of floats representing RGBA color where 1.0 = 255.
|
||||
*/
|
||||
public abstract float[] getRenderColor(Random rand);
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user