mirror of
https://github.com/GTNewHorizons/TinkersConstruct.git
synced 2026-10-26 14:33:50 +00:00
Signal Bus Release
This commit is contained in:
1 parent
d4bfef708c
commit
eb7cb19441
34 files changed
+5508
-12
No files matched your search
+9
-1
@@ -1,4 +1,12 @@
|
||||
/build/
|
||||
/bin/
|
||||
/download/
|
||||
/src/com/xcompwiz/
|
||||
#Remove OS generated garbage
|
||||
*/.DS_Store
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
Icon?
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
@@ -100,6 +100,9 @@ block.fancybrick.stone.name=Fancy Stone Brick
|
||||
|
||||
tile.rail.wood.name=Wooden Rail
|
||||
|
||||
tile.signalbus.name=Signal Bus
|
||||
tile.signalterminal.name=Signal Terminal
|
||||
|
||||
tile.cloth.white.slab.name=Wool Slab
|
||||
tile.cloth.orange.slab.name=Orange Wool Slab
|
||||
tile.cloth.magenta.slab.name=Magenta Wool Slab
|
||||
@@ -125,7 +128,10 @@ item.oreberry.aluminum.name=Aluminum Oreberry
|
||||
item.oreberry.essence.name=Concentrated Essence Berry
|
||||
|
||||
item.goldenhead.name=Golden Head
|
||||
item.tconstruct.titleicon.name=Spawn
|
||||
item.tconstruct.titleicon.name=Spawn
|
||||
|
||||
item.spoolwire.name=Spool of Wire
|
||||
item.lengthwire.name=Length of Wire
|
||||
|
||||
item.InfiTool.Pickaxe.name=Pickaxe
|
||||
item.InfiTool.Shovel.name=Shovel
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 432 B |
Binary file not shown.
|
After Width: | Height: | Size: 374 B |
Binary file not shown.
|
After Width: | Height: | Size: 357 B |
@@ -13,10 +13,13 @@ import java.util.logging.Logger;
|
||||
import net.minecraft.crash.CallableMinecraftVersion;
|
||||
import net.minecraft.world.gen.structure.MapGenStructureIO;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import tconstruct.blocks.SignalBus;
|
||||
import tconstruct.client.SignalTetherWorldOverlayRenderer;
|
||||
import tconstruct.client.event.EventCloakRender;
|
||||
import tconstruct.common.*;
|
||||
import tconstruct.library.TConstructRegistry;
|
||||
import tconstruct.library.crafting.*;
|
||||
import tconstruct.library.multiblock.MultiblockEventHandler;
|
||||
import tconstruct.library.util.TabTools;
|
||||
import tconstruct.util.*;
|
||||
import tconstruct.util.config.*;
|
||||
@@ -95,6 +98,8 @@ public class TConstruct
|
||||
proxy.addNames();
|
||||
proxy.readManuals();
|
||||
proxy.registerKeys();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new MultiblockEventHandler());
|
||||
|
||||
GameRegistry.registerWorldGenerator(new TBaseWorldGenerator());
|
||||
MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenEventHandler());
|
||||
@@ -135,6 +140,8 @@ public class TConstruct
|
||||
if (event.getSide() == Side.CLIENT)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.register(new EventCloakRender());
|
||||
MinecraftForge.EVENT_BUS.register(TConstruct.instance.content.signalBus);
|
||||
MinecraftForge.EVENT_BUS.register(new SignalTetherWorldOverlayRenderer());
|
||||
}
|
||||
|
||||
content.intermodCommunication();
|
||||
|
||||
@@ -0,0 +1,601 @@
|
||||
package tconstruct.blocks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.naming.Context;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import tconstruct.TConstruct;
|
||||
import tconstruct.blocks.SignalTerminal.TerminalGeometry;
|
||||
import tconstruct.blocks.logic.CastingChannelLogic;
|
||||
import tconstruct.blocks.logic.SignalBusLogic;
|
||||
import tconstruct.blocks.logic.SignalTerminalLogic;
|
||||
import tconstruct.client.block.BlockRenderCastingChannel;
|
||||
import tconstruct.client.block.SignalBusRender;
|
||||
import tconstruct.items.blocks.SignalBusItem;
|
||||
import tconstruct.library.TConstructRegistry;
|
||||
import tconstruct.library.multiblock.IMultiblockMember;
|
||||
import tconstruct.library.multiblock.MultiblockMasterBaseLogic;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.ITileEntityProvider;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.texture.IconRegister;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.ChatMessageComponent;
|
||||
import net.minecraft.util.EnumMovingObjectType;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.ForgeSubscribe;
|
||||
|
||||
public class SignalBus extends Block implements ITileEntityProvider {
|
||||
public static class Geometry {
|
||||
public static double cable_width_min = 0.375D;
|
||||
public static double cable_width_max = 1 - cable_width_min;
|
||||
public static double cable_low_height = 0.2D;
|
||||
public static double cable_low_offset = 0.0D;
|
||||
|
||||
public static double cable_high_height = 1.0D;
|
||||
public static double cable_high_offset = 1 - cable_low_height;
|
||||
|
||||
public static double cable_extend_min = 0.0D;
|
||||
public static double cable_extend_max = 1.0D;
|
||||
|
||||
public static double cable_corner_min = cable_high_offset - 1;
|
||||
public static double cable_corner_max = cable_low_height + 1;
|
||||
|
||||
public static double zfight = 0.0000001D;
|
||||
}
|
||||
|
||||
public static int HITBOXES = 6;
|
||||
|
||||
public Icon[] icons;
|
||||
public String[] textureNames = new String[] { "signalbus" };
|
||||
|
||||
public SignalBus(int par1) {
|
||||
super(par1, Material.circuits);
|
||||
this.setHardness(0.1F);
|
||||
this.setResistance(1);
|
||||
this.setStepSound(soundMetalFootstep);
|
||||
setCreativeTab(TConstructRegistry.blockTab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) {
|
||||
if (par1World.isRemote) { return false; }
|
||||
TileEntity te = par1World.getBlockTileEntity(par2, par3, par4);
|
||||
if (te != null && te instanceof SignalBusLogic) {
|
||||
TConstruct.logger.info(((SignalBusLogic)te).debugString());
|
||||
if (((SignalBusLogic)te).getMultiblockMaster() != null) {
|
||||
TConstruct.logger.info((((SignalBusLogic)te).getMultiblockMaster().debugString()));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborTileChange(World world, int x, int y, int z, int tileX, int tileY, int tileZ) {
|
||||
TileEntity te = world.getBlockTileEntity(tileX, tileY, tileZ);
|
||||
if (te instanceof SignalBusLogic) {
|
||||
if (((SignalBusLogic)te).getMultiblockMaster() != null) {
|
||||
((SignalBusLogic)te).getMultiblockMaster().detachBlock((IMultiblockMember)te, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(World world, int x, int y, int z) {
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te != null && te instanceof SignalBusLogic) {
|
||||
((SignalBusLogic)te).onBlockAdded(world, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public Icon getIcon (int side, int metadata)
|
||||
{
|
||||
return icons[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons (IconRegister iconRegister)
|
||||
{
|
||||
this.icons = new Icon[textureNames.length];
|
||||
|
||||
for (int i = 0; i < this.icons.length; ++i)
|
||||
{
|
||||
this.icons[i] = iconRegister.registerIcon("tinker:" + textureNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void setBlockBoundsBasedOnState (IBlockAccess world, int x, int y, int z)
|
||||
// {
|
||||
// SignalBusLogic tile = (SignalBusLogic) world.getBlockTileEntity(x, y, z);
|
||||
// if (!(tile instanceof SignalBusLogic)) return;
|
||||
// float minX = 0.375F;
|
||||
// float maxX = 0.625F;
|
||||
// float minZ = 0.375F;
|
||||
// float maxZ = 0.625F;
|
||||
// if (tile.isConnected(ForgeDirection.DOWN, ForgeDirection.NORTH))
|
||||
// minZ = 0F;
|
||||
// if (tile.isConnected(ForgeDirection.DOWN, ForgeDirection.SOUTH))
|
||||
// maxZ = 1F;
|
||||
// if (tile.isConnected(ForgeDirection.DOWN, ForgeDirection.WEST))
|
||||
// minX = 0F;
|
||||
// if (tile.isConnected(ForgeDirection.DOWN, ForgeDirection.EAST))
|
||||
// maxX = 1F;
|
||||
//
|
||||
// //this.setBlockBounds(minX, 0.0F, minZ, maxX, 0.2F, maxZ);
|
||||
// this.setBlockBounds(0, 0, 0, 1, 1, 1);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean renderAsNormalBlock ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderType ()
|
||||
{
|
||||
return SignalBusRender.renderID;
|
||||
}
|
||||
|
||||
public void addCollisionBoxesToList (World world, int x, int y, int z, AxisAlignedBB collisionTest, List collisionBoxList, Entity entity)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
for (AxisAlignedBB aabb : getBoxes((SignalBusLogic) te))
|
||||
{
|
||||
if (aabb == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aabb = AxisAlignedBB.getBoundingBox(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ);
|
||||
aabb.minX += x;
|
||||
aabb.minY += y;
|
||||
aabb.minZ += z;
|
||||
aabb.maxX += x;
|
||||
aabb.maxY += y;
|
||||
aabb.maxZ += z;
|
||||
|
||||
if (collisionTest.intersectsWith(aabb))
|
||||
{
|
||||
collisionBoxList.add(aabb);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super.addCollisionBoxesToList(world, x, y, z, collisionTest, collisionBoxList, entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean shouldSideBeRendered (IBlockAccess par1iBlockAccess, int par2, int par3, int par4, int par5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MovingObjectPosition collisionRayTrace (World world, int x, int y, int z, Vec3 start, Vec3 end)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
MovingObjectPosition closest = null;
|
||||
AxisAlignedBB[] boxes = getBoxes((SignalBusLogic)te);
|
||||
|
||||
double closestCalc = Double.MAX_VALUE;
|
||||
double hitDistance = 0D;
|
||||
|
||||
for (int i = 0; i < boxes.length; i++)
|
||||
{
|
||||
if (boxes[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
this.setBlockBounds((float)boxes[i].minX, (float)boxes[i].minY, (float)boxes[i].minZ, (float)boxes[i].maxX, (float)boxes[i].maxY, (float)boxes[i].maxZ);
|
||||
MovingObjectPosition hit = super.collisionRayTrace(world, x, y, z, start, end);
|
||||
if (hit != null)
|
||||
{
|
||||
hitDistance = start.distanceTo(hit.hitVec);
|
||||
if (hitDistance < closestCalc)
|
||||
{
|
||||
closestCalc = hitDistance;
|
||||
closest = hit;
|
||||
}
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static AxisAlignedBB[] getBoxes (SignalBusLogic logic)
|
||||
{
|
||||
boolean placed[] = logic.placedSides();
|
||||
boolean connected[];
|
||||
boolean corners[];
|
||||
boolean renderDir[];
|
||||
|
||||
AxisAlignedBB[] parts = new AxisAlignedBB[HITBOXES];
|
||||
|
||||
double minX;
|
||||
double minY;
|
||||
double minZ;
|
||||
double maxX;
|
||||
double maxY;
|
||||
double maxZ;
|
||||
boolean didRender = false;
|
||||
|
||||
if (placed[ForgeDirection.DOWN.ordinal()])
|
||||
{
|
||||
connected = logic.connectedSides(ForgeDirection.DOWN);
|
||||
corners = logic.getRenderCorners(ForgeDirection.DOWN);
|
||||
renderDir = new boolean[] {
|
||||
(connected[0] || placed[0] || corners[0]),
|
||||
(connected[1] || placed[1] || corners[1]),
|
||||
(connected[2] || placed[2] || corners[2]),
|
||||
(connected[3] || placed[3] || corners[3]),
|
||||
(connected[4] || placed[4] || corners[4]),
|
||||
(connected[5] || placed[5] || corners[5])
|
||||
};
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = Geometry.cable_low_offset;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_low_height;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
parts[0] = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
didRender = true;
|
||||
}
|
||||
if (placed[ForgeDirection.UP.ordinal()])
|
||||
{
|
||||
connected = logic.connectedSides(ForgeDirection.UP);
|
||||
corners = logic.getRenderCorners(ForgeDirection.UP);
|
||||
renderDir = new boolean[] {
|
||||
(connected[0] || placed[0] || corners[0]),
|
||||
(connected[1] || placed[1] || corners[1]),
|
||||
(connected[2] || placed[2] || corners[2]),
|
||||
(connected[3] || placed[3] || corners[3]),
|
||||
(connected[4] || placed[4] || corners[4]),
|
||||
(connected[5] || placed[5] || corners[5])
|
||||
};
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = Geometry.cable_high_offset;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_high_height;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
parts[1] = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
didRender = true;
|
||||
}
|
||||
if (placed[ForgeDirection.NORTH.ordinal()])
|
||||
{
|
||||
connected = logic.connectedSides(ForgeDirection.NORTH);
|
||||
corners = logic.getRenderCorners(ForgeDirection.NORTH);
|
||||
renderDir = new boolean[] {
|
||||
(connected[0] || placed[0] || corners[0]),
|
||||
(connected[1] || placed[1] || corners[1]),
|
||||
(connected[2] || placed[2] || corners[2]),
|
||||
(connected[3] || placed[3] || corners[3]),
|
||||
(connected[4] || placed[4] || corners[4]),
|
||||
(connected[5] || placed[5] || corners[5])
|
||||
};
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_low_offset;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_low_height;
|
||||
|
||||
|
||||
parts[2] = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
didRender = true;
|
||||
}
|
||||
if (placed[ForgeDirection.SOUTH.ordinal()])
|
||||
{
|
||||
connected = logic.connectedSides(ForgeDirection.SOUTH);
|
||||
corners = logic.getRenderCorners(ForgeDirection.SOUTH);
|
||||
renderDir = new boolean[] {
|
||||
(connected[0] || placed[0] || corners[0]),
|
||||
(connected[1] || placed[1] || corners[1]),
|
||||
(connected[2] || placed[2] || corners[2]),
|
||||
(connected[3] || placed[3] || corners[3]),
|
||||
(connected[4] || placed[4] || corners[4]),
|
||||
(connected[5] || placed[5] || corners[5])
|
||||
};
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_high_offset;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_high_height;
|
||||
|
||||
parts[3] = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
didRender = true;
|
||||
}
|
||||
if (placed[ForgeDirection.WEST.ordinal()])
|
||||
{
|
||||
connected = logic.connectedSides(ForgeDirection.WEST);
|
||||
corners = logic.getRenderCorners(ForgeDirection.WEST);
|
||||
renderDir = new boolean[] {
|
||||
(connected[0] || placed[0] || corners[0]),
|
||||
(connected[1] || placed[1] || corners[1]),
|
||||
(connected[2] || placed[2] || corners[2]),
|
||||
(connected[3] || placed[3] || corners[3]),
|
||||
(connected[4] || placed[4] || corners[4]),
|
||||
(connected[5] || placed[5] || corners[5])
|
||||
};
|
||||
minX = Geometry.cable_low_offset;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_low_height;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
parts[4] = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
didRender = true;
|
||||
}
|
||||
if (placed[ForgeDirection.EAST.ordinal()])
|
||||
{
|
||||
connected = logic.connectedSides(ForgeDirection.EAST);
|
||||
corners = logic.getRenderCorners(ForgeDirection.EAST);
|
||||
renderDir = new boolean[] {
|
||||
(connected[0] || placed[0] || corners[0]),
|
||||
(connected[1] || placed[1] || corners[1]),
|
||||
(connected[2] || placed[2] || corners[2]),
|
||||
(connected[3] || placed[3] || corners[3]),
|
||||
(connected[4] || placed[4] || corners[4]),
|
||||
(connected[5] || placed[5] || corners[5])
|
||||
};
|
||||
minX = Geometry.cable_high_offset;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_high_height;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
parts[5] = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
didRender = true;
|
||||
}
|
||||
if (!didRender)
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = Geometry.cable_low_offset;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_low_height;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
parts[0] = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
private static int closestClicked (EntityPlayer player, double reachDistance, SignalBusLogic terminal, AxisAlignedBB[] parts)
|
||||
{
|
||||
int closest = -1;
|
||||
|
||||
Vec3 playerPosition = Vec3.createVectorHelper(player.posX - terminal.xCoord, player.posY - terminal.yCoord + player.getEyeHeight(), player.posZ - terminal.zCoord);
|
||||
Vec3 playerLook = player.getLookVec();
|
||||
|
||||
Vec3 playerViewOffset = Vec3.createVectorHelper(playerPosition.xCoord + playerLook.xCoord * reachDistance, playerPosition.yCoord + playerLook.yCoord * reachDistance, playerPosition.zCoord
|
||||
+ playerLook.zCoord * reachDistance);
|
||||
double closestCalc = Double.MAX_VALUE;
|
||||
double hitDistance = 0D;
|
||||
|
||||
for (int i = 0; i < parts.length; i++)
|
||||
{
|
||||
if (parts[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MovingObjectPosition hit = parts[i].calculateIntercept(playerPosition, playerViewOffset);
|
||||
if (hit != null)
|
||||
{
|
||||
hitDistance = playerPosition.distanceTo(hit.hitVec);
|
||||
if (hitDistance < closestCalc)
|
||||
{
|
||||
closestCalc = hitDistance;
|
||||
closest = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
@SideOnly(Side.CLIENT)
|
||||
@ForgeSubscribe
|
||||
public void onBlockHighlight (DrawBlockHighlightEvent event)
|
||||
{
|
||||
return;
|
||||
// if (event.target.typeOfHit == EnumMovingObjectType.TILE && event.player.worldObj.getBlockId(event.target.blockX, event.target.blockY, event.target.blockZ) == this.blockID)
|
||||
// {
|
||||
// TileEntity te = event.player.worldObj.getBlockTileEntity(event.target.blockX, event.target.blockY, event.target.blockZ);
|
||||
// if (!(te instanceof SignalBusLogic))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// AxisAlignedBB[] boxes = getBoxes((SignalBusLogic)te);
|
||||
// double reach = Minecraft.getMinecraft().playerController.getBlockReachDistance();
|
||||
// int hitbox = closestClicked(event.player, reach, (SignalBusLogic)te, boxes);
|
||||
//
|
||||
// if (hitbox > 0 && hitbox < HITBOXES)
|
||||
// {
|
||||
// float f1 = 0.002F;
|
||||
// double d0 = event.player.lastTickPosX + (event.player.posX - event.player.lastTickPosX) * (double)event.partialTicks;
|
||||
// double d1 = event.player.lastTickPosY + (event.player.posY - event.player.lastTickPosY) * (double)event.partialTicks;
|
||||
// double d2 = event.player.lastTickPosZ + (event.player.posZ - event.player.lastTickPosZ) * (double)event.partialTicks;
|
||||
// drawOutlinedBoundingBox(boxes[hitbox].expand((double)f1, (double)f1, (double)f1).getOffsetBoundingBox(-d0, -d1, -d2));
|
||||
//
|
||||
// }
|
||||
// event.setCanceled(true);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws lines for the edges of the bounding box.
|
||||
*/
|
||||
private static void drawOutlinedBoundingBox(AxisAlignedBB par1AxisAlignedBB)
|
||||
{
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
tessellator.startDrawing(3);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
|
||||
tessellator.draw();
|
||||
tessellator.startDrawing(3);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
|
||||
tessellator.draw();
|
||||
tessellator.startDrawing(1);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.minZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.maxX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.minY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.addVertex(par1AxisAlignedBB.minX, par1AxisAlignedBB.maxY, par1AxisAlignedBB.maxZ);
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(World world, int metadata) {
|
||||
return new SignalBusLogic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world) {
|
||||
return new SignalBusLogic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<ItemStack> getBlockDropped (World world, int x, int y, int z, int metadata, int fortune)
|
||||
{
|
||||
return new ArrayList<ItemStack>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy (World world, int x, int y, int z, EntityLivingBase entityLiving, ItemStack itemStack)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
NBTTagCompound data = itemStack.stackTagCompound;
|
||||
if (data != null && data.hasKey("connectedSide"))
|
||||
{
|
||||
((SignalBusLogic) te).addPlacedSide(data.getInteger("connectedSide"));
|
||||
itemStack.stackTagCompound = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange (World par1World, int par2, int par3, int par4, int par5)
|
||||
{
|
||||
super.onNeighborBlockChange(par1World, par2, par3, par4, par5);
|
||||
|
||||
if (par5 == this.blockID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
TileEntity te = par1World.getBlockTileEntity(par2, par3, par4);
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
((SignalBusLogic)te).forceNeighborCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock (World world, int x, int y, int z, int id, int meta)
|
||||
{
|
||||
int dropBus, dropWire = 0;
|
||||
float jumpX, jumpY, jumpZ;
|
||||
ItemStack tempStack;
|
||||
Random rand = new Random();
|
||||
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
dropBus = ((SignalBusLogic) te).getDroppedBuses();
|
||||
dropWire = ((SignalBusLogic) te).getDroppedWire();
|
||||
if (dropBus > 0)
|
||||
{
|
||||
tempStack = new ItemStack(TConstruct.instance.content.signalBus.blockID, dropBus, 0);
|
||||
jumpX = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpY = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpZ = rand.nextFloat() * 0.8F + 0.1F;
|
||||
|
||||
EntityItem entityitem = new EntityItem(world, (double) ((float) x + jumpX), (double) ((float) y + jumpY), (double) ((float) z + jumpZ), tempStack);
|
||||
|
||||
float offset = 0.05F;
|
||||
entityitem.motionX = (double) ((float) rand.nextGaussian() * offset);
|
||||
entityitem.motionY = (double) ((float) rand.nextGaussian() * offset + 0.2F);
|
||||
entityitem.motionZ = (double) ((float) rand.nextGaussian() * offset);
|
||||
world.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
if (dropWire > 0)
|
||||
{
|
||||
tempStack = new ItemStack(TConstruct.instance.content.lengthWire, dropWire);
|
||||
jumpX = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpY = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpZ = rand.nextFloat() * 0.8F + 0.1F;
|
||||
|
||||
EntityItem entityitem = new EntityItem(world, (double) ((float) x + jumpX), (double) ((float) y + jumpY), (double) ((float) z + jumpZ), tempStack);
|
||||
|
||||
float offset = 0.05F;
|
||||
entityitem.motionX = (double) ((float) rand.nextGaussian() * offset);
|
||||
entityitem.motionY = (double) ((float) rand.nextGaussian() * offset + 0.2F);
|
||||
entityitem.motionZ = (double) ((float) rand.nextGaussian() * offset);
|
||||
world.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
((SignalBusLogic) te).notifyBreak();
|
||||
}
|
||||
|
||||
super.breakBlock(world, x, y, z, id, meta);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,567 @@
|
||||
package tconstruct.blocks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import codechicken.nei.api.IHighlightHandler;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
import tconstruct.TConstruct;
|
||||
import tconstruct.blocks.logic.SignalBusLogic;
|
||||
import tconstruct.blocks.logic.SignalTerminalLogic;
|
||||
import tconstruct.client.block.SignalBusRender;
|
||||
import tconstruct.client.block.SignalTerminalRender;
|
||||
import tconstruct.library.TConstructRegistry;
|
||||
import net.minecraft.block.Block;
|
||||
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.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.EnumMovingObjectType;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
import net.minecraftforge.common.ForgeDirection.*;
|
||||
import net.minecraftforge.event.ForgeSubscribe;
|
||||
|
||||
public class SignalTerminal extends Block implements ITileEntityProvider
|
||||
{
|
||||
|
||||
public static class TerminalGeometry
|
||||
{
|
||||
public static float plate_width_min = 0.25F;
|
||||
public static float plate_width_max = 0.75F;
|
||||
public static float plate_low_max = 0.15F;
|
||||
public static float plate_high_max = 1.0F;
|
||||
public static float plate_low_min = 0.0F;
|
||||
public static float plate_high_min = 1 - plate_low_max;
|
||||
public static float center_min = 0.375F;
|
||||
public static float center_max = 0.625F;
|
||||
public static float channel_width_min = 0.375F;
|
||||
public static float channel_width_max = 0.625F;
|
||||
public static float channel_low_max = center_min;
|
||||
public static float channel_high_max = plate_high_min;
|
||||
public static float channel_low_min = plate_low_max;
|
||||
public static float channel_high_min = center_max;
|
||||
}
|
||||
|
||||
public static int HITBOXES = 13;
|
||||
public static int[] sideBoxMapping = new int[] { -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
|
||||
|
||||
public Icon[] icons;
|
||||
public Icon[] channelIcons;
|
||||
public String[] textureNames = new String[] { "signalbus" };
|
||||
public String[] channelTextureNames = new String[] { "white", "orange", "magenta", "lightblue", "yellow", "lime", "pink", "gray", "lightgray", "cyan", "purple", "blue", "brown", "green", "red",
|
||||
"black" };
|
||||
|
||||
public SignalTerminal(int par1)
|
||||
{
|
||||
super(par1, Material.circuits);
|
||||
this.setHardness(0.1F);
|
||||
this.setResistance(1);
|
||||
this.setStepSound(soundMetalFootstep);
|
||||
setCreativeTab(TConstructRegistry.blockTab);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public Icon getIcon (int side, int metadata)
|
||||
{
|
||||
return icons[0];
|
||||
}
|
||||
|
||||
public Icon getChannelIcon (int channel)
|
||||
{
|
||||
if (channel < 0 || channel >= channelIcons.length)
|
||||
{
|
||||
return channelIcons[0];
|
||||
}
|
||||
|
||||
return channelIcons[channel];
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons (IconRegister iconRegister)
|
||||
{
|
||||
this.icons = new Icon[textureNames.length];
|
||||
|
||||
for (int i = 0; i < this.icons.length; ++i)
|
||||
{
|
||||
this.icons[i] = iconRegister.registerIcon("tinker:" + textureNames[i]);
|
||||
}
|
||||
|
||||
this.channelIcons = new Icon[channelTextureNames.length];
|
||||
|
||||
for (int i = 0; i < this.channelIcons.length; ++i)
|
||||
{
|
||||
this.channelIcons[i] = iconRegister.registerIcon("tinker:glass/stainedglass_" + channelTextureNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
|
||||
* cleared to be reused)
|
||||
*/
|
||||
public AxisAlignedBB getCollisionBoundingBoxFromPool (World par1World, int par2, int par3, int par4)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
|
||||
* adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
|
||||
*/
|
||||
public boolean isOpaqueCube ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
|
||||
*/
|
||||
public boolean renderAsNormalBlock ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockSolidOnSide (World world, int x, int y, int z, ForgeDirection side)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te != null && te instanceof SignalTerminalLogic)
|
||||
{
|
||||
if (((SignalTerminalLogic) te).getConnectedSides()[side.ordinal()] != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of render function that is called for this block
|
||||
*/
|
||||
@Override
|
||||
public int getRenderType ()
|
||||
{
|
||||
return SignalTerminalRender.renderID;
|
||||
}
|
||||
|
||||
/**
|
||||
* How many world ticks before ticking
|
||||
*/
|
||||
public int tickRate (World par1World)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
|
||||
*/
|
||||
public boolean canPlaceBlockOnSide (World world, int x, int y, int z, int side)
|
||||
{
|
||||
ForgeDirection dir = ForgeDirection.getOrientation(side);
|
||||
return true || (dir == ForgeDirection.NORTH && world.isBlockSolidOnSide(x, y, z + 1, ForgeDirection.NORTH))
|
||||
|| (dir == ForgeDirection.SOUTH && world.isBlockSolidOnSide(x, y, z - 1, ForgeDirection.SOUTH))
|
||||
|| (dir == ForgeDirection.WEST && world.isBlockSolidOnSide(x + 1, y, z, ForgeDirection.WEST))
|
||||
|| (dir == ForgeDirection.EAST && world.isBlockSolidOnSide(x - 1, y, z, ForgeDirection.EAST)) || (dir == ForgeDirection.UP && world.isBlockSolidOnSide(x, y - 1, z, ForgeDirection.UP))
|
||||
|| (dir == ForgeDirection.DOWN && world.isBlockSolidOnSide(x, y + 1, z, ForgeDirection.DOWN));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
|
||||
*/
|
||||
public boolean canPlaceBlockAt (World world, int x, int y, int z)
|
||||
{
|
||||
return world.isBlockSolidOnSide(x - 1, y, z, ForgeDirection.EAST) || world.isBlockSolidOnSide(x + 1, y, z, ForgeDirection.WEST) || world.isBlockSolidOnSide(x, y, z - 1, ForgeDirection.SOUTH)
|
||||
|| world.isBlockSolidOnSide(x, y, z + 1, ForgeDirection.NORTH) || world.isBlockSolidOnSide(x, y - 1, z, ForgeDirection.UP)
|
||||
|| world.isBlockSolidOnSide(x, y + 1, z, ForgeDirection.DOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the blocks bounds based on its current state. Args: world, x, y, z
|
||||
*/
|
||||
public void setBlockBoundsBasedOnState (IBlockAccess world, int x, int y, int z)
|
||||
{
|
||||
float minX = 1;
|
||||
float minY = 1;
|
||||
float minZ = 1;
|
||||
float maxX = 0;
|
||||
float maxY = 0;
|
||||
float maxZ = 0;
|
||||
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
for (AxisAlignedBB aabb : getBoxes((SignalTerminalLogic) te))
|
||||
{
|
||||
if (aabb == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
minX = Math.min(minX, (float) aabb.minX);
|
||||
minY = Math.min(minY, (float) aabb.minY);
|
||||
minZ = Math.min(minZ, (float) aabb.minZ);
|
||||
maxX = Math.max(maxX, (float) aabb.maxX);
|
||||
maxY = Math.max(maxY, (float) aabb.maxY);
|
||||
maxZ = Math.max(maxZ, (float) aabb.maxZ);
|
||||
}
|
||||
|
||||
setBlockBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.375F, 0.375F, 0.375F, 0.625F, 0.625F, 0.625F);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public void addCollisionBoxesToList (World world, int x, int y, int z, AxisAlignedBB collisionTest, List collisionBoxList, Entity entity)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
for (AxisAlignedBB aabb : getBoxes((SignalTerminalLogic) te))
|
||||
{
|
||||
if (aabb == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aabb = AxisAlignedBB.getBoundingBox(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ);
|
||||
aabb.minX += x;
|
||||
aabb.minY += y;
|
||||
aabb.minZ += z;
|
||||
aabb.maxX += x;
|
||||
aabb.maxY += y;
|
||||
aabb.maxZ += z;
|
||||
|
||||
if (collisionTest.intersectsWith(aabb))
|
||||
{
|
||||
collisionBoxList.add(aabb);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super.addCollisionBoxesToList(world, x, y, z, collisionTest, collisionBoxList, entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the block is emitting indirect/weak redstone power on the specified side. If isBlockNormalCube
|
||||
* returns true, standard redstone propagation rules will apply instead and this will not be called. Args: World, X,
|
||||
* Y, Z, side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block.
|
||||
*/
|
||||
public int isProvidingWeakPower (IBlockAccess world, int x, int y, int z, int localSide)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
return ((SignalTerminalLogic) te).isProvidingWeakPower(localSide);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean shouldSideBeRendered (IBlockAccess par1iBlockAccess, int par2, int par3, int par4, int par5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the block is emitting direct/strong redstone power on the specified side. Args: World, X, Y, Z,
|
||||
* side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block.
|
||||
*/
|
||||
public int isProvidingStrongPower (IBlockAccess world, int x, int y, int z, int localSide)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
return ((SignalTerminalLogic) te).isProvidingStrongPower(localSide);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCheckWeakPower (World world, int x, int y, int z, int side)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this block provide power. Only wire currently seems to have this change based on its state.
|
||||
*/
|
||||
public boolean canProvidePower ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity (World world)
|
||||
{
|
||||
return new SignalTerminalLogic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborBlockChange (World world, int x, int y, int z, int neighborID)
|
||||
{
|
||||
super.onNeighborBlockChange(world, x, y, z, neighborID);
|
||||
|
||||
// if (neighborID == blockID) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
((SignalTerminalLogic) te).onNeighborBlockChange();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static AxisAlignedBB[] getBoxes (SignalTerminalLogic logic)
|
||||
{
|
||||
byte connected[] = logic.getConnectedSides();
|
||||
|
||||
AxisAlignedBB[] parts = new AxisAlignedBB[HITBOXES];
|
||||
|
||||
// Center
|
||||
parts[0] = AxisAlignedBB.getBoundingBox(TerminalGeometry.center_min, TerminalGeometry.center_min, TerminalGeometry.center_min, TerminalGeometry.center_max, TerminalGeometry.center_max,
|
||||
TerminalGeometry.center_max);
|
||||
|
||||
if (connected[ForgeDirection.DOWN.ordinal()] != -1)
|
||||
{
|
||||
parts[1] = AxisAlignedBB.getBoundingBox(TerminalGeometry.plate_width_min, TerminalGeometry.plate_low_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_width_max,
|
||||
TerminalGeometry.plate_low_max, TerminalGeometry.plate_width_max);
|
||||
parts[2] = AxisAlignedBB.getBoundingBox(TerminalGeometry.channel_width_min, TerminalGeometry.channel_low_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_width_max,
|
||||
TerminalGeometry.channel_low_max, TerminalGeometry.channel_width_max);
|
||||
}
|
||||
|
||||
if (connected[ForgeDirection.UP.ordinal()] != -1)
|
||||
{
|
||||
parts[3] = AxisAlignedBB.getBoundingBox(TerminalGeometry.plate_width_min, TerminalGeometry.plate_high_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_width_max,
|
||||
TerminalGeometry.plate_high_max, TerminalGeometry.plate_width_max);
|
||||
parts[4] = AxisAlignedBB.getBoundingBox(TerminalGeometry.channel_width_min, TerminalGeometry.channel_high_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_width_max,
|
||||
TerminalGeometry.channel_high_max, TerminalGeometry.channel_width_max);
|
||||
}
|
||||
|
||||
if (connected[ForgeDirection.NORTH.ordinal()] != -1)
|
||||
{
|
||||
parts[5] = AxisAlignedBB.getBoundingBox(TerminalGeometry.plate_width_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_high_min, TerminalGeometry.plate_width_max,
|
||||
TerminalGeometry.plate_width_max, TerminalGeometry.plate_high_max);
|
||||
parts[6] = AxisAlignedBB.getBoundingBox(TerminalGeometry.channel_width_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_high_min, TerminalGeometry.channel_width_max,
|
||||
TerminalGeometry.channel_width_max, TerminalGeometry.channel_high_max);
|
||||
}
|
||||
|
||||
if (connected[ForgeDirection.SOUTH.ordinal()] != -1)
|
||||
{
|
||||
parts[7] = AxisAlignedBB.getBoundingBox(TerminalGeometry.plate_width_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_low_min, TerminalGeometry.plate_width_max,
|
||||
TerminalGeometry.plate_width_max, TerminalGeometry.plate_low_max);
|
||||
parts[8] = AxisAlignedBB.getBoundingBox(TerminalGeometry.channel_width_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_low_min, TerminalGeometry.channel_width_max,
|
||||
TerminalGeometry.channel_width_max, TerminalGeometry.channel_low_max);
|
||||
}
|
||||
|
||||
if (connected[ForgeDirection.WEST.ordinal()] != -1)
|
||||
{
|
||||
parts[9] = AxisAlignedBB.getBoundingBox(TerminalGeometry.plate_low_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_low_max,
|
||||
TerminalGeometry.plate_width_max, TerminalGeometry.plate_width_max);
|
||||
parts[10] = AxisAlignedBB.getBoundingBox(TerminalGeometry.channel_low_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_low_max,
|
||||
TerminalGeometry.channel_width_max, TerminalGeometry.channel_width_max);
|
||||
}
|
||||
|
||||
if (connected[ForgeDirection.EAST.ordinal()] != -1)
|
||||
{
|
||||
parts[11] = AxisAlignedBB.getBoundingBox(TerminalGeometry.plate_high_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_width_min, TerminalGeometry.plate_high_max,
|
||||
TerminalGeometry.plate_width_max, TerminalGeometry.plate_width_max);
|
||||
parts[12] = AxisAlignedBB.getBoundingBox(TerminalGeometry.channel_high_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_width_min, TerminalGeometry.channel_high_max,
|
||||
TerminalGeometry.channel_width_max, TerminalGeometry.channel_width_max);
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
private static int closestClicked (EntityPlayer player, double reachDistance, SignalTerminalLogic terminal, AxisAlignedBB[] parts)
|
||||
{
|
||||
int closest = -1;
|
||||
|
||||
Vec3 playerPosition = Vec3.createVectorHelper(player.posX - terminal.xCoord, player.posY - terminal.yCoord + player.getEyeHeight(), player.posZ - terminal.zCoord);
|
||||
Vec3 playerLook = player.getLookVec();
|
||||
|
||||
Vec3 playerViewOffset = Vec3.createVectorHelper(playerPosition.xCoord + playerLook.xCoord * reachDistance, playerPosition.yCoord + playerLook.yCoord * reachDistance, playerPosition.zCoord
|
||||
+ playerLook.zCoord * reachDistance);
|
||||
double closestCalc = Double.MAX_VALUE;
|
||||
double hitDistance = 0D;
|
||||
|
||||
for (int i = 0; i < parts.length; i++)
|
||||
{
|
||||
if (parts[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MovingObjectPosition hit = parts[i].calculateIntercept(playerPosition, playerViewOffset);
|
||||
if (hit != null)
|
||||
{
|
||||
hitDistance = playerPosition.distanceTo(hit.hitVec);
|
||||
if (hitDistance < closestCalc)
|
||||
{
|
||||
closestCalc = hitDistance;
|
||||
closest = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated (World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
|
||||
{
|
||||
int meta = par1World.getBlockMetadata(par2, par3, par4);
|
||||
TileEntity te = par1World.getBlockTileEntity(par2, par3, par4);
|
||||
|
||||
if (!par1World.isRemote)
|
||||
{
|
||||
if (te != null && te instanceof SignalTerminalLogic)
|
||||
{
|
||||
// ((SignalTerminalLogic) te).nextChannel();
|
||||
if (!par1World.isRemote)
|
||||
{
|
||||
// par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, 1);
|
||||
// par1World.markBlockForRenderUpdate(par2, par3, par4);
|
||||
par1World.markBlockForUpdate(par2, par3, par4);
|
||||
}
|
||||
int boxHit = closestClicked(par5EntityPlayer, 3.0F, (SignalTerminalLogic) te, getBoxes((SignalTerminalLogic) te));
|
||||
if (boxHit < 0 || boxHit >= HITBOXES)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (boxHit == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int side = sideBoxMapping[boxHit];
|
||||
|
||||
if (side < 0 || side >= 6)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (par5EntityPlayer.isSneaking())
|
||||
{
|
||||
((SignalTerminalLogic) te).prevChannel(side);
|
||||
}
|
||||
else
|
||||
{
|
||||
((SignalTerminalLogic) te).nextChannel(side);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
TConstruct.logger.info(((SignalTerminalLogic) te).debugString());
|
||||
}
|
||||
|
||||
TConstruct.logger.info("meta: " + meta);
|
||||
|
||||
//this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy (World world, int x, int y, int z, EntityLivingBase entityLiving, ItemStack itemStack)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
NBTTagCompound data = itemStack.stackTagCompound;
|
||||
if (data != null && data.hasKey("connectedSide"))
|
||||
{
|
||||
((SignalTerminalLogic) te).addPendingSide(data.getInteger("connectedSide"));
|
||||
itemStack.stackTagCompound = null;
|
||||
}
|
||||
((SignalTerminalLogic) te).connectPending();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ArrayList<ItemStack> getBlockDropped (World world, int x, int y, int z, int metadata, int fortune)
|
||||
{
|
||||
return new ArrayList<ItemStack>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock (World world, int x, int y, int z, int id, int meta)
|
||||
{
|
||||
int dropTerm, dropWire = 0;
|
||||
float jumpX, jumpY, jumpZ;
|
||||
ItemStack tempStack;
|
||||
Random rand = new Random();
|
||||
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te instanceof SignalTerminalLogic)
|
||||
{
|
||||
dropTerm = ((SignalTerminalLogic) te).getDroppedTerminals();
|
||||
dropWire = ((SignalTerminalLogic) te).getDroppedWire();
|
||||
|
||||
if (dropTerm > 0)
|
||||
{
|
||||
tempStack = new ItemStack(TConstruct.instance.content.signalTerminal.blockID, dropTerm, 0);
|
||||
jumpX = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpY = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpZ = rand.nextFloat() * 0.8F + 0.1F;
|
||||
|
||||
EntityItem entityitem = new EntityItem(world, (double) ((float) x + jumpX), (double) ((float) y + jumpY), (double) ((float) z + jumpZ), tempStack);
|
||||
|
||||
float offset = 0.05F;
|
||||
entityitem.motionX = (double) ((float) rand.nextGaussian() * offset);
|
||||
entityitem.motionY = (double) ((float) rand.nextGaussian() * offset + 0.2F);
|
||||
entityitem.motionZ = (double) ((float) rand.nextGaussian() * offset);
|
||||
world.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
if (dropWire > 0)
|
||||
{
|
||||
tempStack = new ItemStack(TConstruct.instance.content.lengthWire, dropWire);
|
||||
jumpX = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpY = rand.nextFloat() * 0.8F + 0.1F;
|
||||
jumpZ = rand.nextFloat() * 0.8F + 0.1F;
|
||||
|
||||
EntityItem entityitem = new EntityItem(world, (double) ((float) x + jumpX), (double) ((float) y + jumpY), (double) ((float) z + jumpZ), tempStack);
|
||||
|
||||
float offset = 0.05F;
|
||||
entityitem.motionX = (double) ((float) rand.nextGaussian() * offset);
|
||||
entityitem.motionY = (double) ((float) rand.nextGaussian() * offset + 0.2F);
|
||||
entityitem.motionZ = (double) ((float) rand.nextGaussian() * offset);
|
||||
world.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
((SignalTerminalLogic) te).notifyBreak();
|
||||
}
|
||||
|
||||
super.breakBlock(world, x, y, z, id, meta);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
package tconstruct.blocks.component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import tconstruct.blocks.logic.SignalBusLogic;
|
||||
import tconstruct.library.multiblock.IMultiblockMember;
|
||||
import tconstruct.library.multiblock.MultiblockMasterBaseLogic;
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
|
||||
public class SignalBusMasterLogic extends MultiblockMasterBaseLogic
|
||||
{
|
||||
private boolean forceUpdate = false;
|
||||
private boolean signalUpdate = false;
|
||||
private byte[] masterSignals = new byte[16];
|
||||
private CoordTuple[] signalProviderCoords = new CoordTuple[16];
|
||||
|
||||
//private List<CoordTuple> tetheredBuses = new LinkedList<CoordTuple>(); // Buses that contain linked Terminals
|
||||
private Map<CoordTuple, byte[]> tetheredBuses = new HashMap<CoordTuple, byte[]>();
|
||||
|
||||
public SignalBusMasterLogic(World world)
|
||||
{
|
||||
super(world);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
masterSignals[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doUpdate ()
|
||||
{
|
||||
if (worldObj.isRemote || !forceUpdate)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
forceUpdate = false;
|
||||
|
||||
TileEntity te;
|
||||
|
||||
// Calculate new signals from last tick's information
|
||||
byte[] oldSignals = masterSignals;
|
||||
masterSignals = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
for (byte[] signals : tetheredBuses.values())
|
||||
{
|
||||
calcSignals(signals);
|
||||
}
|
||||
|
||||
if (!Arrays.equals(oldSignals, masterSignals))
|
||||
{
|
||||
// Send updates to SignalBuses
|
||||
for (CoordTuple coord : tetheredBuses.keySet())
|
||||
{
|
||||
if (worldObj.getChunkProvider().chunkExists(coord.x >> 4, coord.z >> 4))
|
||||
{
|
||||
te = worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
((SignalBusLogic) te).updateLocalSignals(masterSignals);
|
||||
((SignalBusLogic) te).multiBlockTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateBusSignals (CoordTuple bus, byte[] signals)
|
||||
{
|
||||
if (!Arrays.equals(tetheredBuses.get(bus), signals))
|
||||
{
|
||||
tetheredBuses.put(bus, signals);
|
||||
forceUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getSignals ()
|
||||
{
|
||||
return masterSignals.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBlockAdded (IMultiblockMember newMember)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBlockRemoved (IMultiblockMember oldMember)
|
||||
{
|
||||
if (tetheredBuses.containsKey(oldMember.getCoordInWorld()))
|
||||
{
|
||||
tetheredBuses.remove(oldMember.getCoordInWorld());
|
||||
forceUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDataMerge (MultiblockMasterBaseLogic newMaster)
|
||||
{
|
||||
byte[] oldSignals = ((SignalBusMasterLogic) newMaster).getSignals();
|
||||
|
||||
byte[] newMasterSignals = ((SignalBusMasterLogic) newMaster).getSignals();
|
||||
|
||||
if (tetheredBuses.size() > 0)
|
||||
{
|
||||
((SignalBusMasterLogic) newMaster).mergeTethered(tetheredBuses);
|
||||
}
|
||||
|
||||
((SignalBusMasterLogic) newMaster).calcSignals(masterSignals);
|
||||
|
||||
if (!Arrays.equals(oldSignals, ((SignalBusMasterLogic) newMaster).getSignals()))
|
||||
{
|
||||
((SignalBusMasterLogic) newMaster).forceUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void calcSignals (byte[] signals)
|
||||
{
|
||||
if (signals[0] > masterSignals[0])
|
||||
{
|
||||
masterSignals[0] = signals[0];
|
||||
}
|
||||
if (signals[1] > masterSignals[1])
|
||||
{
|
||||
masterSignals[1] = signals[1];
|
||||
}
|
||||
if (signals[2] > masterSignals[2])
|
||||
{
|
||||
masterSignals[2] = signals[2];
|
||||
}
|
||||
if (signals[3] > masterSignals[3])
|
||||
{
|
||||
masterSignals[3] = signals[3];
|
||||
}
|
||||
if (signals[4] > masterSignals[4])
|
||||
{
|
||||
masterSignals[4] = signals[4];
|
||||
}
|
||||
if (signals[5] > masterSignals[5])
|
||||
{
|
||||
masterSignals[5] = signals[5];
|
||||
}
|
||||
if (signals[6] > masterSignals[6])
|
||||
{
|
||||
masterSignals[6] = signals[6];
|
||||
}
|
||||
if (signals[7] > masterSignals[7])
|
||||
{
|
||||
masterSignals[7] = signals[7];
|
||||
}
|
||||
if (signals[8] > masterSignals[8])
|
||||
{
|
||||
masterSignals[8] = signals[8];
|
||||
}
|
||||
if (signals[9] > masterSignals[9])
|
||||
{
|
||||
masterSignals[9] = signals[9];
|
||||
}
|
||||
if (signals[10] > masterSignals[10])
|
||||
{
|
||||
masterSignals[10] = signals[10];
|
||||
}
|
||||
if (signals[11] > masterSignals[11])
|
||||
{
|
||||
masterSignals[11] = signals[11];
|
||||
}
|
||||
if (signals[12] > masterSignals[12])
|
||||
{
|
||||
masterSignals[12] = signals[12];
|
||||
}
|
||||
if (signals[13] > masterSignals[13])
|
||||
{
|
||||
masterSignals[13] = signals[13];
|
||||
}
|
||||
if (signals[14] > masterSignals[14])
|
||||
{
|
||||
masterSignals[14] = signals[14];
|
||||
}
|
||||
if (signals[15] > masterSignals[15])
|
||||
{
|
||||
masterSignals[15] = signals[15];
|
||||
}
|
||||
}
|
||||
|
||||
protected void mergeTethered (Map<CoordTuple, byte[]> oldMasterTethered)
|
||||
{
|
||||
tetheredBuses.putAll(oldMasterTethered);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT (NBTTagCompound data)
|
||||
{
|
||||
// Nothing important at the moment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT (NBTTagCompound data)
|
||||
{
|
||||
// Nothing important at the moment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void formatDescriptionPacket (NBTTagCompound data)
|
||||
{
|
||||
// Nothing important at the moment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decodeDescriptionPacket (NBTTagCompound data)
|
||||
{
|
||||
// Nothing important at the moment
|
||||
}
|
||||
|
||||
@Override
|
||||
public String debugString ()
|
||||
{
|
||||
String fromSuper = super.debugString();
|
||||
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return fromSuper;
|
||||
}
|
||||
|
||||
String tstring = "Tethered Buses: " + tetheredBuses.size() + "\n Signals: [";
|
||||
for (int n = 0; n < 16; n++)
|
||||
{
|
||||
tstring += n + ":" + masterSignals[n];
|
||||
|
||||
if (n != 15)
|
||||
tstring += ", ";
|
||||
}
|
||||
tstring += "]";
|
||||
|
||||
return fromSuper + "\n" + tstring;
|
||||
}
|
||||
|
||||
public void forceUpdate ()
|
||||
{
|
||||
forceUpdate = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,690 @@
|
||||
package tconstruct.blocks.logic;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.swing.text.MaskFormatter;
|
||||
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.Packet132TileEntityData;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidEvent;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidTankInfo;
|
||||
import net.minecraftforge.fluids.IFluidHandler;
|
||||
import net.minecraftforge.fluids.IFluidTank;
|
||||
import tconstruct.TConstruct;
|
||||
import tconstruct.blocks.component.SignalBusMasterLogic;
|
||||
import tconstruct.library.component.ISignalBusConnectable;
|
||||
import tconstruct.library.multiblock.IMultiblockMember;
|
||||
import tconstruct.library.multiblock.MultiblockBaseLogic;
|
||||
import tconstruct.library.multiblock.MultiblockMasterBaseLogic;
|
||||
import tconstruct.library.signal.ISignalTransceiver;
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
import tconstruct.library.util.IActiveLogic;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class SignalBusLogic extends MultiblockBaseLogic implements IActiveLogic, ISignalBusConnectable
|
||||
{
|
||||
private int ticks = 0;
|
||||
private Map<CoordTuple, byte[]> transceivers = new HashMap<CoordTuple, byte[]>();
|
||||
private byte[] localHighSignals = new byte[16];
|
||||
private byte[] cachedReceivedSignals = new byte[16];
|
||||
|
||||
private boolean southboundSignalsChanged = false;
|
||||
private boolean northboundSignalsChanged = false;
|
||||
private boolean forceCheck = false;
|
||||
|
||||
private boolean[] placedSides = new boolean[] { false, false, false, false, false, false };
|
||||
|
||||
public SignalBusLogic()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUpdate ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMultiblockMember[] getNeighboringMembers ()
|
||||
{
|
||||
List<IMultiblockMember> corners = new LinkedList<IMultiblockMember>();
|
||||
|
||||
int i, j;
|
||||
int tX, tY, tZ;
|
||||
TileEntity te;
|
||||
for (i = 0; i < 6; ++i)
|
||||
{
|
||||
if (!placedSides[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < 6; ++j)
|
||||
{
|
||||
if (j == i || j == ForgeDirection.OPPOSITES[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tX = ForgeDirection.VALID_DIRECTIONS[j].offsetX + xCoord;
|
||||
tY = ForgeDirection.VALID_DIRECTIONS[j].offsetY + yCoord;
|
||||
tZ = ForgeDirection.VALID_DIRECTIONS[j].offsetZ + zCoord;
|
||||
if (worldObj.isBlockOpaqueCube(tX, tY, tZ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tX += ForgeDirection.VALID_DIRECTIONS[i].offsetX;
|
||||
tY += ForgeDirection.VALID_DIRECTIONS[i].offsetY;
|
||||
tZ += ForgeDirection.VALID_DIRECTIONS[i].offsetZ;
|
||||
te = worldObj.getBlockTileEntity(tX, tY, tZ);
|
||||
if (te instanceof IMultiblockMember && ((IMultiblockMember) te).isCompatible((Object) this))
|
||||
{
|
||||
corners.add((IMultiblockMember) te);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
corners.addAll(Arrays.asList(super.getNeighboringMembers()));
|
||||
IMultiblockMember[] tmp = new IMultiblockMember[corners.size()];
|
||||
return corners.toArray(tmp);
|
||||
}
|
||||
|
||||
public void broadcastSouthboundSignals ()
|
||||
{
|
||||
if (southboundSignalsChanged)
|
||||
{
|
||||
TileEntity te = null;
|
||||
|
||||
for (CoordTuple coord : transceivers.keySet())
|
||||
{
|
||||
if (worldObj.getChunkProvider().chunkExists(coord.x >> 4, coord.z >> 4))
|
||||
{
|
||||
te = worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
if (te instanceof ISignalTransceiver)
|
||||
{
|
||||
((ISignalTransceiver) te).receiveSignalUpdate(cachedReceivedSignals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
southboundSignalsChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void multiBlockTick ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEntity ()
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isConnected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (forceCheck)
|
||||
{
|
||||
forceCheck = false;
|
||||
super.onBlockAdded(worldObj, xCoord, yCoord, zCoord);
|
||||
this.getMultiblockMaster().revisitBlocks();
|
||||
}
|
||||
|
||||
if (northboundSignalsChanged)
|
||||
{
|
||||
|
||||
TileEntity te;
|
||||
byte[] signals;
|
||||
|
||||
localHighSignals = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
for (CoordTuple coord : transceivers.keySet())
|
||||
{
|
||||
|
||||
signals = transceivers.get(coord);
|
||||
|
||||
if (signals[0] > localHighSignals[0])
|
||||
{
|
||||
localHighSignals[0] = signals[0];
|
||||
}
|
||||
if (signals[1] > localHighSignals[1])
|
||||
{
|
||||
localHighSignals[1] = signals[1];
|
||||
}
|
||||
if (signals[2] > localHighSignals[2])
|
||||
{
|
||||
localHighSignals[2] = signals[2];
|
||||
}
|
||||
if (signals[3] > localHighSignals[3])
|
||||
{
|
||||
localHighSignals[3] = signals[3];
|
||||
}
|
||||
if (signals[4] > localHighSignals[4])
|
||||
{
|
||||
localHighSignals[4] = signals[4];
|
||||
}
|
||||
if (signals[5] > localHighSignals[5])
|
||||
{
|
||||
localHighSignals[5] = signals[5];
|
||||
}
|
||||
if (signals[6] > localHighSignals[6])
|
||||
{
|
||||
localHighSignals[6] = signals[6];
|
||||
}
|
||||
if (signals[7] > localHighSignals[7])
|
||||
{
|
||||
localHighSignals[7] = signals[7];
|
||||
}
|
||||
if (signals[8] > localHighSignals[8])
|
||||
{
|
||||
localHighSignals[8] = signals[8];
|
||||
}
|
||||
if (signals[9] > localHighSignals[9])
|
||||
{
|
||||
localHighSignals[9] = signals[9];
|
||||
}
|
||||
if (signals[10] > localHighSignals[10])
|
||||
{
|
||||
localHighSignals[10] = signals[10];
|
||||
}
|
||||
if (signals[11] > localHighSignals[11])
|
||||
{
|
||||
localHighSignals[11] = signals[11];
|
||||
}
|
||||
if (signals[12] > localHighSignals[12])
|
||||
{
|
||||
localHighSignals[12] = signals[12];
|
||||
}
|
||||
if (signals[13] > localHighSignals[13])
|
||||
{
|
||||
localHighSignals[13] = signals[13];
|
||||
}
|
||||
if (signals[14] > localHighSignals[14])
|
||||
{
|
||||
localHighSignals[14] = signals[14];
|
||||
}
|
||||
if (signals[15] > localHighSignals[15])
|
||||
{
|
||||
localHighSignals[15] = signals[15];
|
||||
}
|
||||
}
|
||||
|
||||
((SignalBusMasterLogic) getMultiblockMaster()).updateBusSignals(getCoordInWorld(), localHighSignals);
|
||||
|
||||
northboundSignalsChanged = false;
|
||||
|
||||
}
|
||||
|
||||
broadcastSouthboundSignals();
|
||||
}
|
||||
|
||||
public boolean registerTerminal (World world, int x, int y, int z, boolean rehome)
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (world == worldObj && world.isRemote == worldObj.isRemote)
|
||||
{
|
||||
if (worldObj.getBlockTileEntity(x, y, z) instanceof ISignalTransceiver)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
CoordTuple coords = new CoordTuple(x, y, z);
|
||||
byte[] signals = null;
|
||||
|
||||
if (transceivers.containsKey(coords))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int dropWire = ((ISignalTransceiver) te).doUnregister(rehome);
|
||||
if (dropWire > 0)
|
||||
{
|
||||
Random rand = new Random();
|
||||
ItemStack tempStack = new ItemStack(TConstruct.instance.content.lengthWire, dropWire);
|
||||
float jumpX = rand.nextFloat() * 0.8F + 0.1F;
|
||||
float jumpY = rand.nextFloat() * 0.8F + 0.1F;
|
||||
float jumpZ = rand.nextFloat() * 0.8F + 0.1F;
|
||||
|
||||
EntityItem entityitem = new EntityItem(world, (double) ((float) xCoord + jumpX), (double) ((float) yCoord + jumpY), (double) ((float) zCoord + jumpZ), tempStack);
|
||||
|
||||
float offset = 0.05F;
|
||||
entityitem.motionX = (double) ((float) rand.nextGaussian() * offset);
|
||||
entityitem.motionY = (double) ((float) rand.nextGaussian() * offset + 0.2F);
|
||||
entityitem.motionZ = (double) ((float) rand.nextGaussian() * offset);
|
||||
world.spawnEntityInWorld(entityitem);
|
||||
}
|
||||
((ISignalTransceiver) te).setBusCoords(world, xCoord, yCoord, zCoord);
|
||||
|
||||
signals = ((ISignalTransceiver) te).getReceivedSignals();
|
||||
|
||||
transceivers.put(coords, signals);
|
||||
northboundSignalsChanged = true;
|
||||
|
||||
updateLocalSignals(((SignalBusMasterLogic)getMultiblockMaster()).getSignals());
|
||||
((ISignalTransceiver) te).receiveSignalUpdate(cachedReceivedSignals);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetached (MultiblockMasterBaseLogic oldMaster)
|
||||
{
|
||||
|
||||
super.onDetached(oldMaster);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttached (MultiblockMasterBaseLogic newMaster)
|
||||
{
|
||||
super.onAttached(newMaster);
|
||||
|
||||
if (transceivers != null || !transceivers.isEmpty())
|
||||
{
|
||||
northboundSignalsChanged = true;
|
||||
|
||||
updateLocalSignals(((SignalBusMasterLogic)getMultiblockMaster()).getSignals());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRegisteredTerminal (World world, int x, int y, int z)
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return transceivers.containsKey(new CoordTuple(x, y, z));
|
||||
}
|
||||
|
||||
public boolean unregisterTerminal (World world, int x, int y, int z)
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (transceivers.remove(new CoordTuple(x, y, z)) != null)
|
||||
{
|
||||
northboundSignalsChanged = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasTerminals ()
|
||||
{
|
||||
return (transceivers.size() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatible (Object other)
|
||||
{
|
||||
return (other.getClass() == this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT (NBTTagCompound tags)
|
||||
{
|
||||
super.readFromNBT(tags);
|
||||
readCustomNBT(tags);
|
||||
}
|
||||
|
||||
public void readCustomNBT (NBTTagCompound tags)
|
||||
{
|
||||
int temp = tags.getInteger("placedSides");
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
placedSides[i] = (temp >> i & 1) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT (NBTTagCompound tags)
|
||||
{
|
||||
super.writeToNBT(tags);
|
||||
writeCustomNBT(tags);
|
||||
}
|
||||
|
||||
public void writeCustomNBT (NBTTagCompound tags)
|
||||
{
|
||||
int temp = 0;
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (placedSides[i])
|
||||
{
|
||||
temp |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
tags.setInteger("placedSides", temp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet getDescriptionPacket ()
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
writeCustomNBT(tag);
|
||||
return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket (INetworkManager net, Packet132TileEntityData packet)
|
||||
{
|
||||
readCustomNBT(packet.data);
|
||||
this.worldObj.markBlockForRenderUpdate(this.xCoord, this.yCoord, this.zCoord);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getActive ()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActive (boolean flag)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public boolean[] placedSides ()
|
||||
{
|
||||
return placedSides.clone();
|
||||
}
|
||||
|
||||
public boolean[] connectedSides (ForgeDirection fromFace)
|
||||
{
|
||||
boolean[] connected = new boolean[6];
|
||||
|
||||
TileEntity te;
|
||||
ForgeDirection dir;
|
||||
int neighborX;
|
||||
int neighborY;
|
||||
int neighborZ;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (i == fromFace.ordinal() || i == fromFace.getOpposite().ordinal())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dir = ForgeDirection.getOrientation(i);
|
||||
neighborX = xCoord + dir.offsetX;
|
||||
neighborY = yCoord + dir.offsetY;
|
||||
neighborZ = zCoord + dir.offsetZ;
|
||||
|
||||
te = worldObj.getBlockTileEntity(neighborX, neighborY, neighborZ);
|
||||
connected[i] = (te instanceof ISignalBusConnectable && ((ISignalBusConnectable) te).connectableOnFace(fromFace));
|
||||
}
|
||||
|
||||
return connected;
|
||||
}
|
||||
|
||||
// Face is the face in the block; e.g. DOWN = on top of the block below.
|
||||
public boolean connectableOnFace (ForgeDirection side)
|
||||
{
|
||||
return placedSides[side.ordinal()];
|
||||
}
|
||||
|
||||
public boolean isConnected (ForgeDirection side, ForgeDirection dir)
|
||||
{
|
||||
TileEntity te;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case DOWN:
|
||||
return (this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord - 1, this.zCoord) instanceof SignalBusLogic);
|
||||
case NORTH:
|
||||
return (this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord - 1) instanceof SignalBusLogic);
|
||||
case SOUTH:
|
||||
return (this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord + 1) instanceof SignalBusLogic);
|
||||
case WEST:
|
||||
return (this.worldObj.getBlockTileEntity(this.xCoord - 1, this.yCoord, this.zCoord) instanceof SignalBusLogic);
|
||||
case EAST:
|
||||
return (this.worldObj.getBlockTileEntity(this.xCoord + 1, this.yCoord, this.zCoord) instanceof SignalBusLogic);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiblockMasterBaseLogic getNewMultiblockMasterObject ()
|
||||
{
|
||||
return new SignalBusMasterLogic(this.worldObj);
|
||||
}
|
||||
|
||||
public String debugString ()
|
||||
{
|
||||
return "Connected: " + transceivers.size();
|
||||
}
|
||||
|
||||
public byte[] getLocalSignals ()
|
||||
{
|
||||
return localHighSignals;
|
||||
}
|
||||
|
||||
public void updateTransceiverSignals (CoordTuple coords, byte[] signals)
|
||||
{
|
||||
if (!Arrays.equals(signals, transceivers.get(coords)))
|
||||
{
|
||||
transceivers.put(coords, signals);
|
||||
northboundSignalsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Southbound signals update from master
|
||||
public void updateLocalSignals (byte[] signals)
|
||||
{
|
||||
if (!Arrays.equals(signals, cachedReceivedSignals))
|
||||
{
|
||||
cachedReceivedSignals = signals.clone();
|
||||
southboundSignalsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlacedSide (int side)
|
||||
{
|
||||
placedSides[side] = true;
|
||||
forceCheck = true;
|
||||
}
|
||||
|
||||
public boolean[] getRenderCorners (ForgeDirection fromFace)
|
||||
{
|
||||
boolean[] corners = new boolean[6];
|
||||
|
||||
TileEntity te;
|
||||
ForgeDirection dir;
|
||||
int neighborX;
|
||||
int neighborY;
|
||||
int neighborZ;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (i == fromFace.ordinal() || i == fromFace.getOpposite().ordinal())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dir = ForgeDirection.getOrientation(i);
|
||||
neighborX = xCoord + dir.offsetX;
|
||||
neighborY = yCoord + dir.offsetY;
|
||||
neighborZ = zCoord + dir.offsetZ;
|
||||
if (worldObj.isBlockOpaqueCube(neighborX, neighborY, neighborZ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
neighborX += fromFace.offsetX;
|
||||
neighborY += fromFace.offsetY;
|
||||
neighborZ += fromFace.offsetZ;
|
||||
|
||||
te = worldObj.getBlockTileEntity(neighborX, neighborY, neighborZ);
|
||||
corners[i] = (te instanceof ISignalBusConnectable && ((ISignalBusConnectable) te).connectableOnCorner(fromFace.getOpposite(), dir.getOpposite()));
|
||||
}
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connectableOnCorner (ForgeDirection side, ForgeDirection turn)
|
||||
{
|
||||
if (!placedSides[side.ordinal()] && placedSides[turn.ordinal()])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willConnect (CoordTuple coord)
|
||||
{
|
||||
int i, j;
|
||||
ForgeDirection iDir, jDir;
|
||||
TileEntity te;
|
||||
|
||||
for (i = 0; i < 6; ++i)
|
||||
{
|
||||
iDir = ForgeDirection.VALID_DIRECTIONS[i];
|
||||
if (!placedSides[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < 6; ++j)
|
||||
{
|
||||
if (placedSides[j] || j == i || j == i || j == iDir.getOpposite().ordinal())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
jDir = ForgeDirection.VALID_DIRECTIONS[j];
|
||||
if (xCoord + jDir.offsetX == coord.x && yCoord + jDir.offsetY == coord.y && zCoord + jDir.offsetZ == coord.z)
|
||||
{
|
||||
te = worldObj.getBlockTileEntity(xCoord + jDir.offsetX, yCoord + jDir.offsetY, zCoord + jDir.offsetZ);
|
||||
if (te instanceof ISignalBusConnectable && ((ISignalBusConnectable)te).connectableOnFace(iDir))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (worldObj.isBlockOpaqueCube(xCoord + jDir.offsetX, yCoord + jDir.offsetY, zCoord + jDir.offsetZ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (xCoord + iDir.offsetX + jDir.offsetX == coord.x && yCoord + iDir.offsetY + jDir.offsetY == coord.y && xCoord + iDir.offsetZ + jDir.offsetZ == coord.z)
|
||||
{
|
||||
te = worldObj.getBlockTileEntity(xCoord + iDir.offsetX + jDir.offsetX, yCoord + iDir.offsetY + jDir.offsetY, zCoord + iDir.offsetZ + jDir.offsetZ);
|
||||
if (te instanceof ISignalBusConnectable && ((ISignalBusConnectable)te).connectableOnCorner(iDir.getOpposite(), jDir.getOpposite()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CoordTuple[] getNeighborCoords ()
|
||||
{
|
||||
List<CoordTuple> cornerCoords = new LinkedList<CoordTuple>();
|
||||
|
||||
int i, j;
|
||||
ForgeDirection iDir, jDir;
|
||||
CoordTuple coord;
|
||||
|
||||
for (i = 0; i < 6; ++i)
|
||||
{
|
||||
if (!placedSides[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
iDir = ForgeDirection.VALID_DIRECTIONS[i];
|
||||
for (j = 0; j < 6; ++j)
|
||||
{
|
||||
if (placedSides[j] || j == i || j == iDir.getOpposite().ordinal())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
jDir = ForgeDirection.VALID_DIRECTIONS[j];
|
||||
if (worldObj.isBlockOpaqueCube(xCoord + jDir.offsetX, yCoord + jDir.offsetY, zCoord + jDir.offsetZ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
coord = new CoordTuple(xCoord + iDir.offsetX + jDir.offsetX, yCoord + iDir.offsetY + jDir.offsetY, zCoord + iDir.offsetZ + jDir.offsetZ);
|
||||
}
|
||||
}
|
||||
|
||||
cornerCoords.addAll(Arrays.asList(super.getNeighborCoords()));
|
||||
CoordTuple[] tmp = new CoordTuple[cornerCoords.size()];
|
||||
return cornerCoords.toArray(tmp);
|
||||
}
|
||||
|
||||
public void forceNeighborCheck ()
|
||||
{
|
||||
forceCheck = true;
|
||||
}
|
||||
|
||||
public int getDroppedBuses ()
|
||||
{
|
||||
int calc = 0;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (placedSides[i])
|
||||
{
|
||||
++calc;
|
||||
}
|
||||
}
|
||||
|
||||
return calc;
|
||||
}
|
||||
|
||||
public int getDroppedWire ()
|
||||
{
|
||||
int calc = 0;
|
||||
TileEntity te;
|
||||
for (CoordTuple coord : transceivers.keySet())
|
||||
{
|
||||
te = worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
if (te instanceof ISignalTransceiver)
|
||||
{
|
||||
calc += ((ISignalTransceiver) te).getDroppedWire();
|
||||
}
|
||||
}
|
||||
|
||||
return calc;
|
||||
}
|
||||
|
||||
public void notifyBreak ()
|
||||
{
|
||||
TileEntity te;
|
||||
for (CoordTuple coord : transceivers.keySet())
|
||||
{
|
||||
te = worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
if (te instanceof ISignalTransceiver)
|
||||
{
|
||||
((ISignalTransceiver) te).doUnregister(true);
|
||||
}
|
||||
}
|
||||
this.detachSelf(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,700 @@
|
||||
package tconstruct.blocks.logic;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import tconstruct.TConstruct;
|
||||
import tconstruct.blocks.SignalTerminal;
|
||||
import tconstruct.blocks.TConstructBlock;
|
||||
import tconstruct.common.TContent;
|
||||
import tconstruct.library.signal.ISignalTransceiver;
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.Packet132TileEntityData;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Facing;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
|
||||
public class SignalTerminalLogic extends TileEntity implements ISignalTransceiver
|
||||
{
|
||||
private byte[] connectedSides = new byte[6];
|
||||
private byte[] receivingSides = new byte[6];
|
||||
private byte[] sideChannel = new byte[6];
|
||||
|
||||
private boolean forceUpdateSide;
|
||||
private boolean neighborChanged;
|
||||
|
||||
private byte[] cachedSouthboundSignals;
|
||||
|
||||
private int pendingSide = -1;
|
||||
private CoordTuple signalBus = null;
|
||||
private boolean doUpdate = false;
|
||||
private boolean isRegistered = false;
|
||||
|
||||
public SignalTerminalLogic()
|
||||
{
|
||||
super();
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
connectedSides[i] = -1;
|
||||
receivingSides[i] = -1;
|
||||
sideChannel[i] = 0;
|
||||
forceUpdateSide = false;
|
||||
}
|
||||
|
||||
neighborChanged = false;
|
||||
|
||||
}
|
||||
|
||||
private void tryRegister ()
|
||||
{
|
||||
boolean wasRegistered = isRegistered;
|
||||
if (!(worldObj instanceof World))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(signalBus instanceof CoordTuple))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntity te = worldObj.getBlockTileEntity(signalBus.x, signalBus.y, signalBus.z);
|
||||
if (!(te instanceof SignalBusLogic))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
isRegistered = ((SignalBusLogic) te).registerTerminal(worldObj, xCoord, yCoord, zCoord, false);
|
||||
|
||||
if (isRegistered != wasRegistered)
|
||||
{
|
||||
if (isRegistered)
|
||||
{
|
||||
doUpdate = true;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
signalBus = null;
|
||||
doUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT (NBTTagCompound data)
|
||||
{
|
||||
super.readFromNBT(data);
|
||||
|
||||
sideChannel = data.getByteArray("sideChannel");
|
||||
receivingSides = data.getByteArray("receivingSides");
|
||||
connectedSides = data.getByteArray("connectedSides");
|
||||
|
||||
if (sideChannel.length != 6)
|
||||
{
|
||||
sideChannel = new byte[] { 0, 0, 0, 0, 0, 0 };
|
||||
}
|
||||
if (receivingSides.length != 6)
|
||||
{
|
||||
receivingSides = new byte[] { -1, -1, -1, -1, -1, -1 };
|
||||
}
|
||||
if (connectedSides.length != 6)
|
||||
{
|
||||
connectedSides = new byte[] { -1, -1, -1, -1, -1, -1 };
|
||||
}
|
||||
|
||||
int tX = data.getInteger("BusX");
|
||||
int tY = data.getInteger("BusY");
|
||||
int tZ = data.getInteger("BusZ");
|
||||
|
||||
if (tX == xCoord && tY == yCoord && tZ == zCoord)
|
||||
{
|
||||
signalBus = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
signalBus = new CoordTuple(tX, tY, tZ);
|
||||
}
|
||||
|
||||
if (!isRegistered)
|
||||
{
|
||||
tryRegister();
|
||||
}
|
||||
|
||||
doUpdate = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT (NBTTagCompound data)
|
||||
{
|
||||
super.writeToNBT(data);
|
||||
|
||||
data.setByteArray("sideChannel", sideChannel);
|
||||
data.setByteArray("receivingSides", receivingSides);
|
||||
data.setByteArray("connectedSides", connectedSides);
|
||||
|
||||
if (signalBus != null)
|
||||
{
|
||||
data.setInteger("BusX", signalBus.x);
|
||||
data.setInteger("BusY", signalBus.y);
|
||||
data.setInteger("BusZ", signalBus.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.setInteger("BusX", xCoord);
|
||||
data.setInteger("BusY", yCoord);
|
||||
data.setInteger("BusZ", zCoord);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEntity ()
|
||||
{
|
||||
if (pendingSide >= 0 && pendingSide < 6 && connectedSides[pendingSide] == -1)
|
||||
{
|
||||
connectedSides[pendingSide] = 0;
|
||||
pendingSide = -1;
|
||||
forceUpdateSide = true;
|
||||
}
|
||||
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (forceUpdateSide || neighborChanged)
|
||||
{
|
||||
checkNeighbors();
|
||||
neighborChanged = false;
|
||||
forceUpdateSide = false;
|
||||
}
|
||||
|
||||
if (!doUpdate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isRegistered)
|
||||
{
|
||||
tryRegister();
|
||||
}
|
||||
|
||||
if (cachedSouthboundSignals != null)
|
||||
{
|
||||
processSignalUpdate(cachedSouthboundSignals);
|
||||
}
|
||||
|
||||
doUpdate = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Receive Southbound Signal Updates
|
||||
public void receiveSignalUpdate (byte[] signals)
|
||||
{
|
||||
if (!Arrays.equals(cachedSouthboundSignals, signals))
|
||||
{
|
||||
cachedSouthboundSignals = signals.clone();
|
||||
doUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void processSignalUpdate (byte[] signals)
|
||||
{
|
||||
int oldValue;
|
||||
int targetX = 0;
|
||||
int targetY = 0;
|
||||
int targetZ = 0;
|
||||
int oSide;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (connectedSides[i] != -1)
|
||||
{
|
||||
oldValue = connectedSides[i];
|
||||
connectedSides[i] = signals[sideChannel[i]];
|
||||
|
||||
if (oldValue != connectedSides[i])
|
||||
{
|
||||
targetX = xCoord;
|
||||
targetY = yCoord;
|
||||
targetZ = zCoord;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
targetY += -1;
|
||||
oSide = 1;
|
||||
break;
|
||||
case 1:
|
||||
targetY += 1;
|
||||
oSide = 0;
|
||||
break;
|
||||
case 2:
|
||||
targetZ += 1;
|
||||
oSide = 2;
|
||||
break;
|
||||
case 3:
|
||||
targetZ += -1;
|
||||
oSide = 3;
|
||||
break;
|
||||
case 4:
|
||||
targetX += -1;
|
||||
oSide = 5;
|
||||
break;
|
||||
case 5:
|
||||
targetX += 1;
|
||||
oSide = 4;
|
||||
break;
|
||||
default:
|
||||
oSide = 0;
|
||||
}
|
||||
|
||||
worldObj.notifyBlockOfNeighborChange(targetX, targetY, targetZ, TConstruct.instance.content.signalTerminal.blockID);
|
||||
worldObj.notifyBlocksOfNeighborChange(targetX, targetY, targetZ, TConstruct.instance.content.signalTerminal.blockID, oSide);
|
||||
//worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, TConstruct.instance.content.signalTerminal.blockID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Callback from Un/Registration
|
||||
public void setBusCoords (World world, int x, int y, int z)
|
||||
{
|
||||
if (world.provider.dimensionId == worldObj.provider.dimensionId && !world.isRemote && !worldObj.isRemote)
|
||||
{
|
||||
signalBus = new CoordTuple(x, y, z);
|
||||
world.markBlockForUpdate(xCoord, yCoord, zCoord);
|
||||
}
|
||||
doUpdate = true;
|
||||
}
|
||||
|
||||
public int isProvidingWeakPower (int side)
|
||||
{
|
||||
return isProvidingStrongPower(side);
|
||||
}
|
||||
|
||||
public int isProvidingStrongPower (int side)
|
||||
{
|
||||
int tside = side;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0:
|
||||
tside = 1;
|
||||
break;
|
||||
case 1:
|
||||
tside = 0;
|
||||
break;
|
||||
case 2:
|
||||
tside = 2;
|
||||
break;
|
||||
case 3:
|
||||
tside = 3;
|
||||
break;
|
||||
case 4:
|
||||
tside = 5;
|
||||
break;
|
||||
case 5:
|
||||
tside = 4;
|
||||
break;
|
||||
default:
|
||||
tside = side;
|
||||
}
|
||||
|
||||
if (tside >= 0 && tside < 6 && connectedSides[tside] > 0)
|
||||
{
|
||||
return connectedSides[tside] - 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void addPendingSide (int side)
|
||||
{
|
||||
pendingSide = side;
|
||||
}
|
||||
|
||||
public void connectPending ()
|
||||
{
|
||||
if (pendingSide >= 0 && pendingSide < 6 && connectedSides[pendingSide] == -1)
|
||||
{
|
||||
connectedSides[pendingSide] = 0;
|
||||
}
|
||||
pendingSide = -1;
|
||||
doUpdate = true;
|
||||
}
|
||||
|
||||
public byte[] getConnectedSides ()
|
||||
{
|
||||
return connectedSides.clone();
|
||||
}
|
||||
|
||||
public String debugString ()
|
||||
{
|
||||
String tstr = "";
|
||||
|
||||
if (!worldObj.isRemote)
|
||||
{
|
||||
byte tbyte = (byte) 0;
|
||||
for (int n = 0; n < 6; n++)
|
||||
{
|
||||
if (connectedSides[n] != -1)
|
||||
{
|
||||
tbyte &= (1 << n);
|
||||
}
|
||||
}
|
||||
tstr += "Sides: " + tbyte + "\n";
|
||||
}
|
||||
|
||||
return tstr;
|
||||
}
|
||||
|
||||
/* Packets */
|
||||
@Override
|
||||
public Packet getDescriptionPacket ()
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
writeToNBT(tag);
|
||||
return new Packet132TileEntityData(xCoord, yCoord, zCoord, 1, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket (INetworkManager net, Packet132TileEntityData packet)
|
||||
{
|
||||
readFromNBT(packet.data);
|
||||
onInventoryChanged();
|
||||
worldObj.markBlockForRenderUpdate(xCoord, yCoord, zCoord);
|
||||
this.doUpdate = true;
|
||||
}
|
||||
|
||||
public static Icon getChannelIcon (IBlockAccess world, int x, int y, int z, int side)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (te != null && te instanceof SignalTerminalLogic)
|
||||
{
|
||||
int channel = ((SignalTerminalLogic) te).sideChannel[side];
|
||||
|
||||
return ((SignalTerminal) TConstruct.instance.content.signalTerminal).getChannelIcon(channel);
|
||||
}
|
||||
|
||||
return ((SignalTerminal) TConstruct.instance.content.signalTerminal).getChannelIcon(0);
|
||||
}
|
||||
|
||||
public static Icon[] getChannelIcons ()
|
||||
{
|
||||
return ((SignalTerminal) TConstruct.instance.content.signalTerminal).channelIcons;
|
||||
}
|
||||
|
||||
public static Icon getChannelIcon (int channel)
|
||||
{
|
||||
return getChannelIcons()[channel];
|
||||
}
|
||||
|
||||
public Icon getChannelIconFromLogic (int side)
|
||||
{
|
||||
return getChannelIcons()[sideChannel[side]];
|
||||
}
|
||||
|
||||
public void nextChannel (int side)
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sideChannel[side]++;
|
||||
|
||||
if (sideChannel[side] >= 16)
|
||||
{
|
||||
sideChannel[side] = 0;
|
||||
}
|
||||
|
||||
doUpdate = true;
|
||||
}
|
||||
|
||||
public void prevChannel (int side)
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sideChannel[side]--;
|
||||
|
||||
if (sideChannel[side] < 0)
|
||||
{
|
||||
sideChannel[side] = 15;
|
||||
}
|
||||
|
||||
doUpdate = true;
|
||||
}
|
||||
|
||||
public void notifyBreak ()
|
||||
{
|
||||
if (!(worldObj instanceof World) || worldObj.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(signalBus instanceof CoordTuple))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntity te = worldObj.getBlockTileEntity(signalBus.x, signalBus.y, signalBus.z);
|
||||
if (te == null || !(te instanceof SignalBusLogic))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
((SignalBusLogic) te).unregisterTerminal(worldObj, xCoord, yCoord, zCoord);
|
||||
}
|
||||
|
||||
public void onNeighborBlockChange ()
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
neighborChanged = true;
|
||||
}
|
||||
|
||||
public void checkNeighbors ()
|
||||
{
|
||||
if (signalBus != null && signalBus instanceof CoordTuple)
|
||||
{
|
||||
TileEntity te = worldObj.getBlockTileEntity(signalBus.x, signalBus.y, signalBus.z);
|
||||
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
((SignalBusLogic) te).updateTransceiverSignals(new CoordTuple(xCoord, yCoord, zCoord), getReceivedSignals());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We can redistribute signals locally at least
|
||||
receiveSignalUpdate(getReceivedSignals());
|
||||
}
|
||||
}
|
||||
|
||||
public Icon[] getSideIcons ()
|
||||
{
|
||||
Icon[] icons = getChannelIcons();
|
||||
Icon[] sideIcons = new Icon[6];
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (sideChannel[i] > 0)
|
||||
{
|
||||
sideIcons[i] = icons[sideChannel[i]];
|
||||
}
|
||||
else
|
||||
{
|
||||
sideIcons[i] = icons[0];
|
||||
}
|
||||
}
|
||||
|
||||
return sideIcons;
|
||||
}
|
||||
|
||||
// Provide Northbound Signals
|
||||
public byte[] getReceivedSignals (boolean vanillaRedstoneKludge)
|
||||
{
|
||||
byte[] highChannel = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
int[] offset = new int[] { 0, 0, 0 };
|
||||
int oSide;
|
||||
int tempStrength;
|
||||
byte temporarySide;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (connectedSides[i] != -1)
|
||||
{
|
||||
offset[0] = 0;
|
||||
offset[1] = 0;
|
||||
offset[2] = 0;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
offset[1] += -1;
|
||||
oSide = 1;
|
||||
break;
|
||||
case 1:
|
||||
offset[1] += 1;
|
||||
oSide = 0;
|
||||
break;
|
||||
case 2:
|
||||
offset[2] += 1;
|
||||
oSide = 3;
|
||||
break;
|
||||
case 3:
|
||||
offset[2] += -1;
|
||||
oSide = 2;
|
||||
break;
|
||||
case 4:
|
||||
offset[0] += -1;
|
||||
oSide = 5;
|
||||
break;
|
||||
case 5:
|
||||
offset[0] += 1;
|
||||
oSide = 4;
|
||||
break;
|
||||
default:
|
||||
oSide = i;
|
||||
}
|
||||
|
||||
tempStrength = 0;
|
||||
if (connectedSides[i] > 0)
|
||||
{
|
||||
// We are currently powering this side, we need to identify if we are the only source or not
|
||||
temporarySide = connectedSides[i];
|
||||
connectedSides[i] = -1;
|
||||
tempStrength = worldObj.getIndirectPowerLevelTo(xCoord + offset[0], yCoord + offset[1], zCoord + offset[2], oSide);
|
||||
//tempStrength = worldObj.getStrongestIndirectPower(xCoord + offset[0], yCoord + offset[1], zCoord + offset[2]);
|
||||
if (tempStrength > 0 && tempStrength == (temporarySide - 1))
|
||||
{
|
||||
// Let's make sure we're not dealing with vanilla redstone
|
||||
|
||||
int bid = 0;
|
||||
int power = 0;
|
||||
int temp = 0;
|
||||
|
||||
for (int j = 0; j < 6; ++j)
|
||||
{
|
||||
if (offset[0] + Facing.offsetsXForSide[j] == 0 && offset[1] + Facing.offsetsYForSide[j] == 0 && offset[2] + Facing.offsetsZForSide[j] == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
temp = worldObj.getIndirectPowerLevelTo(xCoord + offset[0] + Facing.offsetsXForSide[j], yCoord + offset[1] + Facing.offsetsYForSide[j], zCoord + offset[2] + Facing.offsetsZForSide[j], j);
|
||||
|
||||
if (temp > power)
|
||||
{
|
||||
|
||||
bid = worldObj.getBlockId(xCoord + offset[0] + Facing.offsetsXForSide[j], yCoord + offset[1] + Facing.offsetsYForSide[j], zCoord + offset[2]
|
||||
+ Facing.offsetsZForSide[j]);
|
||||
if (bid != Block.redstoneWire.blockID)
|
||||
{
|
||||
power = temp;
|
||||
}
|
||||
}
|
||||
|
||||
if (power == tempStrength)
|
||||
{
|
||||
// We've found our highest source that's not RS, let's save some cycles
|
||||
break;
|
||||
}
|
||||
}
|
||||
tempStrength = power;
|
||||
|
||||
}
|
||||
connectedSides[i] = temporarySide;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempStrength = worldObj.getIndirectPowerLevelTo(xCoord + offset[0], yCoord + offset[1], zCoord + offset[2], oSide);
|
||||
// tempStrength = worldObj.getStrongestIndirectPower(xCoord + offset[0], yCoord + offset[1], zCoord + offset[2]);
|
||||
}
|
||||
|
||||
// if (tempStrength > 0 && tempStrength < receivingSides[i]){
|
||||
// receivingSides[i] = 0;
|
||||
// connectedSides[i] = 0;
|
||||
// }
|
||||
// else {
|
||||
// receivingSides[i] = (byte)Math.max((byte)tempStrength, 0);
|
||||
// }
|
||||
if (tempStrength > 0)
|
||||
{
|
||||
receivingSides[i] = (byte) (tempStrength - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
receivingSides[i] = 0;
|
||||
}
|
||||
|
||||
// if ((receivingSides[i] - 1) > connectedSides[i]) {
|
||||
// connectedSides[i] = (byte)(receivingSides[i] - 1);
|
||||
// }
|
||||
|
||||
if (receivingSides[i] > highChannel[sideChannel[i]])
|
||||
{
|
||||
highChannel[sideChannel[i]] = (byte) receivingSides[i];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return highChannel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int doUnregister (boolean reHoming)
|
||||
{
|
||||
int dropWire = 0;
|
||||
|
||||
if (signalBus != null)
|
||||
{
|
||||
TileEntity te = worldObj.getBlockTileEntity(signalBus.x, signalBus.y, signalBus.z);
|
||||
dropWire = Math.abs(xCoord - signalBus.x) + Math.abs(yCoord - signalBus.y) + Math.abs(zCoord - signalBus.z);
|
||||
if (te instanceof SignalBusLogic)
|
||||
{
|
||||
((SignalBusLogic)te).unregisterTerminal(worldObj, xCoord, yCoord, zCoord);
|
||||
}
|
||||
}
|
||||
// Remove signalBus coords
|
||||
signalBus = null;
|
||||
|
||||
|
||||
// Calculate new local received signals and provide them to local connections
|
||||
receiveSignalUpdate(getReceivedSignals());
|
||||
|
||||
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
|
||||
return (reHoming) ? dropWire : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getReceivedSignals ()
|
||||
{
|
||||
return getReceivedSignals(false);
|
||||
}
|
||||
|
||||
public int getDroppedTerminals ()
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (connectedSides[i] != -1)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getDroppedWire ()
|
||||
{
|
||||
int calcWire = 0;
|
||||
if (signalBus instanceof CoordTuple)
|
||||
{
|
||||
calcWire += Math.abs(signalBus.x - xCoord);
|
||||
calcWire += Math.abs(signalBus.y - yCoord);
|
||||
calcWire += Math.abs(signalBus.z - zCoord);
|
||||
|
||||
return calcWire;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoordTuple getBusCoords ()
|
||||
{
|
||||
return signalBus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package tconstruct.client;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.math.MathHelper;
|
||||
|
||||
import tconstruct.TConstruct;
|
||||
import tconstruct.library.signal.ISignalTransceiver;
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
import tconstruct.library.util.CoordTuplePair;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import net.minecraftforge.event.ForgeSubscribe;
|
||||
|
||||
public class SignalTetherWorldOverlayRenderer
|
||||
{
|
||||
|
||||
@ForgeSubscribe
|
||||
public void onWorldRenderLast (RenderWorldLastEvent event)
|
||||
{
|
||||
if (event.context.mc.thePlayer == null || event.context.mc.thePlayer.getHeldItem() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (event.context.mc.thePlayer.getHeldItem().itemID == TConstruct.instance.content.spoolWire.itemID)
|
||||
{
|
||||
GL11.glPushMatrix();
|
||||
Entity entity = event.context.mc.renderViewEntity;
|
||||
|
||||
double posX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * event.partialTicks;
|
||||
double posY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * event.partialTicks;
|
||||
double posZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * event.partialTicks;
|
||||
|
||||
GL11.glTranslated(-posX, -posY, -posZ);
|
||||
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glLineWidth(2.5F);
|
||||
GL11.glBegin(GL11.GL_LINES);
|
||||
|
||||
GL11.glColor4f(1, 0, 0, 1);
|
||||
|
||||
World world = entity.worldObj;
|
||||
int x1 = (int) entity.posX;
|
||||
int z1 = (int) entity.posZ;
|
||||
int y1 = (int) ((entity.posY > world.getHeight()-16) ? world.getHeight()-16 : ((entity.posY < 16) ? 16 : entity.posY));
|
||||
AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
|
||||
|
||||
GL11.glColor4f(1, 0, 0, 1);
|
||||
|
||||
Chunk chunks[] = new Chunk[9];
|
||||
|
||||
chunks[4] = world.getChunkFromBlockCoords(x1, z1);
|
||||
int cX = chunks[4].xPosition;
|
||||
int cZ = chunks[4].zPosition;
|
||||
|
||||
chunks[0] = world.getChunkFromChunkCoords(cX - 1, cZ - 1);
|
||||
chunks[1] = world.getChunkFromChunkCoords(cX , cZ - 1);
|
||||
chunks[2] = world.getChunkFromChunkCoords(cX + 1, cZ - 1);
|
||||
|
||||
chunks[3] = world.getChunkFromChunkCoords(cX - 1, cZ );
|
||||
chunks[5] = world.getChunkFromChunkCoords(cX + 1, cZ );
|
||||
|
||||
chunks[6] = world.getChunkFromChunkCoords(cX - 1, cZ + 1);
|
||||
chunks[7] = world.getChunkFromChunkCoords(cX , cZ + 1);
|
||||
chunks[8] = world.getChunkFromChunkCoords(cX + 1, cZ + 1);
|
||||
|
||||
Queue<CoordTuplePair> transceivers = new LinkedList<CoordTuplePair>();
|
||||
CoordTuple src;
|
||||
CoordTuple dst;
|
||||
for (int c = 0; c < 9; ++c)
|
||||
{
|
||||
for(Object obj : chunks[c].chunkTileEntityMap.values())
|
||||
{
|
||||
if (obj instanceof ISignalTransceiver && obj instanceof TileEntity)
|
||||
{
|
||||
dst = ((ISignalTransceiver) obj).getBusCoords();
|
||||
if (dst != null)
|
||||
{
|
||||
src = new CoordTuple(((TileEntity)obj).xCoord, ((TileEntity)obj).yCoord, ((TileEntity)obj).zCoord);
|
||||
transceivers.add(new CoordTuplePair(src,dst));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CoordTuplePair renderPair;
|
||||
while (transceivers.size() > 0)
|
||||
{
|
||||
renderPair = transceivers.remove();
|
||||
|
||||
GL11.glVertex3d(renderPair.a.x + 0.5, renderPair.a.y + 0.5, renderPair.a.z + 0.5);
|
||||
GL11.glVertex3d(renderPair.b.x + 0.5, renderPair.b.y, renderPair.b.z + 0.5);
|
||||
}
|
||||
|
||||
// GL11.glVertex3d(x, y+0.004, z);
|
||||
// GL11.glVertex3d(x+1, y+0.004, z+1);
|
||||
// GL11.glVertex3d(x+1, y+0.004, z);
|
||||
// GL11.glVertex3d(x, y+0.004, z+1);
|
||||
|
||||
GL11.glEnd();
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import net.minecraftforge.fluids.RenderBlockFluid;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.w3c.dom.Document;
|
||||
import tconstruct.TConstruct;
|
||||
import tconstruct.blocks.SignalTerminal;
|
||||
import tconstruct.blocks.SlimeExplosive;
|
||||
import tconstruct.blocks.logic.*;
|
||||
import tconstruct.client.armor.RenderArmorCast;
|
||||
@@ -45,6 +46,7 @@ import tconstruct.inventory.ContainerLandmine;
|
||||
import tconstruct.library.TConstructRegistry;
|
||||
import tconstruct.library.client.*;
|
||||
import tconstruct.library.crafting.ToolBuilder;
|
||||
import tconstruct.library.multiblock.MultiblockServerTickHandler;
|
||||
import tconstruct.library.tools.ToolCore;
|
||||
import tconstruct.util.config.PHConstruct;
|
||||
import tconstruct.util.player.*;
|
||||
@@ -197,6 +199,7 @@ public class TProxyClient extends TProxyCommon
|
||||
// TickRegistry.registerTickHandler(new TimeTicker(), Side.CLIENT);
|
||||
// TickRegistry.registerTickHandler(new TCommonTickHandler(),
|
||||
// Side.CLIENT);
|
||||
TickRegistry.registerScheduledTickHandler(new MultiblockServerTickHandler(), Side.SERVER);
|
||||
}
|
||||
|
||||
/* Registers any rendering code. */
|
||||
@@ -223,6 +226,9 @@ public class TProxyClient extends TProxyCommon
|
||||
RenderingRegistry.registerBlockHandler(new BlockRenderCastingChannel());
|
||||
RenderingRegistry.registerBlockHandler(new SlimeChannelRender());
|
||||
RenderingRegistry.registerBlockHandler(new SlimePadRender());
|
||||
RenderingRegistry.registerBlockHandler(new SignalBusRender());
|
||||
RenderingRegistry.registerBlockHandler(new SignalTerminalRender());
|
||||
|
||||
if (!PHConstruct.newSmeltery)
|
||||
RenderingRegistry.registerBlockHandler(new SmelteryRender());
|
||||
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
package tconstruct.client.block;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import tconstruct.blocks.logic.CastingChannelLogic;
|
||||
import tconstruct.blocks.logic.SignalBusLogic;
|
||||
import tconstruct.blocks.SignalBus.Geometry;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
|
||||
public class SignalBusRender implements ISimpleBlockRenderingHandler
|
||||
{
|
||||
public static int renderID = RenderingRegistry.getNextAvailableRenderId();
|
||||
|
||||
// public static double cable_width_min = 0.375D;
|
||||
// public static double cable_width_max = 1 - cable_width_min;
|
||||
// public static double cable_low_height = 0.2D;
|
||||
// public static double cable_low_offset = 0.0D;
|
||||
//
|
||||
// public static double cable_high_height = 1.0D;
|
||||
// public static double cable_high_offset = 1 - cable_low_height;
|
||||
//
|
||||
// public static double cable_extend_min = 0.0D;
|
||||
// public static double cable_extend_max = 1.0D;
|
||||
//
|
||||
// public static double zfight = 0.0000001D;
|
||||
//
|
||||
@Override
|
||||
public void renderInventoryBlock (Block block, int metadata, int modelID, RenderBlocks renderer)
|
||||
{
|
||||
//Base
|
||||
renderer.setRenderBounds(0.375D, 0.0D, 0.375D, 0.625D, 0.2D, 0.625D);
|
||||
this.renderStandardBlock(block, metadata, renderer);
|
||||
//Extend Z-
|
||||
renderer.setRenderBounds(0.375D, 0.0D, 0.0D, 0.625D, 0.2D, 0.375D);
|
||||
this.renderStandardBlock(block, metadata, renderer);
|
||||
//Extend Z+
|
||||
renderer.setRenderBounds(0.375D, 0.0D, 0.625D, 0.625D, 0.2D, 1D);
|
||||
this.renderStandardBlock(block, metadata, renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderWorldBlock (IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
|
||||
{
|
||||
boolean[] placedSides;
|
||||
boolean[] connectedSides;
|
||||
boolean[] corners;
|
||||
boolean didRender = false;
|
||||
if (modelId == renderID)
|
||||
{
|
||||
SignalBusLogic tile = (SignalBusLogic) world.getBlockTileEntity(x, y, z);
|
||||
placedSides = tile.placedSides();
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (!placedSides[i]){
|
||||
continue;
|
||||
}
|
||||
didRender = true;
|
||||
connectedSides = tile.connectedSides(ForgeDirection.getOrientation(i));
|
||||
corners = tile.getRenderCorners(ForgeDirection.getOrientation(i));
|
||||
|
||||
renderFaceWithConnections(renderer, block, x, y, z, i, placedSides, connectedSides, corners);
|
||||
}
|
||||
if (!didRender)
|
||||
{
|
||||
double minX = Geometry.cable_width_min;
|
||||
double minY = Geometry.cable_low_offset;
|
||||
double minZ = Geometry.cable_width_min;
|
||||
double maxX = Geometry.cable_width_max;
|
||||
double maxY = Geometry.cable_low_height;
|
||||
double maxZ = Geometry.cable_width_max;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void renderFaceWithConnections (RenderBlocks renderer, Block block, int x, int y, int z, int side, boolean[] placed, boolean[] connectedSides, boolean[] corners)
|
||||
{
|
||||
double minX = 0D;
|
||||
double minY = 0D;
|
||||
double minZ = 0D;
|
||||
double maxX = 1D;
|
||||
double maxY = 1D;
|
||||
double maxZ = 1D;
|
||||
int renderCount = 0;
|
||||
|
||||
boolean[] renderDir = {
|
||||
(connectedSides[0] || placed[0] || corners[0]),
|
||||
(connectedSides[1] || placed[1] || corners[1]),
|
||||
(connectedSides[2] || placed[2] || corners[2]),
|
||||
(connectedSides[3] || placed[3] || corners[3]),
|
||||
(connectedSides[4] || placed[4] || corners[4]),
|
||||
(connectedSides[5] || placed[5] || corners[5])
|
||||
};
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0: // DOWN
|
||||
// Render East/West
|
||||
if (renderDir[ForgeDirection.WEST.ordinal()] || renderDir[ForgeDirection.EAST.ordinal()])
|
||||
{
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = Geometry.cable_low_offset;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_low_height;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
maxY += Geometry.zfight;
|
||||
|
||||
minX = (corners[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_corner_min : minX;
|
||||
maxX = (corners[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_corner_max : maxX;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
// Render North/South
|
||||
if (renderDir[ForgeDirection.NORTH.ordinal()] || renderDir[ForgeDirection.SOUTH.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = Geometry.cable_low_offset;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_low_height;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
minZ = (corners[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_corner_min : minZ;
|
||||
maxZ = (corners[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_corner_max : maxZ;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
if (renderCount == 0)
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = Geometry.cable_low_offset;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_low_height;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
break;
|
||||
case 1: // UP
|
||||
// Render East/West
|
||||
if (renderDir[ForgeDirection.WEST.ordinal()] || renderDir[ForgeDirection.EAST.ordinal()])
|
||||
{
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = Geometry.cable_high_offset;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_high_height;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
minY -= Geometry.zfight;
|
||||
|
||||
minX = (corners[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_corner_min : minX;
|
||||
maxX = (corners[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_corner_max : maxX;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
// Render North/South
|
||||
if (renderDir[ForgeDirection.NORTH.ordinal()] || renderDir[ForgeDirection.SOUTH.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = Geometry.cable_high_offset;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_high_height;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
minZ = (corners[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_corner_min : minZ;
|
||||
maxZ = (corners[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_corner_max : maxZ;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
if (renderCount == 0)
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = Geometry.cable_high_offset;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_high_height;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
break;
|
||||
case 2: // NORTH
|
||||
// Render East/West
|
||||
if (renderDir[ForgeDirection.WEST.ordinal()] || renderDir[ForgeDirection.EAST.ordinal()])
|
||||
{
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_low_offset;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_low_height;
|
||||
|
||||
maxZ += Geometry.zfight;
|
||||
|
||||
minX = (corners[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_corner_min : minX;
|
||||
maxX = (corners[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_corner_max : maxX;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
// Render Up/Down
|
||||
if (renderDir[ForgeDirection.DOWN.ordinal()] || renderDir[ForgeDirection.UP.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_low_offset;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_low_height;
|
||||
|
||||
minY = (corners[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_corner_min : minY;
|
||||
maxY = (corners[ForgeDirection.UP.ordinal()]) ? Geometry.cable_corner_max : maxY;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
if (renderCount == 0)
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_low_offset;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_low_height;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
break;
|
||||
case 3: // SOUTH
|
||||
// Render East/West
|
||||
if (renderDir[ForgeDirection.WEST.ordinal()] || renderDir[ForgeDirection.EAST.ordinal()])
|
||||
{
|
||||
minX = (renderDir[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_high_offset;
|
||||
maxX = (renderDir[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_high_height;
|
||||
|
||||
minZ -= Geometry.zfight;
|
||||
|
||||
minX = (corners[ForgeDirection.WEST.ordinal()]) ? Geometry.cable_corner_min : minX;
|
||||
maxX = (corners[ForgeDirection.EAST.ordinal()]) ? Geometry.cable_corner_max : maxX;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
// Render Up/Down
|
||||
if (renderDir[ForgeDirection.DOWN.ordinal()] || renderDir[ForgeDirection.UP.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_high_offset;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_high_height;
|
||||
|
||||
minY = (corners[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_corner_min : minY;
|
||||
maxY = (corners[ForgeDirection.UP.ordinal()]) ? Geometry.cable_corner_max : maxY;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
if (renderCount == 0)
|
||||
{
|
||||
minX = Geometry.cable_width_min;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_high_offset;
|
||||
maxX = Geometry.cable_width_max;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_high_height;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
break;
|
||||
case 4: // WEST
|
||||
// Render North/South
|
||||
if (renderDir[ForgeDirection.NORTH.ordinal()] || renderDir[ForgeDirection.SOUTH.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_low_offset;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_low_height;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
maxX += Geometry.zfight;
|
||||
|
||||
minZ = (corners[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_corner_min : minZ;
|
||||
maxZ = (corners[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_corner_max : maxZ;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
// Render Up/Down
|
||||
if (renderDir[ForgeDirection.DOWN.ordinal()] || renderDir[ForgeDirection.UP.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_low_offset;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_low_height;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
minY = (corners[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_corner_min : minY;
|
||||
maxY = (corners[ForgeDirection.UP.ordinal()]) ? Geometry.cable_corner_max : maxY;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
if (renderCount == 0)
|
||||
{
|
||||
minX = Geometry.cable_low_offset;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_low_height;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
break;
|
||||
case 5: // EAST
|
||||
// Render North/South
|
||||
if (renderDir[ForgeDirection.NORTH.ordinal()] || renderDir[ForgeDirection.SOUTH.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_high_offset;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = (renderDir[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_high_height;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = (renderDir[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
|
||||
minX -= Geometry.zfight;
|
||||
|
||||
minZ = (corners[ForgeDirection.NORTH.ordinal()]) ? Geometry.cable_corner_min : minZ;
|
||||
maxZ = (corners[ForgeDirection.SOUTH.ordinal()]) ? Geometry.cable_corner_max : maxZ;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
// Render Up/Down
|
||||
if (renderDir[ForgeDirection.DOWN.ordinal()] || renderDir[ForgeDirection.UP.ordinal()])
|
||||
{
|
||||
minX = Geometry.cable_high_offset;
|
||||
minY = (renderDir[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_extend_min : Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_high_height;
|
||||
maxY = (renderDir[ForgeDirection.UP.ordinal()]) ? Geometry.cable_extend_max : Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
minY = (corners[ForgeDirection.DOWN.ordinal()]) ? Geometry.cable_corner_min : minY;
|
||||
maxY = (corners[ForgeDirection.UP.ordinal()]) ? Geometry.cable_corner_max : maxY;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
++renderCount;
|
||||
}
|
||||
if (renderCount == 0)
|
||||
{
|
||||
minX = Geometry.cable_high_offset;
|
||||
minY = Geometry.cable_width_min;
|
||||
minZ = Geometry.cable_width_min;
|
||||
maxX = Geometry.cable_high_height;
|
||||
maxY = Geometry.cable_width_max;
|
||||
maxZ = Geometry.cable_width_max;
|
||||
|
||||
renderer.setRenderBounds(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void renderStandardBlock (Block block, int meta, RenderBlocks renderer)
|
||||
{
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, -1.0F, 0.0F);
|
||||
renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(0, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, 1.0F, 0.0F);
|
||||
renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(1, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, 0.0F, -1.0F);
|
||||
renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(2, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, 0.0F, 1.0F);
|
||||
renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(3, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(-1.0F, 0.0F, 0.0F);
|
||||
renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(4, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(1.0F, 0.0F, 0.0F);
|
||||
renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(5, meta));
|
||||
tessellator.draw();
|
||||
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender3DInInventory ()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderId ()
|
||||
{
|
||||
return renderID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package tconstruct.client.block;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import tconstruct.blocks.logic.SignalBusLogic;
|
||||
import tconstruct.blocks.logic.SignalTerminalLogic;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
|
||||
import static tconstruct.blocks.SignalTerminal.TerminalGeometry.*;
|
||||
|
||||
public class SignalTerminalRender implements ISimpleBlockRenderingHandler
|
||||
{
|
||||
public static int renderID = RenderingRegistry.getNextAvailableRenderId();
|
||||
|
||||
@Override
|
||||
public void renderInventoryBlock (Block block, int metadata, int modelID, RenderBlocks renderer)
|
||||
{
|
||||
// Render X-
|
||||
renderer.setRenderBounds(plate_low_min, plate_width_min, plate_width_min, plate_low_max, plate_width_max, plate_width_max);
|
||||
this.renderStandardBlock(block, metadata, renderer);
|
||||
|
||||
renderer.setRenderBounds(center_min, center_min, center_min, center_max, center_max, center_max);
|
||||
this.renderStandardBlock(block, metadata, renderer);
|
||||
|
||||
renderer.setRenderBounds(channel_low_min, channel_width_min, channel_width_min, channel_low_max, channel_width_max, channel_width_max);
|
||||
renderer.setOverrideBlockTexture(SignalTerminalLogic.getChannelIcon(0));
|
||||
this.renderStandardBlock(block, metadata, renderer);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderWorldBlock (IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
|
||||
{
|
||||
int sidesRendered = 0;
|
||||
|
||||
if (modelId == renderID)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
if (!(te instanceof SignalTerminalLogic))
|
||||
{
|
||||
// Render X-
|
||||
renderer.setRenderBounds(plate_low_min, plate_width_min, plate_width_min, plate_low_max, plate_width_max, plate_width_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(center_min, center_min, center_min, center_max, center_max, center_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_low_min, channel_width_min, channel_width_min, channel_low_max, channel_width_max, channel_width_max);
|
||||
renderer.setOverrideBlockTexture(SignalTerminalLogic.getChannelIcon(0));
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
return true;
|
||||
}
|
||||
byte[] connectedSides = ((SignalTerminalLogic) te).getConnectedSides();
|
||||
Icon channelIcons[] = ((SignalTerminalLogic) te).getSideIcons();
|
||||
|
||||
// Center
|
||||
renderer.setRenderBounds(center_min, center_min, center_min, center_max, center_max, center_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
if (connectedSides[ForgeDirection.WEST.ordinal()] != -1)
|
||||
{
|
||||
// Render X-
|
||||
renderer.setRenderBounds(plate_low_min, plate_width_min, plate_width_min, plate_low_max, plate_width_max, plate_width_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_low_min, channel_width_min, channel_width_min, channel_low_max, channel_width_max, channel_width_max);
|
||||
renderer.setOverrideBlockTexture(channelIcons[ForgeDirection.WEST.ordinal()]);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
sidesRendered++;
|
||||
}
|
||||
if (connectedSides[ForgeDirection.EAST.ordinal()] != -1)
|
||||
{
|
||||
//Extend X+
|
||||
renderer.setRenderBounds(plate_high_min, plate_width_min, plate_width_min, plate_high_max, plate_width_max, plate_width_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_high_min, channel_width_min, channel_width_min, channel_high_max, channel_width_max, channel_width_max);
|
||||
renderer.setOverrideBlockTexture(channelIcons[ForgeDirection.EAST.ordinal()]);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
sidesRendered++;
|
||||
}
|
||||
if (connectedSides[ForgeDirection.SOUTH.ordinal()] != -1)
|
||||
{
|
||||
//Extend Z-
|
||||
renderer.setRenderBounds(plate_width_min, plate_width_min, plate_low_min, plate_width_max, plate_width_max, plate_low_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_width_min, channel_width_min, channel_low_min, channel_width_max, channel_width_max, channel_low_max);
|
||||
renderer.setOverrideBlockTexture(channelIcons[ForgeDirection.SOUTH.ordinal()]);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
sidesRendered++;
|
||||
}
|
||||
if (connectedSides[ForgeDirection.NORTH.ordinal()] != -1)
|
||||
{
|
||||
//Extend Z+
|
||||
renderer.setRenderBounds(plate_width_min, plate_width_min, plate_high_min, plate_width_max, plate_width_max, plate_high_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_width_min, channel_width_min, channel_high_min, channel_width_max, channel_width_max, channel_high_max);
|
||||
renderer.setOverrideBlockTexture(channelIcons[ForgeDirection.NORTH.ordinal()]);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
sidesRendered++;
|
||||
}
|
||||
if (connectedSides[ForgeDirection.DOWN.ordinal()] != -1)
|
||||
{
|
||||
//Extend Y-
|
||||
renderer.setRenderBounds(plate_width_min, plate_low_min, plate_width_min, plate_width_max, plate_low_max, plate_width_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_width_min, channel_low_min, channel_width_min, channel_width_max, channel_low_max, channel_width_max);
|
||||
renderer.setOverrideBlockTexture(channelIcons[ForgeDirection.DOWN.ordinal()]);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
sidesRendered++;
|
||||
}
|
||||
if (connectedSides[ForgeDirection.UP.ordinal()] != -1)
|
||||
{
|
||||
//Extend Y+
|
||||
renderer.setRenderBounds(plate_width_min, plate_high_min, plate_width_min, plate_width_max, plate_high_max, plate_width_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_width_min, channel_high_min, channel_width_min, channel_width_max, channel_high_max, channel_width_max);
|
||||
renderer.setOverrideBlockTexture(channelIcons[ForgeDirection.UP.ordinal()]);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
sidesRendered++;
|
||||
}
|
||||
|
||||
if (sidesRendered == 0)
|
||||
{
|
||||
// Render X-
|
||||
renderer.setRenderBounds(plate_low_min, plate_width_min, plate_width_min, plate_low_max, plate_width_max, plate_width_max);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
|
||||
renderer.setRenderBounds(channel_low_min, channel_width_min, channel_width_min, channel_low_max, channel_width_max, channel_width_max);
|
||||
renderer.setOverrideBlockTexture(SignalTerminalLogic.getChannelIcon(0));
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
renderer.clearOverrideBlockTexture();
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void renderStandardBlock (Block block, int meta, RenderBlocks renderer)
|
||||
{
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, -1.0F, 0.0F);
|
||||
renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(0, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, 1.0F, 0.0F);
|
||||
renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(1, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, 0.0F, -1.0F);
|
||||
renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(2, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(0.0F, 0.0F, 1.0F);
|
||||
renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(3, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(-1.0F, 0.0F, 0.0F);
|
||||
renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(4, meta));
|
||||
tessellator.draw();
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setNormal(1.0F, 0.0F, 0.0F);
|
||||
renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(5, meta));
|
||||
tessellator.draw();
|
||||
GL11.glTranslatef(0.5F, 0.5F, 0.5F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender3DInInventory ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRenderId ()
|
||||
{
|
||||
return this.renderID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package tconstruct.common;
|
||||
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SpoolRepairRecipe implements IRecipe
|
||||
{
|
||||
ItemStack spool;
|
||||
ItemStack wire;
|
||||
|
||||
public SpoolRepairRecipe(ItemStack spool, ItemStack wire)
|
||||
{
|
||||
this.spool = spool.copy();
|
||||
this.spool.setItemDamage(256);
|
||||
this.wire = wire.copy();
|
||||
}
|
||||
@Override
|
||||
public boolean matches (InventoryCrafting inventorycrafting, World world)
|
||||
{
|
||||
int invLength = inventorycrafting.getSizeInventory();
|
||||
boolean foundSpool = false;
|
||||
int countWire = 0;
|
||||
ItemStack tmpStack;
|
||||
for (int i = 0; i < invLength; ++i)
|
||||
{
|
||||
tmpStack = inventorycrafting.getStackInSlot(i);
|
||||
if (tmpStack instanceof ItemStack)
|
||||
{
|
||||
if (tmpStack.itemID == spool.itemID)
|
||||
{
|
||||
if (foundSpool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
foundSpool = true;
|
||||
}
|
||||
else if (tmpStack.itemID == wire.itemID && tmpStack.getItemDamage() == wire.getItemDamage())
|
||||
{
|
||||
++countWire;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (countWire > 0 && foundSpool)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCraftingResult (InventoryCrafting inventorycrafting)
|
||||
{
|
||||
int invLength = inventorycrafting.getSizeInventory();
|
||||
boolean foundSpool = false;
|
||||
ItemStack newSpool = null;
|
||||
int countWire = 0;
|
||||
ItemStack tmpStack;
|
||||
for (int i = 0; i < invLength; ++i)
|
||||
{
|
||||
tmpStack = inventorycrafting.getStackInSlot(i);
|
||||
if (tmpStack instanceof ItemStack)
|
||||
{
|
||||
if (tmpStack.itemID == spool.itemID)
|
||||
{
|
||||
newSpool = tmpStack.copy();
|
||||
foundSpool = true;
|
||||
}
|
||||
else if (tmpStack.itemID == wire.itemID && tmpStack.getItemDamage() == wire.getItemDamage())
|
||||
{
|
||||
++countWire;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (countWire > 0 && newSpool != null)
|
||||
{
|
||||
newSpool.setItemDamage(newSpool.getItemDamage() - countWire);
|
||||
}
|
||||
|
||||
return newSpool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRecipeSize ()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRecipeOutput ()
|
||||
{
|
||||
return spool.copy();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -279,6 +279,13 @@ public class TContent implements IFuelHandler
|
||||
public static Item leggingsWood;
|
||||
public static Item bootsWood;
|
||||
public static EnumArmorMaterial materialWood;
|
||||
|
||||
//Signal & Logic
|
||||
public static Block signalBus;
|
||||
public static Block signalTerminal;
|
||||
|
||||
public static Item spoolWire;
|
||||
public static Item lengthWire;
|
||||
|
||||
//Temporary items
|
||||
//public static Item armorTest = new ArmorStandard(2445, 4, EnumArmorPart.HELMET).setCreativeTab(CreativeTabs.tabAllSearch);
|
||||
@@ -825,6 +832,16 @@ public class TContent implements IFuelHandler
|
||||
//Rail
|
||||
woodenRail = new WoodRail(PHConstruct.woodenRail).setStepSound(Block.soundWoodFootstep).setCreativeTab(TConstructRegistry.blockTab).setUnlocalizedName("rail.wood");
|
||||
GameRegistry.registerBlock(woodenRail, "rail.wood");
|
||||
|
||||
//Signal & Logic
|
||||
signalBus = (new SignalBus(PHConstruct.signalBus)).setUnlocalizedName("tconstruct.signalbus");
|
||||
GameRegistry.registerBlock(signalBus, SignalBusItem.class, "SignalBus");
|
||||
GameRegistry.registerTileEntity(SignalBusLogic.class, "SignalBus");
|
||||
|
||||
signalTerminal = (new SignalTerminal(PHConstruct.signalTerminal)).setUnlocalizedName("tconstruct.signalterminal");
|
||||
GameRegistry.registerBlock(signalTerminal, SignalTerminalItem.class, "SignalTerminal");
|
||||
GameRegistry.registerTileEntity(SignalTerminalLogic.class, "SignalTerminal");
|
||||
|
||||
}
|
||||
|
||||
void registerItems ()
|
||||
@@ -964,6 +981,9 @@ public class TContent implements IFuelHandler
|
||||
leggingsWood = new ArmorBasic(PHConstruct.woodPants, materialWood, 2, "wood").setUnlocalizedName("tconstruct.leggingsWood");
|
||||
bootsWood = new ArmorBasic(PHConstruct.woodBoots, materialWood, 3, "wood").setUnlocalizedName("tconstruct.bootsWood");
|
||||
|
||||
spoolWire = new SpoolOfWire(PHConstruct.spoolWire).setUnlocalizedName("spoolwire");
|
||||
lengthWire = new LengthWire(PHConstruct.lengthWire).setUnlocalizedName("lengthwire");
|
||||
|
||||
// essenceCrystal = new EssenceCrystal(PHConstruct.essenceCrystal).setUnlocalizedName("tconstruct.crystal.essence");
|
||||
|
||||
String[] materialStrings = { "paperStack", "greenSlimeCrystal", "searedBrick", "ingotCobalt", "ingotArdite", "ingotManyullyn", "mossBall", "lavaCrystal", "necroticBone", "ingotCopper",
|
||||
@@ -989,7 +1009,10 @@ public class TContent implements IFuelHandler
|
||||
TConstructRegistry.addItemStackToDirectory("canisterEmpty", new ItemStack(heartCanister, 1, 0));
|
||||
TConstructRegistry.addItemStackToDirectory("miniRedHeart", new ItemStack(heartCanister, 1, 1));
|
||||
TConstructRegistry.addItemStackToDirectory("canisterRedHeart", new ItemStack(heartCanister, 1, 2));
|
||||
|
||||
|
||||
TConstructRegistry.addItemStackToDirectory("spoolWire", new ItemStack(spoolWire, 1, 0));
|
||||
TConstructRegistry.addItemStackToDirectory("lengthWire", new ItemStack(lengthWire, 1, 0));
|
||||
|
||||
//Vanilla stack sizes
|
||||
Item.doorWood.setMaxStackSize(16);
|
||||
Item.doorIron.setMaxStackSize(16);
|
||||
@@ -1341,6 +1364,13 @@ public class TContent implements IFuelHandler
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(landmine, 1, 3), "mcm", "rpr", 'm', Item.redstoneRepeater, 'c', new ItemStack(blankPattern, 1, 1), 'r', Item.redstone, 'p',
|
||||
Block.pressurePlateStone));
|
||||
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(signalBus.blockID, 1, 0), "www", "sss", 'w', lengthWire, 's', new ItemStack(Block.stoneSingleSlab, 1, OreDictionary.WILDCARD_VALUE)));
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(signalTerminal.blockID, 1, 0), "b", "g", "b", 'b', new ItemStack(signalBus.blockID, 1, 0), 'g', new ItemStack(Block.glass, 1, OreDictionary.WILDCARD_VALUE)));
|
||||
|
||||
GameRegistry.addRecipe(new ItemStack(lengthWire, 8), "a", "a", 'a', aluBrass);
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(spoolWire, 1, 256 - 8), "www", "wrw", "www", 'w', lengthWire, 'r', "stoneRod"));
|
||||
GameRegistry.addRecipe(new SpoolRepairRecipe(new ItemStack(spoolWire, 1, 256), new ItemStack(lengthWire, 1)));
|
||||
|
||||
//Ultra hardcore recipes
|
||||
Object goldType = null;
|
||||
RecipeRemover.removeShapedRecipe(new ItemStack(Item.appleGold));
|
||||
@@ -1463,7 +1493,7 @@ public class TContent implements IFuelHandler
|
||||
patternOutputs = new Item[] { toolRod, pickaxeHead, shovelHead, hatchetHead, swordBlade, wideGuard, handGuard, crossbar, binding, frypanHead, signHead, knifeBlade, chiselHead, toughRod,
|
||||
toughBinding, largePlate, broadAxeHead, scytheBlade, excavatorHead, largeSwordBlade, hammerHead, fullGuard, null, null, arrowhead };
|
||||
|
||||
int[] nonMetals = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 17 };
|
||||
int[] nonMetals = { 0, 1, 3, 4, 5, 6, 7, 8, 9 };
|
||||
|
||||
if (PHConstruct.craftMetalTools)
|
||||
{
|
||||
@@ -1597,6 +1627,7 @@ public class TContent implements IFuelHandler
|
||||
|
||||
//Buckets
|
||||
ItemStack bucket = new ItemStack(Item.bucketEmpty);
|
||||
|
||||
for (int sc = 0; sc < 24; sc++)
|
||||
{
|
||||
tableCasting.addCastingRecipe(new ItemStack(buckets, 1, sc), new FluidStack(fluids[sc], FluidContainerRegistry.BUCKET_VOLUME), bucket, true, 10);
|
||||
@@ -1732,6 +1763,7 @@ public class TContent implements IFuelHandler
|
||||
Smeltery.addMelting(FluidType.Steel, new ItemStack(toolShard, 1, 16), 0, TConstruct.chunkLiquidValue);
|
||||
|
||||
// Items
|
||||
|
||||
Smeltery.addMelting(FluidType.AluminumBrass, new ItemStack(blankPattern, 4, 1), -50, TConstruct.ingotLiquidValue);
|
||||
Smeltery.addMelting(FluidType.Gold, new ItemStack(blankPattern, 4, 1), -50, TConstruct.ingotLiquidValue);
|
||||
|
||||
@@ -2002,7 +2034,7 @@ public class TContent implements IFuelHandler
|
||||
|
||||
ensureOreIsRegistered("stoneMossy", new ItemStack(Block.stoneBrick, 1, 1));
|
||||
ensureOreIsRegistered("stoneMossy", new ItemStack(Block.cobblestoneMossy));
|
||||
|
||||
|
||||
ensureOreIsRegistered("crafterWood", new ItemStack(Block.workbench, 1));
|
||||
|
||||
String[] matNames = { "wood", "stone", "iron", "flint", "cactus", "bone", "obsidian", "netherrack", "slime", "paper", "cobalt", "ardite", "manyullyn", "copper", "bronze", "alumite", "steel",
|
||||
|
||||
@@ -2,6 +2,8 @@ package tconstruct.common;
|
||||
|
||||
import cpw.mods.fml.common.network.IGuiHandler;
|
||||
import cpw.mods.fml.common.registry.LanguageRegistry;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
@@ -9,6 +11,7 @@ import tconstruct.TConstruct;
|
||||
import tconstruct.blocks.logic.TileEntityLandmine;
|
||||
import tconstruct.inventory.*;
|
||||
import tconstruct.library.blocks.InventoryLogic;
|
||||
import tconstruct.library.multiblock.MultiblockServerTickHandler;
|
||||
import tconstruct.util.player.TPlayerStats;
|
||||
|
||||
/**
|
||||
@@ -85,6 +88,7 @@ public class TProxyCommon implements IGuiHandler
|
||||
public void registerTickHandler ()
|
||||
{
|
||||
//TickRegistry.registerTickHandler(new TimeTicker(), Side.SERVER);
|
||||
TickRegistry.registerScheduledTickHandler(new MultiblockServerTickHandler(), Side.SERVER);
|
||||
}
|
||||
|
||||
/* Registers any rendering code. Does nothing server-side */
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package tconstruct.items;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import tconstruct.library.TConstructRegistry;
|
||||
import net.minecraft.client.renderer.texture.IconRegister;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.util.MathHelper;
|
||||
|
||||
public class LengthWire extends Item
|
||||
{
|
||||
public String[] textureNames = new String[] { "lengthwire" };
|
||||
public String[] unlocalizedNames = new String[] { "lengthwire" };
|
||||
public String folder = "logic/";
|
||||
public Icon[] icons;
|
||||
|
||||
|
||||
public LengthWire(int id)
|
||||
{
|
||||
super(id);
|
||||
this.setCreativeTab(TConstructRegistry.toolTab);
|
||||
this.maxStackSize = 64;
|
||||
this.setHasSubtypes(false);
|
||||
}
|
||||
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public Icon getIconFromDamage (int meta)
|
||||
{
|
||||
int arr = MathHelper.clamp_int(meta, 0, unlocalizedNames.length);
|
||||
return icons[arr];
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons (IconRegister iconRegister)
|
||||
{
|
||||
this.icons = new Icon[textureNames.length];
|
||||
|
||||
for (int i = 0; i < this.icons.length; ++i)
|
||||
{
|
||||
if (!(textureNames[i].equals("")))
|
||||
this.icons[i] = iconRegister.registerIcon("tinker:" + folder + textureNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void getSubItems (int id, CreativeTabs tab, List list)
|
||||
{
|
||||
for (int i = 0; i < unlocalizedNames.length; i++)
|
||||
if (!(textureNames[i].equals("")))
|
||||
list.add(new ItemStack(id, 1, i));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package tconstruct.items;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import tconstruct.blocks.logic.SignalBusLogic;
|
||||
import tconstruct.blocks.logic.SignalTerminalLogic;
|
||||
import tconstruct.library.TConstructRegistry;
|
||||
import net.minecraft.client.renderer.texture.IconRegister;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Icon;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SpoolOfWire extends Item
|
||||
{
|
||||
public String textureName = "spoolwire";
|
||||
public String unlocalizedName = "spoolwire";
|
||||
public String folder = "logic/";
|
||||
public Icon icon;
|
||||
|
||||
public SpoolOfWire(int id)
|
||||
{
|
||||
super(id);
|
||||
this.setCreativeTab(TConstructRegistry.toolTab);
|
||||
this.maxStackSize = 1;
|
||||
this.setMaxDamage(256);
|
||||
this.setHasSubtypes(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getContainerItemStack (ItemStack itemStack)
|
||||
{
|
||||
return new ItemStack(this.itemID, 1, this.getMaxDamage());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void addInformation (ItemStack stack, EntityPlayer player, List list, boolean par4)
|
||||
{
|
||||
switch (stack.getItemDamage())
|
||||
{
|
||||
case 0:
|
||||
list.add("Wirey!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public String getUnlocalizedName (ItemStack stack)
|
||||
{
|
||||
return "item." + unlocalizedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemUse (ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int par7, float par8, float par9, float par10)
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(x, y, z);
|
||||
NBTTagCompound data = itemstack.stackTagCompound;
|
||||
NBTTagCompound spoolData = null;
|
||||
|
||||
if (world.isRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
data = new NBTTagCompound();
|
||||
itemstack.stackTagCompound = data;
|
||||
}
|
||||
if (te != null && te instanceof SignalBusLogic)
|
||||
{
|
||||
if (data.hasKey("spoolWireData"))
|
||||
{
|
||||
spoolData = data.getCompoundTag("spoolWireData");
|
||||
|
||||
int targetDim = spoolData.getInteger("targetDim");
|
||||
int targetX = spoolData.getInteger("targetX");
|
||||
int targetY = spoolData.getInteger("targetY");
|
||||
int targetZ = spoolData.getInteger("targetZ");
|
||||
|
||||
int calc = Math.abs(targetX - x) + Math.abs(targetY - y) + Math.abs(targetZ - z);
|
||||
if ((itemstack.getMaxDamage() - itemstack.getItemDamage()) < calc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (targetDim == world.provider.dimensionId && calc < 16)
|
||||
{
|
||||
((SignalBusLogic) te).registerTerminal(world, targetX, targetY, targetZ, true);
|
||||
data.removeTag("spoolWireData");
|
||||
|
||||
itemstack.damageItem(calc, player);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if (te != null && te instanceof SignalTerminalLogic)
|
||||
{
|
||||
data = itemstack.stackTagCompound;
|
||||
spoolData = null;
|
||||
if (data.hasKey("spoolWireData"))
|
||||
{
|
||||
data.removeTag("spoolWireData");
|
||||
}
|
||||
spoolData = new NBTTagCompound();
|
||||
|
||||
spoolData.setInteger("targetDim", world.provider.dimensionId);
|
||||
spoolData.setInteger("targetX", x);
|
||||
spoolData.setInteger("targetY", y);
|
||||
spoolData.setInteger("targetZ", z);
|
||||
|
||||
data.setCompoundTag("spoolWireData", spoolData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public Icon getIconFromDamage (int meta)
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons (IconRegister iconRegister)
|
||||
{
|
||||
this.icon = iconRegister.registerIcon("tinker:" + folder + textureName);
|
||||
}
|
||||
|
||||
public void getSubItems (int id, CreativeTabs tab, List list)
|
||||
{
|
||||
list.add(new ItemStack(id, 1, 0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package tconstruct.items.blocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import tconstruct.blocks.logic.SignalBusLogic;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
|
||||
public class SignalBusItem extends ItemBlock
|
||||
{
|
||||
public static final String blockType[] = { "signalbus" };
|
||||
|
||||
public SignalBusItem(int id)
|
||||
{
|
||||
super(id);
|
||||
this.maxStackSize = 64;
|
||||
this.setHasSubtypes(false);
|
||||
}
|
||||
|
||||
public int getMetadata (int meta)
|
||||
{
|
||||
return meta;
|
||||
}
|
||||
|
||||
public String getUnlocalizedName (ItemStack itemstack)
|
||||
{
|
||||
int pos = MathHelper.clamp_int(itemstack.getItemDamage(), 0, blockType.length - 1);
|
||||
return (new StringBuilder()).append("tile.").append(blockType[pos]).toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean canPlaceItemBlockOnSide (World world, int x, int y, int z, int side, EntityPlayer entityPlayer, ItemStack itemStack)
|
||||
{
|
||||
return super.canPlaceItemBlockOnSide(world, x, y, z, side, entityPlayer, itemStack) || _canPlaceItemBlockOnSide(world, x, y, z, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemUse (ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
int tmpX = x;
|
||||
int tmpY = y;
|
||||
int tmpZ = z;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0:
|
||||
tmpY += -1;
|
||||
break;
|
||||
case 1:
|
||||
tmpY += 1;
|
||||
break;
|
||||
case 2:
|
||||
tmpZ += -1;
|
||||
break;
|
||||
case 3:
|
||||
tmpZ += 1;
|
||||
break;
|
||||
case 4:
|
||||
tmpX += -1;
|
||||
break;
|
||||
case 5:
|
||||
tmpX += 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int tside = side;
|
||||
switch (side)
|
||||
{
|
||||
case 0: // DOWN
|
||||
case 1: // UP
|
||||
case 2: // NORTH
|
||||
case 3: // SOUTH
|
||||
case 4: // EAST
|
||||
case 5: // WEST
|
||||
tside = ForgeDirection.OPPOSITES[side];
|
||||
break;
|
||||
default:
|
||||
tside = side;
|
||||
break;
|
||||
}
|
||||
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
stack.stackTagCompound = data;
|
||||
data.setInteger("connectedSide", tside);
|
||||
|
||||
if (super.onItemUse(stack, player, world, x, y, z, side, hitX, hitY, hitZ))
|
||||
{
|
||||
stack.stackTagCompound = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(_canPlaceItemBlockOnSide(world, x, y, z, side)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TileEntity te = world.getBlockTileEntity(tmpX, tmpY, tmpZ);
|
||||
|
||||
((SignalBusLogic) te).addPlacedSide(tside);
|
||||
|
||||
stack.stackTagCompound = null;
|
||||
|
||||
--stack.stackSize;
|
||||
|
||||
world.markBlockForRenderUpdate(x, y, z);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private boolean _canPlaceItemBlockOnSide (World world, int x, int y, int z, int side)
|
||||
{
|
||||
int tmpX = x;
|
||||
int tmpY = y;
|
||||
int tmpZ = z;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0:
|
||||
tmpY += -1;
|
||||
break;
|
||||
case 1:
|
||||
tmpY += 1;
|
||||
break;
|
||||
case 2:
|
||||
tmpZ += -1;
|
||||
break;
|
||||
case 3:
|
||||
tmpZ += 1;
|
||||
break;
|
||||
case 4:
|
||||
tmpX += -1;
|
||||
break;
|
||||
case 5:
|
||||
tmpX += 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (world.getBlockId(tmpX, tmpY, tmpZ) == this.getBlockID())
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(tmpX, tmpY, tmpZ);
|
||||
if (te == null || !(te instanceof SignalBusLogic))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package tconstruct.items.blocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import tconstruct.blocks.logic.SignalTerminalLogic;
|
||||
import tconstruct.library.TConstructRegistry;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
|
||||
public class SignalTerminalItem extends ItemBlock
|
||||
{
|
||||
public static final String blockType[] = { "signalterminal" };
|
||||
|
||||
public SignalTerminalItem(int id)
|
||||
{
|
||||
super(id);
|
||||
this.maxStackSize = 64;
|
||||
this.setHasSubtypes(false);
|
||||
}
|
||||
|
||||
public int getMetadata (int meta)
|
||||
{
|
||||
return meta;
|
||||
}
|
||||
|
||||
public String getUnlocalizedName (ItemStack itemstack)
|
||||
{
|
||||
int pos = MathHelper.clamp_int(itemstack.getItemDamage(), 0, blockType.length - 1);
|
||||
return (new StringBuilder()).append("tile.").append(blockType[pos]).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean placeBlockAt (ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, int metadata)
|
||||
{
|
||||
return super.placeBlockAt(stack, player, world, x, y, z, side, hitX, hitY, hitZ, metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean canPlaceItemBlockOnSide (World world, int x, int y, int z, int side, EntityPlayer entityPlayer, ItemStack itemStack)
|
||||
{
|
||||
if (super.canPlaceItemBlockOnSide(world, x, y, z, side, entityPlayer, itemStack) || _canPlaceItemBlockOnSide(world, x, y, z, side))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemUse (ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
int tmpX = x;
|
||||
int tmpY = y;
|
||||
int tmpZ = z;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0:
|
||||
tmpY += -1;
|
||||
break;
|
||||
case 1:
|
||||
tmpY += 1;
|
||||
break;
|
||||
case 2:
|
||||
tmpZ += -1;
|
||||
break;
|
||||
case 3:
|
||||
tmpZ += 1;
|
||||
break;
|
||||
case 4:
|
||||
tmpX += -1;
|
||||
break;
|
||||
case 5:
|
||||
tmpX += 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int tside = side;
|
||||
switch (side)
|
||||
{
|
||||
case 0: // DOWN
|
||||
case 1: // UP
|
||||
case 4: // EAST
|
||||
case 5: // WEST
|
||||
tside = ForgeDirection.OPPOSITES[side];
|
||||
break;
|
||||
default:
|
||||
tside = side;
|
||||
break;
|
||||
}
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
stack.stackTagCompound = data;
|
||||
data.setInteger("connectedSide", tside);
|
||||
|
||||
if (super.onItemUse(stack, player, world, x, y, z, side, hitX, hitY, hitZ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(_canPlaceItemBlockOnSide(world, x, y, z, side)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TileEntity te = world.getBlockTileEntity(tmpX, tmpY, tmpZ);
|
||||
|
||||
((SignalTerminalLogic) te).addPendingSide(tside);
|
||||
((SignalTerminalLogic) te).connectPending();
|
||||
|
||||
stack.stackTagCompound = null;
|
||||
|
||||
--stack.stackSize;
|
||||
|
||||
world.markBlockForRenderUpdate(x, y, z);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private boolean _canPlaceItemBlockOnSide (World world, int x, int y, int z, int side)
|
||||
{
|
||||
int tmpX = x;
|
||||
int tmpY = y;
|
||||
int tmpZ = z;
|
||||
|
||||
switch (side)
|
||||
{
|
||||
case 0:
|
||||
tmpY += -1;
|
||||
break;
|
||||
case 1:
|
||||
tmpY += 1;
|
||||
break;
|
||||
case 2:
|
||||
tmpZ += -1;
|
||||
break;
|
||||
case 3:
|
||||
tmpZ += 1;
|
||||
break;
|
||||
case 4:
|
||||
tmpX += -1;
|
||||
break;
|
||||
case 5:
|
||||
tmpX += 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (world.getBlockId(tmpX, tmpY, tmpZ) == this.getBlockID())
|
||||
{
|
||||
TileEntity te = world.getBlockTileEntity(tmpX, tmpY, tmpZ);
|
||||
if (te == null || !(te instanceof SignalTerminalLogic))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package tconstruct.library.component;
|
||||
|
||||
import net.minecraftforge.common.ForgeDirection;
|
||||
|
||||
public interface ISignalBusConnectable
|
||||
{
|
||||
public boolean connectableOnFace (ForgeDirection side);
|
||||
|
||||
public boolean connectableOnCorner (ForgeDirection side, ForgeDirection turn);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package tconstruct.library.multiblock;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockContainer;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class BlockMultiblock extends BlockContainer
|
||||
{
|
||||
|
||||
protected BlockMultiblock(int par1, Material par2Material)
|
||||
{
|
||||
super(par1, par2Material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract TileEntity createNewTileEntity (World world);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package tconstruct.library.multiblock;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
|
||||
public interface IMultiblockMember
|
||||
{
|
||||
|
||||
public boolean isCompatible (Object other);
|
||||
|
||||
public boolean isConnected ();
|
||||
|
||||
public MultiblockMasterBaseLogic getMultiblockMaster ();
|
||||
|
||||
public CoordTuple getCoordInWorld ();
|
||||
|
||||
public void onAttached (MultiblockMasterBaseLogic newMaster);
|
||||
|
||||
public void onDetached (MultiblockMasterBaseLogic oldMaster);
|
||||
|
||||
public void createNewMultiblock ();
|
||||
|
||||
public MultiblockMasterBaseLogic getNewMultiblockMasterObject ();
|
||||
|
||||
public void onMasterMerged (MultiblockMasterBaseLogic newMaster);
|
||||
|
||||
public void setVisited ();
|
||||
|
||||
public void setUnivisted ();
|
||||
|
||||
public boolean isVisited ();
|
||||
|
||||
public void becomeMultiblockSaveDelegate ();
|
||||
|
||||
public void forfeitMultiblockSaveDelegate ();
|
||||
|
||||
public boolean isMultiblockSaveDelegate ();
|
||||
|
||||
public IMultiblockMember[] getNeighboringMembers ();
|
||||
|
||||
public void onBlockAdded (World world, int x, int y, int z);
|
||||
|
||||
public void onChunkLoad ();
|
||||
|
||||
public void onOrphaned ();
|
||||
|
||||
public void onChunkUnloaded ();
|
||||
|
||||
public World getWorldObj ();
|
||||
|
||||
public boolean willConnect (CoordTuple coord);
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
package tconstruct.library.multiblock;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.Packet132TileEntityData;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class MultiblockBaseLogic extends TileEntity implements IMultiblockMember
|
||||
{
|
||||
|
||||
private MultiblockMasterBaseLogic master;
|
||||
private byte visited;
|
||||
private static final byte kUnvisited = 0;
|
||||
private static final byte kVisited = 1;
|
||||
|
||||
private boolean saveMultiblockData;
|
||||
private NBTTagCompound cachedMultiblockData;
|
||||
private boolean doUpdate;
|
||||
|
||||
public MultiblockBaseLogic()
|
||||
{
|
||||
super();
|
||||
master = null;
|
||||
visited = kUnvisited;
|
||||
saveMultiblockData = false;
|
||||
doUpdate = false;
|
||||
cachedMultiblockData = null;
|
||||
}
|
||||
|
||||
public boolean isCompatible (Object other)
|
||||
{
|
||||
return other.getClass().equals(this.getClass());
|
||||
}
|
||||
|
||||
public void doMultiblockTick ()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected ()
|
||||
{
|
||||
return (master != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willConnect (CoordTuple coord)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiblockMasterBaseLogic getMultiblockMaster ()
|
||||
{
|
||||
return master;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoordTuple getCoordInWorld ()
|
||||
{
|
||||
return new CoordTuple(this.xCoord, this.yCoord, this.zCoord);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttached (MultiblockMasterBaseLogic newMaster)
|
||||
{
|
||||
this.master = newMaster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetached (MultiblockMasterBaseLogic oldMaster)
|
||||
{
|
||||
if (this.master != oldMaster)
|
||||
{
|
||||
throw new IllegalArgumentException("Detaching from wrong master");
|
||||
}
|
||||
|
||||
this.master = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNewMultiblock ()
|
||||
{
|
||||
MultiblockMasterBaseLogic newMaster = getNewMultiblockMasterObject();
|
||||
newMaster.attachBlock(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMasterMerged (MultiblockMasterBaseLogic newMaster)
|
||||
{
|
||||
assert (this.master != newMaster);
|
||||
|
||||
this.master = newMaster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisited ()
|
||||
{
|
||||
this.visited = kVisited;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnivisted ()
|
||||
{
|
||||
this.visited = kUnvisited;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisited ()
|
||||
{
|
||||
return this.visited != kUnvisited;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void becomeMultiblockSaveDelegate ()
|
||||
{
|
||||
this.saveMultiblockData = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forfeitMultiblockSaveDelegate ()
|
||||
{
|
||||
this.saveMultiblockData = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultiblockSaveDelegate ()
|
||||
{
|
||||
return this.saveMultiblockData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMultiblockMember[] getNeighboringMembers ()
|
||||
{
|
||||
CoordTuple[] neighbors = getNeighborCoords();
|
||||
TileEntity te;
|
||||
List<IMultiblockMember> neighborMembers = new LinkedList<IMultiblockMember>();
|
||||
for (CoordTuple neighbor : neighbors)
|
||||
{
|
||||
te = this.worldObj.getBlockTileEntity(neighbor.x, neighbor.y, neighbor.z);
|
||||
if (te instanceof IMultiblockMember)
|
||||
{
|
||||
// Verify compatible member
|
||||
if (((IMultiblockMember) te).isCompatible((Object) this) && ((IMultiblockMember) te).willConnect(getCoordInWorld()))
|
||||
{
|
||||
neighborMembers.add((IMultiblockMember) te);
|
||||
}
|
||||
}
|
||||
}
|
||||
IMultiblockMember[] tmp = new IMultiblockMember[neighborMembers.size()];
|
||||
return neighborMembers.toArray(tmp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded (World world, int x, int y, int z)
|
||||
{
|
||||
IMultiblockMember[] neighbors = getNeighboringMembers();
|
||||
|
||||
List<MultiblockMasterBaseLogic> masters = new LinkedList<MultiblockMasterBaseLogic>();
|
||||
|
||||
for (IMultiblockMember neighbor : neighbors)
|
||||
{
|
||||
if (neighbor.isConnected() && !masters.contains(neighbor.getMultiblockMaster()))
|
||||
{
|
||||
masters.add(neighbor.getMultiblockMaster());
|
||||
}
|
||||
}
|
||||
|
||||
if (masters.size() > 0)
|
||||
{
|
||||
MultiblockMasterBaseLogic targetMaster = null;
|
||||
|
||||
for (MultiblockMasterBaseLogic candidateMaster : masters)
|
||||
{
|
||||
if (targetMaster == null)
|
||||
{
|
||||
targetMaster = candidateMaster;
|
||||
}
|
||||
else
|
||||
{
|
||||
int comparison = targetMaster.getReferenceCoord().compareTo(candidateMaster.getReferenceCoord());
|
||||
if (comparison < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (comparison == 0)
|
||||
{
|
||||
throw new IllegalStateException(String.format("Found two controllers (hashes %d, %d) with identical reference coord %s", targetMaster.hashCode(), candidateMaster.hashCode(),
|
||||
targetMaster.getReferenceCoord().toString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
targetMaster = candidateMaster;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert (targetMaster != null);
|
||||
|
||||
masters.remove(targetMaster);
|
||||
targetMaster.attachBlock(this);
|
||||
|
||||
if (masters.size() > 0)
|
||||
{
|
||||
CoordTuple hostLoc = this.master.getReferenceCoord();
|
||||
this.master.beginMerging();
|
||||
for (MultiblockMasterBaseLogic masterToMerge : masters)
|
||||
{
|
||||
this.master.merge(masterToMerge);
|
||||
}
|
||||
this.master.endMerging();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.createNewMultiblock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOrphaned ()
|
||||
{
|
||||
if (this.isConnected())
|
||||
{
|
||||
// Turns out, we're not an orphan after all
|
||||
return;
|
||||
}
|
||||
|
||||
createNewMultiblock();
|
||||
// Now for fun. Add all neighbors and DFS out into the world.
|
||||
Queue<IMultiblockMember> membersToCheck = new LinkedList<IMultiblockMember>();
|
||||
// Add all unconnected neighbors
|
||||
CoordTuple[] neighborCoords = getNeighborCoords();
|
||||
for (CoordTuple coord : neighborCoords)
|
||||
{
|
||||
TileEntity neighborTE = this.worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
if (neighborTE instanceof IMultiblockMember && !((IMultiblockMember) neighborTE).isConnected() && ((IMultiblockMember) neighborTE).willConnect(getCoordInWorld()))
|
||||
{
|
||||
membersToCheck.add((IMultiblockMember) neighborTE);
|
||||
}
|
||||
}
|
||||
|
||||
IMultiblockMember member;
|
||||
while (!membersToCheck.isEmpty())
|
||||
{
|
||||
member = membersToCheck.remove();
|
||||
if (member.isConnected())
|
||||
{
|
||||
// This member has better things to do
|
||||
continue;
|
||||
}
|
||||
|
||||
// We're already connected by virtue of the new master
|
||||
this.master.attachBlock(member);
|
||||
|
||||
// Add all unconnected neighbors of this member
|
||||
IMultiblockMember[] neighborMembers = member.getNeighboringMembers();
|
||||
for (IMultiblockMember neighbor : neighborMembers)
|
||||
{
|
||||
if (!neighbor.isConnected())
|
||||
{
|
||||
membersToCheck.add(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT (NBTTagCompound data)
|
||||
{
|
||||
super.readFromNBT(data);
|
||||
|
||||
// We can't directly initialize a multiblock master yet, so we cache the data here until
|
||||
// we receive a validate() call, which creates the controller and hands off the cached data.
|
||||
if (data.hasKey("multiblockData"))
|
||||
{
|
||||
this.cachedMultiblockData = data.getCompoundTag("multiblockData");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT (NBTTagCompound data)
|
||||
{
|
||||
super.writeToNBT(data);
|
||||
|
||||
if (this.saveMultiblockData)
|
||||
{
|
||||
NBTTagCompound multiblockData = new NBTTagCompound();
|
||||
this.master.writeToNBT(multiblockData);
|
||||
data.setCompoundTag("multiblockData", multiblockData);
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore Vanilla TE updates
|
||||
@Override
|
||||
public boolean canUpdate ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate ()
|
||||
{
|
||||
super.invalidate();
|
||||
|
||||
detachSelf(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnload ()
|
||||
{
|
||||
super.onChunkUnload();
|
||||
|
||||
if (this.worldObj.isRemote)
|
||||
{
|
||||
detachSelf(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkLoad ()
|
||||
{
|
||||
if (this.cachedMultiblockData != null)
|
||||
{
|
||||
// We need to create a multiblock BUT we cannot check the world yet.
|
||||
// So we do something stupid and special.
|
||||
MultiblockMasterBaseLogic newMaster = getNewMultiblockMasterObject();
|
||||
newMaster.restore(this.cachedMultiblockData);
|
||||
this.cachedMultiblockData = null;
|
||||
newMaster.attachBlock(this); // This should grab any other connected blocks in the chunk
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.isConnected())
|
||||
{
|
||||
// Ignore blocks that are already connected
|
||||
this.onBlockAdded(this.worldObj, xCoord, yCoord, zCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnloaded ()
|
||||
{
|
||||
detachSelf(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate ()
|
||||
{
|
||||
super.validate();
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
MultiblockRegistry.registerMember(this.worldObj, ChunkCoordIntPair.chunkXZ2Int(xCoord >> 4, zCoord >> 4), this);
|
||||
|
||||
if (!this.worldObj.getChunkProvider().chunkExists(xCoord >> 4, zCoord >> 4))
|
||||
{
|
||||
boolean master = this.cachedMultiblockData != null;
|
||||
MultiblockRegistry.onMemberLoad(this.worldObj, ChunkCoordIntPair.chunkXZ2Int(xCoord >> 4, zCoord >> 4), this, master);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract MultiblockMasterBaseLogic getNewMultiblockMasterObject ();
|
||||
|
||||
protected void attachSelf (World world, MultiblockMasterBaseLogic newMaster)
|
||||
{
|
||||
this.master = newMaster;
|
||||
this.master.attachBlock(this);
|
||||
}
|
||||
|
||||
protected void detachSelf (boolean chunkUnloading)
|
||||
{
|
||||
if (this.master != null)
|
||||
{
|
||||
this.master.detachBlock(this, chunkUnloading);
|
||||
this.master = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected CoordTuple[] getNeighborCoords ()
|
||||
{
|
||||
return new CoordTuple[] { new CoordTuple(this.xCoord - 1, this.yCoord, this.zCoord), new CoordTuple(this.xCoord, this.yCoord - 1, this.zCoord),
|
||||
new CoordTuple(this.xCoord, this.yCoord, this.zCoord - 1), new CoordTuple(this.xCoord, this.yCoord, this.zCoord + 1), new CoordTuple(this.xCoord, this.yCoord + 1, this.zCoord),
|
||||
new CoordTuple(this.xCoord + 1, this.yCoord, this.zCoord) };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package tconstruct.library.multiblock;
|
||||
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.event.EventPriority;
|
||||
import net.minecraftforge.event.ForgeSubscribe;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
public class MultiblockEventHandler
|
||||
{
|
||||
@ForgeSubscribe(priority = EventPriority.NORMAL)
|
||||
public void onChunkLoad (ChunkEvent.Load loadEvent)
|
||||
{
|
||||
Chunk chunk = loadEvent.getChunk();
|
||||
World world = loadEvent.world;
|
||||
if (world.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MultiblockRegistry.onChunkLoaded(world, ChunkCoordIntPair.chunkXZ2Int(chunk.xPosition, chunk.zPosition));
|
||||
}
|
||||
|
||||
@ForgeSubscribe(priority = EventPriority.NORMAL)
|
||||
public void onChunkUnload (ChunkEvent.Unload unloadEvent)
|
||||
{
|
||||
Chunk chunk = unloadEvent.getChunk();
|
||||
World world = unloadEvent.world;
|
||||
if (world.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MultiblockRegistry.onChunkUnloaded(world, ChunkCoordIntPair.chunkXZ2Int(chunk.xPosition, chunk.zPosition));
|
||||
}
|
||||
|
||||
@ForgeSubscribe(priority = EventPriority.NORMAL)
|
||||
public void onWorldUnload (WorldEvent.Unload unloadWorldEvent)
|
||||
{
|
||||
MultiblockRegistry.onWorldUnloaded(unloadWorldEvent.world);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
package tconstruct.library.multiblock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ChatMessageComponent;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
|
||||
public abstract class MultiblockMasterBaseLogic
|
||||
{
|
||||
protected World worldObj;
|
||||
protected Set<CoordTuple> connectedBlocks;
|
||||
protected CoordTuple referenceCoord;
|
||||
protected CoordTuple minimumCoord;
|
||||
protected CoordTuple maximumCoord;
|
||||
protected boolean forceRecheck;
|
||||
protected boolean chunksHaveLoaded;
|
||||
protected boolean doUpdates;
|
||||
|
||||
protected MultiblockMasterBaseLogic(World world)
|
||||
{
|
||||
worldObj = world;
|
||||
connectedBlocks = new CopyOnWriteArraySet<CoordTuple>();
|
||||
referenceCoord = null;
|
||||
|
||||
minimumCoord = new CoordTuple(0, 0, 0);
|
||||
maximumCoord = new CoordTuple(0, 0, 0);
|
||||
|
||||
forceRecheck = false;
|
||||
chunksHaveLoaded = false;
|
||||
|
||||
doUpdates = true;
|
||||
}
|
||||
|
||||
public void restore (NBTTagCompound savedData)
|
||||
{
|
||||
this.readFromNBT(savedData);
|
||||
MultiblockRegistry.register(this);
|
||||
}
|
||||
|
||||
public boolean hasBlock (CoordTuple blockCoord)
|
||||
{
|
||||
return connectedBlocks.contains(blockCoord);
|
||||
}
|
||||
|
||||
public void attachBlock (IMultiblockMember member)
|
||||
{
|
||||
CoordTuple coords = member.getCoordInWorld();
|
||||
boolean newMultiblock = this.connectedBlocks.isEmpty();
|
||||
|
||||
if (connectedBlocks.contains(coords))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
connectedBlocks.add(coords);
|
||||
member.onAttached(this);
|
||||
this.onBlockAdded(member);
|
||||
this.worldObj.markBlockForUpdate(coords.x, coords.y, coords.z);
|
||||
|
||||
if (newMultiblock)
|
||||
{
|
||||
MultiblockRegistry.register(this);
|
||||
}
|
||||
|
||||
if (this.referenceCoord == null)
|
||||
{
|
||||
referenceCoord = coords;
|
||||
member.becomeMultiblockSaveDelegate();
|
||||
}
|
||||
else if (coords.compareTo(referenceCoord) < 0)
|
||||
{
|
||||
TileEntity te = this.worldObj.getBlockTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z);
|
||||
((IMultiblockMember) te).forfeitMultiblockSaveDelegate();
|
||||
|
||||
referenceCoord = coords;
|
||||
member.becomeMultiblockSaveDelegate();
|
||||
}
|
||||
|
||||
forceRecheck = true;
|
||||
}
|
||||
|
||||
protected abstract void onBlockAdded (IMultiblockMember newMember);
|
||||
|
||||
protected abstract void onBlockRemoved (IMultiblockMember oldMember);
|
||||
|
||||
public void detachBlock (IMultiblockMember member, boolean chunkUnloading)
|
||||
{
|
||||
_detachBlock(member, chunkUnloading);
|
||||
|
||||
if (!chunkUnloading && forceRecheck)
|
||||
{
|
||||
this.revisitBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
private void _detachBlock (IMultiblockMember member, boolean chunkUnloading)
|
||||
{
|
||||
CoordTuple coords = member.getCoordInWorld();
|
||||
if (chunkUnloading)
|
||||
{
|
||||
this.disableUpdates();
|
||||
}
|
||||
|
||||
if (connectedBlocks.contains(coords))
|
||||
{
|
||||
member.onDetached(this);
|
||||
connectedBlocks.remove(coords);
|
||||
this.onBlockRemoved(member);
|
||||
|
||||
if (referenceCoord != null && referenceCoord.equals(coords))
|
||||
{
|
||||
member.forfeitMultiblockSaveDelegate();
|
||||
referenceCoord = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (connectedBlocks.isEmpty())
|
||||
{
|
||||
MultiblockRegistry.unregister(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forceRecheck && chunkUnloading)
|
||||
{
|
||||
this.chunksHaveLoaded = true;
|
||||
}
|
||||
else if (this.chunksHaveLoaded)
|
||||
{
|
||||
this.chunksHaveLoaded = chunkUnloading;
|
||||
}
|
||||
|
||||
forceRecheck = true;
|
||||
|
||||
if (referenceCoord == null)
|
||||
{
|
||||
if (!this.connectedBlocks.isEmpty())
|
||||
{
|
||||
for (CoordTuple tcoord : connectedBlocks)
|
||||
{
|
||||
TileEntity te = this.worldObj.getBlockTileEntity(tcoord.x, tcoord.y, tcoord.z);
|
||||
if (te == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (referenceCoord == null)
|
||||
{
|
||||
referenceCoord = tcoord;
|
||||
}
|
||||
else if (tcoord.compareTo(referenceCoord) < 0)
|
||||
{
|
||||
referenceCoord = tcoord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (referenceCoord != null)
|
||||
{
|
||||
TileEntity te = this.worldObj.getBlockTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z);
|
||||
((IMultiblockMember) te).becomeMultiblockSaveDelegate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void disableUpdates ()
|
||||
{
|
||||
doUpdates = false;
|
||||
}
|
||||
|
||||
private void enableUpdates ()
|
||||
{
|
||||
doUpdates = true;
|
||||
}
|
||||
|
||||
private boolean getUpdateState ()
|
||||
{
|
||||
return doUpdates;
|
||||
}
|
||||
|
||||
public void beginMerging ()
|
||||
{
|
||||
}
|
||||
|
||||
public void merge (MultiblockMasterBaseLogic other)
|
||||
{
|
||||
if (this.referenceCoord.compareTo(other.referenceCoord) >= 0)
|
||||
{
|
||||
throw new IllegalArgumentException("You're doing it wrong");
|
||||
}
|
||||
|
||||
TileEntity te;
|
||||
Set<CoordTuple> acquiredMembers = new CopyOnWriteArraySet<CoordTuple>(other.connectedBlocks);
|
||||
|
||||
other.onMergedIntoOtherMaster(this);
|
||||
|
||||
IMultiblockMember acquiredMember;
|
||||
for (CoordTuple coord : acquiredMembers)
|
||||
{
|
||||
this.connectedBlocks.add(coord);
|
||||
te = this.worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
acquiredMember = (IMultiblockMember) te;
|
||||
acquiredMember.onMasterMerged(this);
|
||||
this.onBlockAdded(acquiredMember);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMergedIntoOtherMaster (MultiblockMasterBaseLogic newMaster)
|
||||
{
|
||||
this.disableUpdates();
|
||||
|
||||
if (referenceCoord != null)
|
||||
{
|
||||
TileEntity te = this.worldObj.getBlockTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z);
|
||||
((IMultiblockMember) te).forfeitMultiblockSaveDelegate();
|
||||
this.referenceCoord = null;
|
||||
}
|
||||
|
||||
this.connectedBlocks.clear();
|
||||
MultiblockRegistry.unregister(this);
|
||||
|
||||
this.onDataMerge(newMaster);
|
||||
}
|
||||
|
||||
protected abstract void onDataMerge (MultiblockMasterBaseLogic newMaster);
|
||||
|
||||
public void endMerging ()
|
||||
{
|
||||
}
|
||||
|
||||
public final void doMultiblockTick ()
|
||||
{
|
||||
if (this.connectedBlocks.isEmpty())
|
||||
{
|
||||
MultiblockRegistry.unregister(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.forceRecheck)
|
||||
{
|
||||
// Recheck structure
|
||||
this.doStructureCheck();
|
||||
this.forceRecheck = false;
|
||||
}
|
||||
|
||||
if (this.doUpdates)
|
||||
{
|
||||
if (doUpdate())
|
||||
{
|
||||
// Force save delegate to update data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override to provide sanity checking on structure
|
||||
public void doStructureCheck ()
|
||||
{
|
||||
}
|
||||
|
||||
// Return true to force chunk saving
|
||||
public boolean doUpdate ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void revisitBlocks ()
|
||||
{
|
||||
TileEntity te;
|
||||
// Ensure that our current reference coords are valid. If not, invalidate it.
|
||||
if (referenceCoord != null && this.worldObj.getBlockTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z) == null)
|
||||
{
|
||||
referenceCoord = null;
|
||||
}
|
||||
|
||||
// Reset visitations and find the minimum coordinate
|
||||
for (CoordTuple coord : connectedBlocks)
|
||||
{
|
||||
|
||||
if (!this.worldObj.getChunkProvider().chunkExists(coord.x >> 4, coord.z >> 4))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
te = this.worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
if (te == null)
|
||||
{
|
||||
continue;
|
||||
} // this happens during chunk unload; ignore it
|
||||
|
||||
((IMultiblockMember) te).setUnivisted();
|
||||
|
||||
if (referenceCoord == null)
|
||||
{
|
||||
referenceCoord = coord;
|
||||
}
|
||||
else if (coord.compareTo(referenceCoord) < 0)
|
||||
{
|
||||
referenceCoord = coord;
|
||||
}
|
||||
}
|
||||
|
||||
if (referenceCoord == null)
|
||||
{
|
||||
// There are no valid parts remaining. This is due to a chunk unload.
|
||||
return;
|
||||
}
|
||||
|
||||
// Now visit all connected parts, breadth-first, starting from reference coord.
|
||||
LinkedList<IMultiblockMember> membersToCheck = new LinkedList<IMultiblockMember>();
|
||||
IMultiblockMember[] nearbyMembers = null;
|
||||
IMultiblockMember member = (IMultiblockMember) this.worldObj.getBlockTileEntity(referenceCoord.x, referenceCoord.y, referenceCoord.z);
|
||||
|
||||
membersToCheck.add(member);
|
||||
while (!membersToCheck.isEmpty())
|
||||
{
|
||||
member = membersToCheck.removeFirst();
|
||||
member.setVisited();
|
||||
|
||||
nearbyMembers = member.getNeighboringMembers();
|
||||
for (IMultiblockMember nearbyMember : nearbyMembers)
|
||||
{
|
||||
// Ignore different machines
|
||||
if (nearbyMember.getMultiblockMaster() != this)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!nearbyMember.isVisited())
|
||||
{
|
||||
nearbyMember.setVisited();
|
||||
membersToCheck.add(nearbyMember);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First, remove any blocks that are still disconnected
|
||||
List<IMultiblockMember> orphans = new LinkedList<IMultiblockMember>();
|
||||
List<CoordTuple> deadBlocks = new ArrayList<CoordTuple>();
|
||||
for (CoordTuple coord : connectedBlocks)
|
||||
{
|
||||
if (!this.worldObj.getChunkProvider().chunkExists(coord.x >> 4, coord.z >> 4))
|
||||
{
|
||||
deadBlocks.add(coord);
|
||||
continue;
|
||||
}
|
||||
member = (IMultiblockMember) this.worldObj.getBlockTileEntity(coord.x, coord.y, coord.z);
|
||||
if (!member.isVisited())
|
||||
{
|
||||
orphans.add(member);
|
||||
}
|
||||
}
|
||||
|
||||
this.connectedBlocks.removeAll(deadBlocks);
|
||||
|
||||
// Remove all orphaned parts. i.e. Actually orphan them
|
||||
for (IMultiblockMember orphan : orphans)
|
||||
{
|
||||
this._detachBlock(orphan, false);
|
||||
}
|
||||
|
||||
// Now go through and start up as many new masters as possible
|
||||
for (IMultiblockMember orphan : orphans)
|
||||
{
|
||||
if (!orphan.isConnected())
|
||||
{
|
||||
orphan.onOrphaned();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CoordTuple getReferenceCoord ()
|
||||
{
|
||||
return referenceCoord;
|
||||
}
|
||||
|
||||
public int getNumConnectedBlocks ()
|
||||
{
|
||||
return connectedBlocks.size();
|
||||
}
|
||||
|
||||
public abstract void writeToNBT (NBTTagCompound data);
|
||||
|
||||
public abstract void readFromNBT (NBTTagCompound data);
|
||||
|
||||
public abstract void formatDescriptionPacket (NBTTagCompound data);
|
||||
|
||||
public abstract void decodeDescriptionPacket (NBTTagCompound data);
|
||||
|
||||
public String debugString ()
|
||||
{
|
||||
return "refCoords: [" + referenceCoord.x + "," + referenceCoord.y + "," + referenceCoord.z + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package tconstruct.library.multiblock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class MultiblockRegistry
|
||||
{
|
||||
private static Set<MultiblockMasterBaseLogic> masters = new CopyOnWriteArraySet<MultiblockMasterBaseLogic>();
|
||||
private static HashMap<Integer, HashMap<Long, List<IMultiblockMember>>> preInitMembers = new HashMap<Integer, HashMap<Long, List<IMultiblockMember>>>();
|
||||
private static HashMap<Integer, HashMap<Long, List<IMultiblockMember>>> preInitMasters = new HashMap<Integer, HashMap<Long, List<IMultiblockMember>>>();
|
||||
private static HashMap<Integer, HashMap<Long, List<IMultiblockMember>>> loadedMembers = new HashMap<Integer, HashMap<Long, List<IMultiblockMember>>>();
|
||||
|
||||
public static void tick (World world)
|
||||
{
|
||||
for (MultiblockMasterBaseLogic logic : masters)
|
||||
{
|
||||
if (logic.worldObj == world && logic.worldObj.isRemote == world.isRemote)
|
||||
{
|
||||
logic.doMultiblockTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void register (MultiblockMasterBaseLogic logic)
|
||||
{
|
||||
masters.add(logic);
|
||||
}
|
||||
|
||||
public static void unregister (MultiblockMasterBaseLogic logic)
|
||||
{
|
||||
masters.remove(logic);
|
||||
}
|
||||
|
||||
public static void onMemberLoad (World world, Long chunkCoord, IMultiblockMember member, boolean master)
|
||||
{
|
||||
HashMap<Integer, HashMap<Long, List<IMultiblockMember>>> pending = preInitMembers;
|
||||
if (master)
|
||||
{
|
||||
pending = preInitMasters;
|
||||
}
|
||||
|
||||
int dimensionId = world.provider.dimensionId;
|
||||
putMemberInList(pending, dimensionId, chunkCoord, member);
|
||||
|
||||
}
|
||||
|
||||
public static void onChunkLoaded (World world, long chunkCoord)
|
||||
{
|
||||
int dimensionId = world.provider.dimensionId;
|
||||
List<IMultiblockMember> pending = getMembersFromListForWorldChunk(preInitMasters, dimensionId, chunkCoord);
|
||||
if (pending != null)
|
||||
{
|
||||
for (IMultiblockMember member : pending)
|
||||
{
|
||||
member.onChunkLoad();
|
||||
}
|
||||
preInitMasters.get(dimensionId).remove(chunkCoord);
|
||||
}
|
||||
|
||||
pending = getMembersFromListForWorldChunk(preInitMembers, dimensionId, chunkCoord);
|
||||
if (pending != null)
|
||||
{
|
||||
for (IMultiblockMember member : pending)
|
||||
{
|
||||
member.onChunkLoad();
|
||||
}
|
||||
preInitMembers.get(dimensionId).remove(chunkCoord);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onChunkUnloaded (World world, long chunkCoord)
|
||||
{
|
||||
int dimensionId = world.provider.dimensionId;
|
||||
List<IMultiblockMember> pending = getMembersFromListForWorldChunk(loadedMembers, dimensionId, chunkCoord);
|
||||
if (pending != null)
|
||||
{
|
||||
for (IMultiblockMember member : pending)
|
||||
{
|
||||
member.onChunkUnloaded();
|
||||
}
|
||||
loadedMembers.get(dimensionId).remove(chunkCoord);
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerMember (World world, long chunkCoord, IMultiblockMember member)
|
||||
{
|
||||
putMemberInList(loadedMembers, world.provider.dimensionId, chunkCoord, member);
|
||||
}
|
||||
|
||||
public static void onWorldUnloaded (World world)
|
||||
{
|
||||
List<MultiblockMasterBaseLogic> mastersToRemove = new ArrayList<MultiblockMasterBaseLogic>();
|
||||
for (MultiblockMasterBaseLogic master : mastersToRemove)
|
||||
{
|
||||
if (master.worldObj.isRemote == world.isRemote && master.worldObj.provider.dimensionId == world.provider.dimensionId)
|
||||
{
|
||||
mastersToRemove.add(master);
|
||||
}
|
||||
}
|
||||
|
||||
masters.removeAll(mastersToRemove);
|
||||
}
|
||||
|
||||
private static List<IMultiblockMember> getMembersFromListForWorldChunk (HashMap<Integer, HashMap<Long, List<IMultiblockMember>>> source, int dimensionId, long chunkCoord)
|
||||
{
|
||||
if (!source.containsKey(dimensionId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!source.get(dimensionId).containsKey(chunkCoord))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return source.get(dimensionId).get(chunkCoord);
|
||||
}
|
||||
|
||||
private static void putMemberInList (HashMap<Integer, HashMap<Long, List<IMultiblockMember>>> destList, int dimensionId, long chunkCoord, IMultiblockMember member)
|
||||
{
|
||||
if (!destList.containsKey(dimensionId))
|
||||
{
|
||||
destList.put(dimensionId, new HashMap<Long, List<IMultiblockMember>>());
|
||||
}
|
||||
|
||||
HashMap<Long, List<IMultiblockMember>> innerMap = destList.get(dimensionId);
|
||||
|
||||
if (!innerMap.containsKey(chunkCoord))
|
||||
{
|
||||
innerMap.put(chunkCoord, new ArrayList<IMultiblockMember>());
|
||||
}
|
||||
|
||||
innerMap.get(chunkCoord).add(member);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package tconstruct.library.multiblock;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import cpw.mods.fml.common.IScheduledTickHandler;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
|
||||
public class MultiblockServerTickHandler implements IScheduledTickHandler
|
||||
{
|
||||
|
||||
@Override
|
||||
public void tickStart (EnumSet<TickType> type, Object... tickData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tickEnd (EnumSet<TickType> type, Object... tickData)
|
||||
{
|
||||
if (type.contains(TickType.WORLD))
|
||||
{
|
||||
World world = (World) tickData[0];
|
||||
MultiblockRegistry.tick(world);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<TickType> ticks ()
|
||||
{
|
||||
return EnumSet.of(TickType.WORLD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel ()
|
||||
{
|
||||
return "TConstruct:MultiblockServerTickHandler";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextTickSpacing ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package tconstruct.library.signal;
|
||||
|
||||
import tconstruct.library.util.CoordTuple;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface ISignalTransceiver
|
||||
{
|
||||
|
||||
void setBusCoords (World world, int xCoord, int yCoord, int zCoord);
|
||||
|
||||
CoordTuple getBusCoords ();
|
||||
|
||||
byte[] getReceivedSignals ();
|
||||
|
||||
void receiveSignalUpdate (byte[] signals);
|
||||
|
||||
int doUnregister (boolean reHoming);
|
||||
|
||||
int getDroppedWire ();
|
||||
|
||||
}
|
||||
@@ -13,6 +13,13 @@ public class CoordTuple implements Comparable
|
||||
z = posZ;
|
||||
}
|
||||
|
||||
public CoordTuple(CoordTuple tuple)
|
||||
{
|
||||
x = tuple.x;
|
||||
y = tuple.y;
|
||||
z = tuple.z;
|
||||
}
|
||||
|
||||
public boolean equalCoords (int posX, int posY, int posZ)
|
||||
{
|
||||
if (this.x == posX && this.y == posY && this.z == posZ)
|
||||
@@ -57,11 +64,34 @@ public class CoordTuple implements Comparable
|
||||
{
|
||||
if (o == null)
|
||||
throw new NullPointerException("Object cannot be null");
|
||||
|
||||
CoordTuple coord = (CoordTuple) o;
|
||||
if (coord.equals(this))
|
||||
return 0;
|
||||
|
||||
return (x - coord.x) + (y - coord.y) + (z - coord.z);
|
||||
|
||||
CoordTuple coord = (CoordTuple) o;
|
||||
|
||||
if (x < coord.x)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (x > coord.x)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (y < coord.y)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (y > coord.y)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (z < coord.z)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (z > coord.z)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package tconstruct.library.util;
|
||||
|
||||
public class CoordTuplePair
|
||||
{
|
||||
public CoordTuple a;
|
||||
public CoordTuple b;
|
||||
|
||||
public CoordTuplePair (CoordTuple a, CoordTuple b)
|
||||
{
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public CoordTuplePair (int aX, int aY, int aZ, int bX, int bY, int bZ)
|
||||
{
|
||||
this.a = new CoordTuple(aX, aY, aZ);
|
||||
this.b = new CoordTuple(bX, bY, bZ);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,6 @@ public class PHConstruct
|
||||
keepHunger = config.get("Difficulty Changes", "Keep hunger on death", true).getBoolean(true);
|
||||
keepLevels = config.get("Difficulty Changes", "Keep levels on death", true).getBoolean(true);
|
||||
beginnerBook = config.get("Difficulty Changes", "Spawn beginner book", true).getBoolean(true);
|
||||
|
||||
superfunWorld = config.get("Superfun", "All the world is Superfun", false).getBoolean(false);
|
||||
|
||||
enableTWood = config.get("Difficulty Changes", "Enable mod wooden tools", true).getBoolean(true);
|
||||
@@ -179,6 +178,8 @@ public class PHConstruct
|
||||
slimeExplosive = config.getBlock("SDX", 3247).getInt(3247);
|
||||
castingChannel = config.getBlock("Casting Channel", 3249).getInt(3249);
|
||||
woodenRail = config.getBlock("Wooden Rail", 3250).getInt(3250);
|
||||
signalBus = config.getBlock("Signal Bus", 3251).getInt(3251);
|
||||
signalTerminal = config.getBlock("Signal Terminal", 3252).getInt(3252);
|
||||
|
||||
manual = config.getItem("Patterns and Misc", "Tinker's Manual", 14018).getInt(14018);
|
||||
blankPattern = config.getItem("Patterns and Misc", "Blank Patterns", 14019).getInt(14019);
|
||||
@@ -263,6 +264,9 @@ public class PHConstruct
|
||||
essenceCrystal = config.getItem("Patterns and Misc", "Essence Crystal", 14114).getInt(14114);
|
||||
jerky = config.getItem("Patterns and Misc", "Jerky", 14115).getInt(14115);
|
||||
|
||||
spoolWire = config.getItem("Logic", "SpoolWire", 14120).getInt(14120);
|
||||
lengthWire = config.getItem("Logic", "LengthWire", 14121).getInt(14121);
|
||||
|
||||
boolean ic2 = true;
|
||||
boolean xycraft = true;
|
||||
try
|
||||
@@ -410,6 +414,9 @@ public class PHConstruct
|
||||
public static int dryingRack;
|
||||
|
||||
public static int woodenRail;
|
||||
|
||||
public static int signalBus;
|
||||
public static int signalTerminal;
|
||||
|
||||
//Crops
|
||||
public static int oreBerry;
|
||||
@@ -578,6 +585,9 @@ public class PHConstruct
|
||||
public static int knapsack;
|
||||
|
||||
public static int heartCanister;
|
||||
|
||||
public static int spoolWire;
|
||||
public static int lengthWire;
|
||||
|
||||
//Ore values
|
||||
public static boolean generateCopper;
|
||||
|
||||
Reference in new issue
Block a user