Refactored jump logic
Added separate structures for ship definition Added separate structures for compatibility with ArsMagica2, OpenComputers and ImmersiveEngineering Added rotation support for blocks, tile entities, entities and chunkloading
This commit is contained in:
parent
33dbd82837
commit
68f050235e
14 changed files with 1260 additions and 501 deletions
File diff suppressed because it is too large
Load diff
39
src/main/java/cr0s/warpdrive/api/IBlockTransformer.java
Normal file
39
src/main/java/cr0s/warpdrive/api/IBlockTransformer.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public interface IBlockTransformer {
|
||||
// Return true if this transformer is applicable to that TileEntity.
|
||||
boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity);
|
||||
|
||||
// Called when preparing to save a ship structure.
|
||||
// Use this to prevent jump during critical events/animations.
|
||||
@Deprecated
|
||||
boolean isJumpReady(final TileEntity tileEntity);
|
||||
|
||||
// Called when saving a ship structure.
|
||||
// Use this to save external data in the ship schematic.
|
||||
// You don't need to save Block and TileEntity data here, it's already covered.
|
||||
// Warning: do NOT assume that the ship will be removed!
|
||||
NBTBase saveExternals(final TileEntity tileEntity);
|
||||
|
||||
// Called when removing the original ship structure.
|
||||
// Use this to prevents drops, clear energy networks, etc.
|
||||
// Block and TileEntity will be removed right after this call.
|
||||
// When moving, the new ship is placed first.
|
||||
void remove(TileEntity tileEntity);
|
||||
|
||||
// Called when restoring a ship in the world.
|
||||
// Use this to apply metadata & NBT rotation, right before block & tile entity placement.
|
||||
// Use priority placement to ensure dependent blocks are placed first.
|
||||
// Warning: do NOT place the block or tile entity!
|
||||
int rotate(final Block block, int metadata, NBTTagCompound nbtTileEntity, final byte rotationSteps, final float rotationYaw);
|
||||
|
||||
// Called when placing back a ship in the world.
|
||||
// Use this to restore external data from the ship schematic, right after block & tile entity placement.
|
||||
// Use priority placement to ensure dependent blocks are placed first.
|
||||
void restoreExternals(TileEntity tileEntity, ITransformation transformation, NBTBase nbtBase);
|
||||
}
|
35
src/main/java/cr0s/warpdrive/api/IEntityTransformer.java
Normal file
35
src/main/java/cr0s/warpdrive/api/IEntityTransformer.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
|
||||
@Deprecated
|
||||
public interface IEntityTransformer {
|
||||
// Return true if this transformer is applicable to that Entity.
|
||||
boolean isApplicable(Entity entity);
|
||||
|
||||
// Called when preparing to save a ship structure.
|
||||
// Use this to prevent jump during critical events/animations.
|
||||
boolean isJumpReady(Entity entity);
|
||||
|
||||
// Called when saving a ship structure.
|
||||
// Use this to save external data in the ship schematic.
|
||||
// You don't need to save entity data here, it's already covered.
|
||||
// Warning: do NOT assume that the ship will be removed!
|
||||
NBTBase saveExternals(Entity entity);
|
||||
|
||||
// Called when removing the original ship structure.
|
||||
// Use this to prevents drops, clear energy networks, etc.
|
||||
// Entity will be removed right after this call.
|
||||
void remove(Entity entity);
|
||||
|
||||
// Called when restoring a ship in the world.
|
||||
// Use this to apply entity rotation, right before entity placement.
|
||||
// Warning: do NOT spawn the entity!
|
||||
short rotate(NBTBase nbtEntity, final byte rotationSteps, final float rotationYaw);
|
||||
|
||||
// Called when placing back a ship in the world.
|
||||
// Use this to restore external data from the ship schematic, right after entity placement.
|
||||
// Use priority placement to ensure dependent blocks are placed first.
|
||||
void restoreExternals(Entity entity, ITransformation transformation, NBTBase nbtBase);
|
||||
}
|
23
src/main/java/cr0s/warpdrive/api/ITransformation.java
Normal file
23
src/main/java/cr0s/warpdrive/api/ITransformation.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface ITransformation {
|
||||
|
||||
World getTargetWorld();
|
||||
|
||||
byte getRotationSteps();
|
||||
|
||||
float getRotationYaw();
|
||||
|
||||
Vec3 apply(final double sourceX, final double sourceY, final double sourceZ);
|
||||
|
||||
ChunkCoordinates apply(final int sourceX, final int sourceY, final int sourceZ);
|
||||
|
||||
ChunkCoordinates apply(final TileEntity tileEntity);
|
||||
|
||||
ChunkCoordinates apply(final ChunkCoordinates chunkCoordinates);
|
||||
}
|
|
@ -25,6 +25,7 @@ import cr0s.warpdrive.block.movement.TileEntityShipCore;
|
|||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.JumpBlock;
|
||||
import cr0s.warpdrive.data.Transformation;
|
||||
import cr0s.warpdrive.data.Vector3;
|
||||
import cr0s.warpdrive.network.PacketHandler;
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
|
@ -159,25 +160,26 @@ public class TileEntityShipScanner extends TileEntityAbstractEnergy {
|
|||
|
||||
for (int index = 0; index < blocks; index++) {
|
||||
if (currentDeployIndex >= blocksToDeployCount) {
|
||||
isDeploying = false;
|
||||
isDeploying = false;
|
||||
setActive(false); // disable scanner
|
||||
break;
|
||||
}
|
||||
|
||||
// Deploy single block
|
||||
JumpBlock jb = blocksToDeploy[currentDeployIndex];
|
||||
JumpBlock jumpBlock = blocksToDeploy[currentDeployIndex];
|
||||
|
||||
if (jb != null && !Dictionary.BLOCKS_ANCHOR.contains(jb.block)) {
|
||||
Block blockAtTarget = worldObj.getBlock(targetX + jb.x, targetY + jb.y, targetZ + jb.z);
|
||||
if (jumpBlock != null && !Dictionary.BLOCKS_ANCHOR.contains(jumpBlock.block)) {
|
||||
Block blockAtTarget = worldObj.getBlock(targetX + jumpBlock.x, targetY + jumpBlock.y, targetZ + jumpBlock.z);
|
||||
if (blockAtTarget == Blocks.air || Dictionary.BLOCKS_EXPANDABLE.contains(blockAtTarget)) {
|
||||
jb.deploy(worldObj, targetX, targetY, targetZ);
|
||||
Transformation transformation = new Transformation(null, worldObj, targetX, targetY, targetZ, (byte) 0); // FIXME: need proper ship object here
|
||||
jumpBlock.deploy(worldObj, transformation);
|
||||
|
||||
if (worldObj.rand.nextInt(100) <= 10) {
|
||||
worldObj.playSoundEffect(xCoord + 0.5f, yCoord, zCoord + 0.5f, "warpdrive:lowlaser", 4F, 1F);
|
||||
|
||||
PacketHandler.sendBeamPacket(worldObj,
|
||||
new Vector3(this).translate(0.5D),
|
||||
new Vector3(targetX + jb.x, targetY + jb.y, targetZ + jb.z).translate(0.5D),
|
||||
new Vector3(targetX + jumpBlock.x, targetY + jumpBlock.y, targetZ + jumpBlock.z).translate(0.5D),
|
||||
0f, 1f, 0f, 15, 0, 100);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy {
|
|||
if (cooldownTime > 0) {
|
||||
cooldownTime--;
|
||||
warmupTime = 0;
|
||||
if (cooldownTime == 0) {
|
||||
if (cooldownTime == 0 && controller != null) {
|
||||
controller.cooldownDone();
|
||||
}
|
||||
}
|
||||
|
@ -601,12 +601,12 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy {
|
|||
if (consumeEnergy(calculateRequiredEnergy(currentMode, shipMass, controller.getDistance()), false)) {
|
||||
WarpDrive.logger.info(this + " Moving ship to beacon (" + beaconX + "; " + yCoord + "; " + beaconZ + ")");
|
||||
EntityJump jump = new EntityJump(worldObj, xCoord, yCoord, zCoord, dx, dz, this, false, 1, 0, true, beaconX, yCoord, beaconZ);
|
||||
jump.maxX = maxX;
|
||||
jump.minX = minX;
|
||||
jump.maxZ = maxZ;
|
||||
jump.minZ = minZ;
|
||||
jump.maxY = maxY;
|
||||
jump.minY = minY;
|
||||
jump.ship.maxX = maxX;
|
||||
jump.ship.minX = minX;
|
||||
jump.ship.maxZ = maxZ;
|
||||
jump.ship.minZ = minZ;
|
||||
jump.ship.maxY = maxY;
|
||||
jump.ship.minY = minY;
|
||||
jump.shipLength = shipLength;
|
||||
jump.on = true;
|
||||
worldObj.spawnEntityInWorld(jump);
|
||||
|
@ -771,12 +771,12 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy {
|
|||
if (consumeEnergy(calculateRequiredEnergy(currentMode, shipMass, controller.getDistance()), false)) {
|
||||
WarpDrive.logger.info(this + " Moving ship to a place around gate '" + targetGate.name + "' (" + destX + "; " + destY + "; " + destZ + ")");
|
||||
EntityJump jump = new EntityJump(worldObj, xCoord, yCoord, zCoord, dx, dz, this, false, 1, 0, true, destX, destY, destZ);
|
||||
jump.maxX = maxX;
|
||||
jump.minX = minX;
|
||||
jump.maxZ = maxZ;
|
||||
jump.minZ = minZ;
|
||||
jump.maxY = maxY;
|
||||
jump.minY = minY;
|
||||
jump.ship.maxX = maxX;
|
||||
jump.ship.minX = minX;
|
||||
jump.ship.maxZ = maxZ;
|
||||
jump.ship.minZ = minZ;
|
||||
jump.ship.maxY = maxY;
|
||||
jump.ship.minY = minY;
|
||||
jump.shipLength = shipLength;
|
||||
jump.on = true;
|
||||
worldObj.spawnEntityInWorld(jump);
|
||||
|
@ -854,12 +854,12 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy {
|
|||
}
|
||||
EntityJump jump = new EntityJump(worldObj, xCoord, yCoord, zCoord, dx, dz, this, (currentMode == ShipCoreMode.HYPERSPACE), distance, direction,
|
||||
false, 0, 0, 0);
|
||||
jump.maxX = maxX;
|
||||
jump.minX = minX;
|
||||
jump.maxZ = maxZ;
|
||||
jump.minZ = minZ;
|
||||
jump.maxY = maxY;
|
||||
jump.minY = minY;
|
||||
jump.ship.maxX = maxX;
|
||||
jump.ship.minX = minX;
|
||||
jump.ship.maxZ = maxZ;
|
||||
jump.ship.minZ = minZ;
|
||||
jump.ship.maxY = maxY;
|
||||
jump.ship.minY = minY;
|
||||
jump.shipLength = shipLength;
|
||||
jump.on = true;
|
||||
worldObj.spawnEntityInWorld(jump);
|
||||
|
@ -1150,7 +1150,7 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy {
|
|||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s \'%s\' @ \'%s\' %d, %d, %d",
|
||||
"%s \'%s\' @ \'%s\' (%d %d %d)",
|
||||
new Object[] { getClass().getSimpleName(), shipName, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
|
||||
Integer.valueOf(xCoord), Integer.valueOf(yCoord), Integer.valueOf(zCoord) });
|
||||
}
|
||||
|
|
104
src/main/java/cr0s/warpdrive/compat/CompatArsMagica2.java
Normal file
104
src/main/java/cr0s/warpdrive/compat/CompatArsMagica2.java
Normal file
|
@ -0,0 +1,104 @@
|
|||
package cr0s.warpdrive.compat;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import am2.api.power.IPowerNode;
|
||||
import am2.power.PowerNodeRegistry;
|
||||
import cpw.mods.fml.common.Optional;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class CompatArsMagica2 implements IBlockTransformer {
|
||||
|
||||
public static void register() {
|
||||
WarpDriveConfig.registerBlockTransformer("arsmagica2", new CompatArsMagica2());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity) {
|
||||
return tileEntity instanceof IPowerNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJumpReady(final TileEntity tileEntity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "arsmagica2")
|
||||
public NBTBase saveExternals(final TileEntity tileEntity) {
|
||||
if (tileEntity instanceof IPowerNode) {
|
||||
NBTBase nbtArsMagica2 = PowerNodeRegistry.For(tileEntity.getWorldObj()).getDataCompoundForNode((IPowerNode) tileEntity);
|
||||
return nbtArsMagica2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "arsmagica2")
|
||||
public void remove(TileEntity tileEntity) {
|
||||
PowerNodeRegistry.For(tileEntity.getWorldObj()).removePowerNode((IPowerNode) tileEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rotate(final Block block, final int metadata, NBTTagCompound nbtTileEntity, final byte rotationSteps, final float rotationYaw) {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "arsmagica2")
|
||||
public void restoreExternals(TileEntity tileEntity, ITransformation transformation, NBTBase nbtBase) {
|
||||
NBTTagCompound nbtTagCompound = (NBTTagCompound) nbtBase;
|
||||
|
||||
// powerAmounts
|
||||
// (no changes)
|
||||
|
||||
// powerPathList
|
||||
NBTTagList powerPathList = nbtTagCompound.getTagList("powerPathList", Constants.NBT.TAG_COMPOUND);
|
||||
if (powerPathList != null) {
|
||||
for (int powerPathIndex = 0; powerPathIndex < powerPathList.tagCount(); powerPathIndex++) {
|
||||
NBTTagCompound powerPathEntry = (NBTTagCompound) powerPathList.removeTag(0);
|
||||
|
||||
// powerPathList[powerPathIndex].powerType
|
||||
// (no change)
|
||||
|
||||
// powerPathList[powerPathIndex].nodePaths
|
||||
NBTTagList nodePaths = powerPathEntry.getTagList("nodePaths", Constants.NBT.TAG_LIST);
|
||||
if (nodePaths != null) {
|
||||
for (int nodePathIndex = 0; nodePathIndex < nodePaths.tagCount(); nodePathIndex++) {
|
||||
// we can't directly access it, hence removing then adding back later on
|
||||
NBTTagList nodeList = (NBTTagList) nodePaths.removeTag(0);
|
||||
if (nodeList != null) {
|
||||
for (int nodeIndex = 0; nodeIndex < nodeList.tagCount(); nodeIndex++) {
|
||||
NBTTagCompound node = (NBTTagCompound) nodeList.removeTag(0);
|
||||
// read coordinates
|
||||
Vec3 target = transformation.apply(node.getFloat("Vec3_x"), node.getFloat("Vec3_y"), node.getFloat("Vec3_z"));
|
||||
node.setFloat("Vec3_x", (float)target.xCoord);
|
||||
node.setFloat("Vec3_y", (float)target.yCoord);
|
||||
node.setFloat("Vec3_z", (float)target.zCoord);
|
||||
//tack the node on to the power path
|
||||
nodeList.appendTag(node);
|
||||
}
|
||||
nodePaths.appendTag(nodeList);
|
||||
}
|
||||
}
|
||||
powerPathEntry.setTag("nodePaths", nodePaths);
|
||||
}
|
||||
powerPathList.appendTag(powerPathEntry);
|
||||
}
|
||||
nbtTagCompound.setTag("powerPathList", powerPathList);
|
||||
}
|
||||
|
||||
World targetWorld = transformation.getTargetWorld();
|
||||
ChunkCoordinates target = transformation.apply(tileEntity);
|
||||
PowerNodeRegistry.For(targetWorld).setDataCompoundForNode((IPowerNode) targetWorld.getTileEntity(target.posX, target.posY, target.posZ), nbtTagCompound);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package cr0s.warpdrive.compat;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import blusunrize.immersiveengineering.api.energy.IImmersiveConnectable;
|
||||
import blusunrize.immersiveengineering.api.energy.ImmersiveNetHandler;
|
||||
import blusunrize.immersiveengineering.api.energy.ImmersiveNetHandler.Connection;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.world.World;
|
||||
import cpw.mods.fml.common.Optional;
|
||||
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class CompatImmersiveEngineering implements IBlockTransformer {
|
||||
|
||||
private static Class<?> classTileEntityIEBase;
|
||||
|
||||
public static void register() {
|
||||
try {
|
||||
classTileEntityIEBase = Class.forName("blusunrize.immersiveengineering.common.blocks.TileEntityIEBase");
|
||||
WarpDriveConfig.registerBlockTransformer("ImmersiveEngineering", new CompatImmersiveEngineering());
|
||||
} catch(ClassNotFoundException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity) {
|
||||
return tileEntity instanceof IImmersiveConnectable || classTileEntityIEBase.isInstance(tileEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJumpReady(TileEntity tileEntity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "ImmersiveEngineering")
|
||||
public NBTBase saveExternals(final TileEntity tileEntity) {
|
||||
if (tileEntity instanceof IImmersiveConnectable) {
|
||||
ChunkCoordinates node = new ChunkCoordinates(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
|
||||
Collection<Connection> connections = ImmersiveNetHandler.INSTANCE.getConnections(tileEntity.getWorldObj(), node);
|
||||
if (connections != null) {
|
||||
NBTTagList nbtImmersiveEngineering = new NBTTagList();
|
||||
for (Connection connection : connections) {
|
||||
nbtImmersiveEngineering.appendTag(connection.writeToNBT());
|
||||
}
|
||||
ImmersiveNetHandler.INSTANCE.clearConnectionsOriginatingFrom(node, tileEntity.getWorldObj());
|
||||
return nbtImmersiveEngineering;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "ImmersiveEngineering")
|
||||
public void remove(TileEntity tileEntity) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rotate(final Block block, final int metadata, NBTTagCompound nbtTileEntity, final byte rotationSteps, final float rotationYaw) {
|
||||
if (rotationSteps == 0 || !nbtTileEntity.hasKey("facing")) {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
int facing = nbtTileEntity.getInteger("facing");
|
||||
final int[] mrot = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
switch (rotationSteps) {
|
||||
case 1:
|
||||
nbtTileEntity.setInteger("facing", mrot[facing]);
|
||||
return metadata;
|
||||
case 2:
|
||||
nbtTileEntity.setInteger("facing", mrot[mrot[facing]]);
|
||||
return metadata;
|
||||
case 3:
|
||||
nbtTileEntity.setInteger("facing", mrot[mrot[mrot[facing]]]);
|
||||
return metadata;
|
||||
default:
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "ImmersiveEngineering")
|
||||
public void restoreExternals(TileEntity tileEntity, ITransformation transformation, NBTBase nbtBase) {
|
||||
NBTTagList nbtImmersiveEngineering = (NBTTagList) nbtBase;
|
||||
if (nbtImmersiveEngineering == null) {
|
||||
return;
|
||||
}
|
||||
World targetWorld = transformation.getTargetWorld();
|
||||
|
||||
// powerPathList
|
||||
for (int connectionIndex = 0; connectionIndex < nbtImmersiveEngineering.tagCount(); connectionIndex++) {
|
||||
Connection connection = Connection.readFromNBT(nbtImmersiveEngineering.getCompoundTagAt(connectionIndex));
|
||||
connection.start = transformation.apply(connection.start);
|
||||
connection.end = transformation.apply(connection.end);
|
||||
|
||||
ImmersiveNetHandler.INSTANCE.addConnection(targetWorld, new ChunkCoordinates(connection.start.posX, connection.start.posY, connection.start.posZ), connection);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package cr0s.warpdrive.compat;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import cpw.mods.fml.common.Optional;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class CompatIndustrialCraft2 implements IBlockTransformer {
|
||||
|
||||
private static Class<?> classIC2tileEntity;
|
||||
|
||||
public static void register() {
|
||||
try {
|
||||
classIC2tileEntity = Class.forName("ic2.core.block.TileEntityBlock");
|
||||
WarpDriveConfig.registerBlockTransformer("IC2", new CompatIndustrialCraft2());
|
||||
} catch (ClassNotFoundException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity) {
|
||||
return classIC2tileEntity.isInstance(tileEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJumpReady(TileEntity tileEntity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "IC2")
|
||||
public NBTBase saveExternals(final TileEntity tileEntity) {
|
||||
// nothing to do
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "IC2")
|
||||
public void remove(TileEntity tileEntity) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rotate(final Block block, final int metadata, NBTTagCompound nbtTileEntity, final byte rotationSteps, final float rotationYaw) {
|
||||
if (rotationSteps == 0 || !nbtTileEntity.hasKey("facing")) {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
short facing = nbtTileEntity.getShort("facing");
|
||||
final short[] mrot = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
switch (rotationSteps) {
|
||||
case 1:
|
||||
nbtTileEntity.setShort("facing", mrot[facing]);
|
||||
return metadata;
|
||||
case 2:
|
||||
nbtTileEntity.setShort("facing", mrot[mrot[facing]]);
|
||||
return metadata;
|
||||
case 3:
|
||||
nbtTileEntity.setShort("facing", mrot[mrot[mrot[facing]]]);
|
||||
return metadata;
|
||||
default:
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "IC2")
|
||||
public void restoreExternals(TileEntity tileEntity, ITransformation transformation, NBTBase nbtBase) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
77
src/main/java/cr0s/warpdrive/compat/CompatOpenComputers.java
Normal file
77
src/main/java/cr0s/warpdrive/compat/CompatOpenComputers.java
Normal file
|
@ -0,0 +1,77 @@
|
|||
package cr0s.warpdrive.compat;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import cpw.mods.fml.common.Optional;
|
||||
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class CompatOpenComputers implements IBlockTransformer {
|
||||
|
||||
private static Class<?> classTileEntityRotatable;
|
||||
|
||||
public static void register() {
|
||||
try {
|
||||
classTileEntityRotatable = Class.forName("li.cil.oc.common.tileentity.traits.Rotatable");
|
||||
WarpDriveConfig.registerBlockTransformer("OpenComputers", new CompatOpenComputers());
|
||||
} catch(ClassNotFoundException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity) {
|
||||
return classTileEntityRotatable.isInstance(tileEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJumpReady(TileEntity tileEntity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public NBTBase saveExternals(final TileEntity tileEntity) {
|
||||
// nothing to do
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public void remove(TileEntity tileEntity) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rotate(final Block block, final int metadata, NBTTagCompound nbtTileEntity, final byte rotationSteps, final float rotationYaw) {
|
||||
if (rotationSteps == 0 || !nbtTileEntity.hasKey("oc:yaw")) {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
int facing = nbtTileEntity.getInteger("oc:yaw");
|
||||
final int[] mrot = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
switch (rotationSteps) {
|
||||
case 1:
|
||||
nbtTileEntity.setInteger("oc:yaw", mrot[facing]);
|
||||
return metadata;
|
||||
case 2:
|
||||
nbtTileEntity.setInteger("oc:yaw", mrot[mrot[facing]]);
|
||||
return metadata;
|
||||
case 3:
|
||||
nbtTileEntity.setInteger("oc:yaw", mrot[mrot[mrot[facing]]]);
|
||||
return metadata;
|
||||
default:
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public void restoreExternals(TileEntity tileEntity, ITransformation transformation, NBTBase nbtBase) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import java.io.FilenameFilter;
|
|||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
@ -20,6 +21,11 @@ import cpw.mods.fml.common.FMLCommonHandler;
|
|||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.compat.CompatArsMagica2;
|
||||
import cr0s.warpdrive.compat.CompatImmersiveEngineering;
|
||||
import cr0s.warpdrive.compat.CompatIndustrialCraft2;
|
||||
import cr0s.warpdrive.compat.CompatOpenComputers;
|
||||
import cr0s.warpdrive.config.filler.FillerManager;
|
||||
import cr0s.warpdrive.config.structures.StructureManager;
|
||||
import cr0s.warpdrive.config.structures.StructureReference;
|
||||
|
@ -287,6 +293,8 @@ public class WarpDriveConfig {
|
|||
public static float[] HULL_HARDNESS = { 25.0F, 50.0F, 80.0F };
|
||||
public static float[] HULL_BLAST_RESISTANCE = { 60.0F, 90.0F, 120.0F };
|
||||
|
||||
// Block transformers library
|
||||
public static HashMap<String, IBlockTransformer> blockTransformers = null;
|
||||
|
||||
|
||||
public static Block getModBlock(final String mod, final String id) {
|
||||
|
@ -695,9 +703,16 @@ public class WarpDriveConfig {
|
|||
// Dictionary
|
||||
Dictionary.loadConfig(config);
|
||||
|
||||
// Block transformers library
|
||||
blockTransformers = new HashMap();
|
||||
|
||||
config.save();
|
||||
}
|
||||
|
||||
public static void registerBlockTransformer(final String modId, IBlockTransformer blockTransformer) {
|
||||
blockTransformers.put(modId, blockTransformer);
|
||||
}
|
||||
|
||||
public static int clamp(final int min, final int max, final int value) {
|
||||
return Math.min(max, Math.max(value, min));
|
||||
}
|
||||
|
@ -715,6 +730,7 @@ public class WarpDriveConfig {
|
|||
isIndustrialCraft2loaded = Loader.isModLoaded("IC2");
|
||||
if (isIndustrialCraft2loaded) {
|
||||
loadIC2();
|
||||
CompatIndustrialCraft2.register();
|
||||
}
|
||||
|
||||
isComputerCraftLoaded = Loader.isModLoaded("ComputerCraft");
|
||||
|
@ -726,8 +742,17 @@ public class WarpDriveConfig {
|
|||
isThermalExpansionLoaded = Loader.isModLoaded("ThermalExpansion");
|
||||
isAppliedEnergistics2Loaded = Loader.isModLoaded("appliedenergistics2");
|
||||
isOpenComputersLoaded = Loader.isModLoaded("OpenComputers");
|
||||
if (isOpenComputersLoaded) {
|
||||
CompatOpenComputers.register();
|
||||
}
|
||||
isArsMagica2Loaded = Loader.isModLoaded("arsmagica2");
|
||||
if (isArsMagica2Loaded) {
|
||||
CompatArsMagica2.register();
|
||||
}
|
||||
isImmersiveEngineeringLoaded = Loader.isModLoaded("ImmersiveEngineering");
|
||||
if (isImmersiveEngineeringLoaded) {
|
||||
CompatImmersiveEngineering.register();
|
||||
}
|
||||
isGregTech5loaded = false;
|
||||
if (Loader.isModLoaded("gregtech")) {
|
||||
String gregTechVersion = FMLCommonHandler.instance().findContainerFor("gregtech").getVersion();
|
||||
|
|
|
@ -1,17 +1,53 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockBed;
|
||||
import net.minecraft.block.BlockButton;
|
||||
import net.minecraft.block.BlockChest;
|
||||
import net.minecraft.block.BlockCocoa;
|
||||
import net.minecraft.block.BlockDispenser;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
import net.minecraft.block.BlockEndPortalFrame;
|
||||
import net.minecraft.block.BlockEnderChest;
|
||||
import net.minecraft.block.BlockFenceGate;
|
||||
import net.minecraft.block.BlockFurnace;
|
||||
import net.minecraft.block.BlockHopper;
|
||||
import net.minecraft.block.BlockHugeMushroom;
|
||||
import net.minecraft.block.BlockLadder;
|
||||
import net.minecraft.block.BlockLever;
|
||||
import net.minecraft.block.BlockLog;
|
||||
import net.minecraft.block.BlockPistonBase;
|
||||
import net.minecraft.block.BlockPistonExtension;
|
||||
import net.minecraft.block.BlockPistonMoving;
|
||||
import net.minecraft.block.BlockPortal;
|
||||
import net.minecraft.block.BlockPumpkin;
|
||||
import net.minecraft.block.BlockRailBase;
|
||||
import net.minecraft.block.BlockRedstoneDiode;
|
||||
import net.minecraft.block.BlockSign;
|
||||
import net.minecraft.block.BlockSkull;
|
||||
import net.minecraft.block.BlockStairs;
|
||||
import net.minecraft.block.BlockTorch;
|
||||
import net.minecraft.block.BlockTrapDoor;
|
||||
import net.minecraft.block.BlockTripWireHook;
|
||||
import net.minecraft.block.BlockVine;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.block.detection.BlockMonitor;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.config.filler.Filler;
|
||||
|
||||
|
@ -23,8 +59,7 @@ public class JumpBlock {
|
|||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
public NBTTagCompound nbtArsMagica2;
|
||||
public NBTTagList nbtImmersiveEngineering;
|
||||
public HashMap<String, NBTBase> externals;
|
||||
|
||||
public JumpBlock() {
|
||||
}
|
||||
|
@ -45,6 +80,14 @@ public class JumpBlock {
|
|||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
|
||||
// save externals
|
||||
for (Entry<String, IBlockTransformer> entryBlockTransformer : WarpDriveConfig.blockTransformers.entrySet()) {
|
||||
if (entryBlockTransformer.getValue().isApplicable(block, blockMeta, tileEntity)) {
|
||||
NBTBase nbtBase = entryBlockTransformer.getValue().saveExternals(tileEntity);
|
||||
setExternal(entryBlockTransformer.getKey(), nbtBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JumpBlock(Filler filler, int x, int y, int z) {
|
||||
|
@ -60,33 +103,172 @@ public class JumpBlock {
|
|||
this.z = z;
|
||||
}
|
||||
|
||||
public boolean deploy(World targetWorld, int offsetX, int offsetY, int offsetZ) {
|
||||
public NBTBase getExternal(final String modId) {
|
||||
if (externals == null) {
|
||||
return null;
|
||||
}
|
||||
NBTBase nbtExternal = externals.get(modId);
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info("Restoring " + modId + " externals at " + x + " " + y + " " + z + " " + nbtExternal);
|
||||
}
|
||||
if (nbtExternal == null) {
|
||||
return null;
|
||||
}
|
||||
return nbtExternal.copy();
|
||||
}
|
||||
|
||||
public void setExternal(final String modId, final NBTBase nbtExternal) {
|
||||
if (externals == null) {
|
||||
externals = new HashMap();
|
||||
}
|
||||
externals.put(modId, nbtExternal);
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info("Saved " + modId + " externals at " + x + " " + y + " " + z + " " + nbtExternal);
|
||||
}
|
||||
}
|
||||
|
||||
// Return updated metadata from rotating a vanilla block
|
||||
private int getMetadataRotation(NBTTagCompound nbtTileEntity, final byte rotationSteps) {
|
||||
if (rotationSteps == 0) {
|
||||
return blockMeta;
|
||||
}
|
||||
|
||||
final byte[] mrotNone = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
final byte[] mrotRail = { 1, 0, 5, 4, 2, 3, 7, 8, 9, 6, 10, 11, 12, 13, 14, 15 };
|
||||
final byte[] mrotAnvil = { 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 12, 13, 14, 15 };
|
||||
final byte[] mrotFenceGate = { 1, 0, 2, 3, 5, 6, 7, 4, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
final byte[] mrotPumpkin = { 1, 2, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; // Tripwire hook, Pumpkin, Jack-o-lantern
|
||||
final byte[] mrotEndPortalFrame = { 1, 2, 3, 0, 5, 6, 7, 4, 8, 9, 10, 11, 12, 13, 14, 15 }; // EndPortal, doors (open/closed, base/top)
|
||||
final byte[] mrotCocoa = { 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 12, 13, 14, 15 };
|
||||
final byte[] mrotRepeater = { 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12 }; // Repeater (normal/lit), Comparator
|
||||
final byte[] mrotBed = { 1, 2, 3, 0, 4, 5, 6, 7, 9, 10, 11, 8, 12, 13, 14, 15 };
|
||||
final byte[] mrotStair = { 2, 3, 1, 0, 6, 7, 5, 4, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
final byte[] mrotSign = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3 }; // Sign, Skull
|
||||
final byte[] mrotTrapDoor = { 3, 2, 0, 1, 7, 6, 4, 5, 11, 10, 8, 9, 15, 14, 12, 13 };
|
||||
final byte[] mrotLever = { 7, 2, 3, 4, 1, 6, 5, 0, 15, 11, 12, 10, 9, 14, 13, 8 };
|
||||
final byte[] mrotNetherPortal = { 0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
final byte[] mrotVine = { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15 };
|
||||
final byte[] mrotButton = { 0, 3, 4, 2, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; // Button, torch (normal, redstone lit/unlit)
|
||||
final byte[] mrotMushroom = { 0, 3, 6, 9, 2, 5, 8, 1, 4, 7, 10, 11, 12, 13, 14, 15 }; // Red/brown mushroom block
|
||||
final byte[] mrotForgeDirection = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; // Furnace (lit/normal), Dispenser/Dropper, Enderchest, Chest (normal/trapped), Hopper, Ladder, Wall sign
|
||||
final byte[] mrotPiston = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 13, 12, 10, 11, 14, 15 }; // Pistons (sticky/normal, base/head)
|
||||
final byte[] mrotWoodLog = { 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15 };
|
||||
|
||||
byte[] mrot = mrotNone;
|
||||
if (block instanceof BlockRailBase) {
|
||||
mrot = mrotRail;
|
||||
} else if (block instanceof BlockRailBase) {
|
||||
mrot = mrotAnvil;
|
||||
} else if (block instanceof BlockFenceGate) {
|
||||
mrot = mrotFenceGate;
|
||||
} else if (block instanceof BlockPumpkin || block instanceof BlockTripWireHook) {
|
||||
mrot = mrotPumpkin;
|
||||
} else if (block instanceof BlockEndPortalFrame || block instanceof BlockDoor) {
|
||||
mrot = mrotEndPortalFrame;
|
||||
} else if (block instanceof BlockCocoa) {
|
||||
mrot = mrotCocoa;
|
||||
} else if (block instanceof BlockRedstoneDiode) {
|
||||
mrot = mrotRepeater;
|
||||
} else if (block instanceof BlockBed) {
|
||||
mrot = mrotBed;
|
||||
} else if (block instanceof BlockStairs) {
|
||||
mrot = mrotStair;
|
||||
} else if (block instanceof BlockSign) {
|
||||
if (block == Blocks.wall_sign) {
|
||||
mrot = mrotForgeDirection;
|
||||
} else {
|
||||
mrot = mrotSign;
|
||||
}
|
||||
} else if (block instanceof BlockTrapDoor) {
|
||||
mrot = mrotTrapDoor;
|
||||
} else if (block instanceof BlockLever) {
|
||||
mrot = mrotLever;
|
||||
} else if (block instanceof BlockPortal) {
|
||||
mrot = mrotNetherPortal;
|
||||
} else if (block instanceof BlockVine) {
|
||||
mrot = mrotVine;
|
||||
} else if (block instanceof BlockButton || block instanceof BlockTorch) {
|
||||
mrot = mrotButton;
|
||||
} else if (block instanceof BlockHugeMushroom) {
|
||||
mrot = mrotMushroom;
|
||||
} else if (block instanceof BlockFurnace || block instanceof BlockDispenser || block instanceof BlockHopper
|
||||
|| block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockLadder
|
||||
|| block instanceof BlockMonitor) {
|
||||
mrot = mrotForgeDirection;
|
||||
} else if (block instanceof BlockPistonBase || block instanceof BlockPistonExtension || block instanceof BlockPistonMoving) {
|
||||
mrot = mrotPiston;
|
||||
} else if (block instanceof BlockLog) {
|
||||
mrot = mrotWoodLog;
|
||||
} else if (block instanceof BlockSkull) {
|
||||
mrot = mrotNone;
|
||||
short facing = nbtTileEntity.getShort("Rot");
|
||||
switch (rotationSteps) {
|
||||
case 1:
|
||||
nbtTileEntity.setShort("Rot", mrotSign[facing]);
|
||||
break;
|
||||
case 2:
|
||||
nbtTileEntity.setShort("Rot", mrotSign[mrotSign[facing]]);
|
||||
break;
|
||||
case 3:
|
||||
nbtTileEntity.setShort("Rot", mrotSign[mrotSign[mrotSign[facing]]]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (rotationSteps) {
|
||||
case 1:
|
||||
return mrot[blockMeta];
|
||||
case 2:
|
||||
return mrot[mrot[blockMeta]];
|
||||
case 3:
|
||||
return mrot[mrot[mrot[blockMeta]]];
|
||||
default:
|
||||
return blockMeta;
|
||||
}
|
||||
}
|
||||
|
||||
public void deploy(World targetWorld, ITransformation transformation) {
|
||||
try {
|
||||
int newX = x + offsetX;
|
||||
int newY = y + offsetY;
|
||||
int newZ = z + offsetZ;
|
||||
setBlockNoLight(targetWorld, newX, newY, newZ, block, blockMeta, 2);
|
||||
NBTTagCompound oldnbt = null;
|
||||
if (blockTileEntity != null) {
|
||||
oldnbt = new NBTTagCompound();
|
||||
blockTileEntity.writeToNBT(oldnbt);
|
||||
}
|
||||
int newBlockMeta = blockMeta;
|
||||
if (externals != null) {
|
||||
for (Entry<String, NBTBase> external : externals.entrySet()) {
|
||||
IBlockTransformer blockTransformer = WarpDriveConfig.blockTransformers.get(external.getKey());
|
||||
if (blockTransformer != null) {
|
||||
newBlockMeta = blockTransformer.rotate(block, blockMeta, oldnbt, transformation.getRotationSteps(), transformation.getRotationYaw());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newBlockMeta = getMetadataRotation(oldnbt, transformation.getRotationSteps());
|
||||
}
|
||||
ChunkCoordinates target = transformation.apply(x, y, z);
|
||||
setBlockNoLight(targetWorld, target.posX, target.posY, target.posZ, block, newBlockMeta, 2);
|
||||
|
||||
// Re-schedule air blocks update
|
||||
if (block == WarpDrive.blockAir) {
|
||||
targetWorld.markBlockForUpdate(newX, newY, newZ);
|
||||
targetWorld.scheduleBlockUpdate(newX, newY, newZ, block, 40 + targetWorld.rand.nextInt(20));
|
||||
targetWorld.markBlockForUpdate(target.posX, target.posY, target.posZ);
|
||||
targetWorld.scheduleBlockUpdate(target.posX, target.posY, target.posZ, block, 40 + targetWorld.rand.nextInt(20));
|
||||
}
|
||||
|
||||
NBTTagCompound oldnbt = new NBTTagCompound();
|
||||
if (blockTileEntity != null) {
|
||||
blockTileEntity.writeToNBT(oldnbt);
|
||||
oldnbt.setInteger("x", newX);
|
||||
oldnbt.setInteger("y", newY);
|
||||
oldnbt.setInteger("z", newZ);
|
||||
if (oldnbt != null) {
|
||||
oldnbt.setInteger("x", target.posX);
|
||||
oldnbt.setInteger("y", target.posY);
|
||||
oldnbt.setInteger("z", target.posZ);
|
||||
|
||||
if (oldnbt.hasKey("mainX") && oldnbt.hasKey("mainY") && oldnbt.hasKey("mainZ")) {// Mekanism 6.0.4.44
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info(this + " deploy: TileEntity has mainXYZ");
|
||||
}
|
||||
oldnbt.setInteger("mainX", oldnbt.getInteger("mainX") + offsetX);
|
||||
oldnbt.setInteger("mainY", oldnbt.getInteger("mainY") + offsetY);
|
||||
oldnbt.setInteger("mainZ", oldnbt.getInteger("mainZ") + offsetZ);
|
||||
ChunkCoordinates mainTarget = transformation.apply(oldnbt.getInteger("mainX"), oldnbt.getInteger("mainY"), oldnbt.getInteger("mainZ"));
|
||||
oldnbt.setInteger("mainX", mainTarget.posX);
|
||||
oldnbt.setInteger("mainY", mainTarget.posY);
|
||||
oldnbt.setInteger("mainZ", mainTarget.posZ);
|
||||
}
|
||||
|
||||
if (oldnbt.hasKey("screenData")) {// IC2NuclearControl 2.2.5a
|
||||
|
@ -96,12 +278,14 @@ public class JumpBlock {
|
|||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info(this + " deploy: TileEntity has screenData.min/maxXYZ");
|
||||
}
|
||||
nbtScreenData.setInteger("minX", nbtScreenData.getInteger("minX") + offsetX);
|
||||
nbtScreenData.setInteger("minY", nbtScreenData.getInteger("minY") + offsetY);
|
||||
nbtScreenData.setInteger("minZ", nbtScreenData.getInteger("minZ") + offsetZ);
|
||||
nbtScreenData.setInteger("maxX", nbtScreenData.getInteger("maxX") + offsetX);
|
||||
nbtScreenData.setInteger("maxY", nbtScreenData.getInteger("maxY") + offsetY);
|
||||
nbtScreenData.setInteger("maxZ", nbtScreenData.getInteger("maxZ") + offsetZ);
|
||||
ChunkCoordinates minTarget = transformation.apply(nbtScreenData.getInteger("minX"), nbtScreenData.getInteger("minY"), nbtScreenData.getInteger("minZ"));
|
||||
nbtScreenData.setInteger("minX", minTarget.posX);
|
||||
nbtScreenData.setInteger("minY", minTarget.posY);
|
||||
nbtScreenData.setInteger("minZ", minTarget.posZ);
|
||||
ChunkCoordinates maxTarget = transformation.apply(nbtScreenData.getInteger("maxX"), nbtScreenData.getInteger("maxY"), nbtScreenData.getInteger("maxZ"));
|
||||
nbtScreenData.setInteger("maxX", maxTarget.posX);
|
||||
nbtScreenData.setInteger("maxY", maxTarget.posY);
|
||||
nbtScreenData.setInteger("maxZ", maxTarget.posZ);
|
||||
oldnbt.setTag("screenData", nbtScreenData);
|
||||
}
|
||||
}
|
||||
|
@ -141,11 +325,12 @@ public class JumpBlock {
|
|||
newTileEntity.setWorldObj(targetWorld);
|
||||
newTileEntity.validate();
|
||||
|
||||
targetWorld.setTileEntity(newX, newY, newZ, newTileEntity);
|
||||
targetWorld.setTileEntity(target.posX, target.posY, target.posZ, newTileEntity);
|
||||
if (isForgeMultipart) {
|
||||
WarpDriveConfig.forgeMultipart_tileMultipart_onChunkLoad.invoke(newTileEntity);
|
||||
WarpDriveConfig.forgeMultipart_helper_sendDescPacket.invoke(null, targetWorld, newTileEntity);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
WarpDrive.logger.info(" deploy failed to create new tile entity at " + x + ", " + y + ", " + z + " blockId " + block + ":" + blockMeta);
|
||||
WarpDrive.logger.info("NBT data was " + oldnbt);
|
||||
|
@ -160,10 +345,10 @@ public class JumpBlock {
|
|||
coordinates = " (unknown coordinates)";
|
||||
}
|
||||
WarpDrive.logger.info("moveBlockSimple exception at " + coordinates);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
public static void refreshBlockStateOnClient(World world, int x, int y, int z) {
|
||||
|
|
183
src/main/java/cr0s/warpdrive/data/JumpShip.java
Normal file
183
src/main/java/cr0s/warpdrive/data/JumpShip.java
Normal file
|
@ -0,0 +1,183 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.world.World;
|
||||
import cr0s.warpdrive.EntityJump;
|
||||
import cr0s.warpdrive.LocalProfiler;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.block.movement.TileEntityShipCore;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class JumpShip {
|
||||
public World worldObj;
|
||||
public int coreX;
|
||||
public int coreY;
|
||||
public int coreZ;
|
||||
public int dx;
|
||||
public int dz;
|
||||
public int direction;
|
||||
public int maxX;
|
||||
public int maxZ;
|
||||
public int maxY;
|
||||
public int minX;
|
||||
public int minZ;
|
||||
public int minY;
|
||||
public JumpBlock[] jumpBlocks;
|
||||
public TileEntityShipCore shipCore;
|
||||
public List<MovingEntity> entitiesOnShip;
|
||||
|
||||
public JumpShip() {
|
||||
}
|
||||
|
||||
public void messageToAllPlayersOnShip(EntityJump entityJump, String msg) {
|
||||
if (entitiesOnShip == null) {
|
||||
shipCore.messageToAllPlayersOnShip(msg);
|
||||
} else {
|
||||
WarpDrive.logger.info(entityJump + " messageToAllPlayersOnShip: " + msg);
|
||||
for (MovingEntity me : entitiesOnShip) {
|
||||
if (me.entity instanceof EntityPlayer) {
|
||||
WarpDrive.addChatMessage((EntityPlayer) me.entity, "["
|
||||
+ ((shipCore != null && shipCore.shipName.length() > 0) ? shipCore.shipName : "WarpCore") + "] " + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String saveEntities(EntityJump entityJump) {
|
||||
String result = null;
|
||||
entitiesOnShip = new ArrayList<MovingEntity>();
|
||||
|
||||
AxisAlignedBB axisalignedbb = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX + 0.99D, maxY + 0.99D, maxZ + 0.99D);
|
||||
|
||||
List<Entity> list = entityJump.worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
|
||||
|
||||
for (Entity entity : list) {
|
||||
if (entity == null || (entity instanceof EntityJump)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String id = EntityList.getEntityString(entity);
|
||||
if (Dictionary.ENTITIES_ANCHOR.contains(id)) {
|
||||
result = "Anchor entity " + id + " detected at " + Math.floor(entity.posX) + ", " + Math.floor(entity.posY) + ", " + Math.floor(entity.posZ) + ", aborting jump...";
|
||||
// we need to continue so players are added so they can see the message...
|
||||
continue;
|
||||
}
|
||||
if (Dictionary.ENTITIES_LEFTBEHIND.contains(id)) {
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info("Leaving entity " + id + " behind: " + entity);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info("Adding entity " + id + ": " + entity);
|
||||
}
|
||||
}
|
||||
MovingEntity movingEntity = new MovingEntity(entity);
|
||||
entitiesOnShip.add(movingEntity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setMinMaxes(EntityJump entityJump, int minXV, int maxXV, int minYV, int maxYV, int minZV, int maxZV) {
|
||||
minX = minXV;
|
||||
maxX = maxXV;
|
||||
minY = minYV;
|
||||
maxY = maxYV;
|
||||
minZ = minZV;
|
||||
maxZ = maxZV;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s/%d \'%s\' @ \'%s\' (%d %d %d)",
|
||||
getClass().getSimpleName(), hashCode(),
|
||||
shipCore == null ? "~NULL~" : (shipCore.uuid + ":" + shipCore.shipName),
|
||||
"-", // worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
|
||||
Double.valueOf(coreX), Double.valueOf(coreY), Double.valueOf(coreZ));
|
||||
}
|
||||
|
||||
public int getRealShipVolume_checkBedrock(EntityJump entityJump, StringBuilder reason) {
|
||||
LocalProfiler.start("EntityJump.getRealShipVolume_checkBedrock");
|
||||
int shipVolume = 0;
|
||||
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
Block block = entityJump.worldObj.getBlock(x, y, z);
|
||||
|
||||
// Skipping vanilla air & ignored blocks
|
||||
if (block == Blocks.air || Dictionary.BLOCKS_LEFTBEHIND.contains(block)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
shipVolume++;
|
||||
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info("Block(" + x + ", " + y + ", " + z + ") is " + block.getUnlocalizedName() + "@" + entityJump.worldObj.getBlockMetadata(x, y, z));
|
||||
}
|
||||
|
||||
// Stop on non-movable blocks
|
||||
if (Dictionary.BLOCKS_ANCHOR.contains(block)) {
|
||||
reason.append(block.getUnlocalizedName() + " detected onboard at " + x + ", " + y + ", " + z + ". Aborting.");
|
||||
LocalProfiler.stop();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Abort jump if blocks with TE are connecting to the ship (avoid crash when splitting multi-blocks)
|
||||
for (int x = minX - 1; x <= maxX + 1; x++) {
|
||||
boolean xBorder = (x == minX - 1) || (x == maxX + 1);
|
||||
for (int z = minZ - 1; z <= maxZ + 1; z++) {
|
||||
boolean zBorder = (z == minZ - 1) || (z == maxZ + 1);
|
||||
for (int y = minY - 1; y <= maxY + 1; y++) {
|
||||
boolean yBorder = (y == minY - 1) || (y == maxY + 1);
|
||||
if ((y < 0) || (y > 255)) {
|
||||
continue;
|
||||
}
|
||||
if (!(xBorder || yBorder || zBorder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Block block = worldObj.getBlock(x, y, z);
|
||||
|
||||
// Skipping any air block & ignored blocks
|
||||
if (worldObj.isAirBlock(x, y, z) || Dictionary.BLOCKS_LEFTBEHIND.contains(block)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skipping non-movable blocks
|
||||
if (Dictionary.BLOCKS_ANCHOR.contains(block)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skipping blocks without tile entities
|
||||
TileEntity tileEntity = worldObj.getTileEntity(x, y, z);
|
||||
if (tileEntity == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
reason.append("Ship snagged by " + block.getLocalizedName() + " at " + x + ", " + y + ", " + z + ". Damage report pending...");
|
||||
worldObj.createExplosion((Entity) null, x, y, z, Math.min(4F * 30, 4F * (shipVolume / 50)), false);
|
||||
LocalProfiler.stop();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LocalProfiler.stop();
|
||||
return shipVolume;
|
||||
}
|
||||
}
|
96
src/main/java/cr0s/warpdrive/data/Transformation.java
Normal file
96
src/main/java/cr0s/warpdrive/data/Transformation.java
Normal file
|
@ -0,0 +1,96 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
|
||||
public class Transformation implements ITransformation {
|
||||
private VectorI sourceCore;
|
||||
private VectorI targetCore;
|
||||
private VectorI move;
|
||||
private byte rotation;
|
||||
private World targetWorld;
|
||||
|
||||
public Transformation(JumpShip ship, World targetWorld, int moveX, int moveY, int moveZ, byte rotation) {
|
||||
sourceCore = new VectorI(ship.coreX, ship.coreY, ship.coreZ);
|
||||
this.targetWorld = targetWorld;
|
||||
move = new VectorI(moveX, moveY, moveZ);
|
||||
targetCore = sourceCore.add(move);
|
||||
this.rotation = (byte) ((rotation + 4) % 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getTargetWorld() {
|
||||
return targetWorld;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getRotationSteps() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRotationYaw() {
|
||||
return 90.0F * rotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 apply(final double sourceX, final double sourceY, final double sourceZ) {
|
||||
if (rotation == 0) {
|
||||
return Vec3.createVectorHelper(sourceX + move.x, sourceY + move.y, sourceZ + move.z);
|
||||
} else {
|
||||
double dX = sourceX - sourceCore.x - 0.5D;
|
||||
double dZ = sourceZ - sourceCore.z - 0.5D;
|
||||
switch (rotation) {
|
||||
case 1:
|
||||
return Vec3.createVectorHelper(targetCore.x + 0.5D - dZ, sourceY + move.y, targetCore.z + 0.5D + dX);
|
||||
case 2:
|
||||
return Vec3.createVectorHelper(targetCore.x + 0.5D - dZ, sourceY + move.y, targetCore.z + 0.5D - dX);
|
||||
case 3:
|
||||
return Vec3.createVectorHelper(targetCore.x + 0.5D + dZ, sourceY + move.y, targetCore.z + 0.5D - dX);
|
||||
default:
|
||||
return null; // dead code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkCoordinates apply(final int sourceX, final int sourceY, final int sourceZ) {
|
||||
if (rotation == 0) {
|
||||
return new ChunkCoordinates(sourceX + move.x, sourceY + move.y, sourceZ + move.z);
|
||||
} else {
|
||||
int dX = sourceX - sourceCore.x;
|
||||
int dZ = sourceZ - sourceCore.z;
|
||||
switch (rotation) {
|
||||
case 1:
|
||||
return new ChunkCoordinates(targetCore.x - dZ, sourceY + move.y, targetCore.z + dX);
|
||||
case 2:
|
||||
return new ChunkCoordinates(targetCore.x - dZ, sourceY + move.y, targetCore.z - dX);
|
||||
case 3:
|
||||
return new ChunkCoordinates(targetCore.x + dZ, sourceY + move.y, targetCore.z - dX);
|
||||
default:
|
||||
return null; // dead code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkCoordinates apply(final TileEntity tileEntity) {
|
||||
return apply(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkCoordinates apply(final ChunkCoordinates chunkCoordinates) {
|
||||
return apply(chunkCoordinates.posX, chunkCoordinates.posY, chunkCoordinates.posZ);
|
||||
}
|
||||
|
||||
public void rotate(Entity entity) {
|
||||
if (rotation == 0) {
|
||||
return;
|
||||
}
|
||||
entity.rotationYaw = (entity.rotationYaw + 270.0F * rotation) % 360.0F - 180.0F;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue