Levitator now functions properly

This commit is contained in:
Calclavia 2014-02-21 17:37:15 +08:00
parent 0f15e6d1fa
commit 85a074e1a9
8 changed files with 277 additions and 1048 deletions

View file

@ -4,25 +4,21 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.AdvancedModelLoader;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.client.model.obj.WavefrontObject;
import org.lwjgl.opengl.GL11;
import resonantinduction.core.Reference;
import resonantinduction.core.render.RenderItemOverlayTile;
import resonantinduction.electrical.levitator.TileLevitator;
import universalelectricity.api.CompatibilityModule;
import universalelectricity.api.energy.UnitDisplay;
import universalelectricity.api.energy.UnitDisplay.Unit;
import universalelectricity.api.vector.Vector3;
import calclavia.lib.render.RenderUtility;
import calclavia.lib.render.item.ISimpleItemRenderer;
import cpw.mods.fml.client.FMLClientHandler;
/**
* Renderer for electric item charger

View file

@ -1,129 +0,0 @@
package resonantinduction.electrical.levitator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.core.Reference;
import resonantinduction.core.render.RIBlockRenderingHandler;
import universalelectricity.api.UniversalElectricity;
import universalelectricity.api.vector.VectorWorld;
import calclavia.components.tool.ToolModeLink;
import calclavia.lib.prefab.block.BlockRotatable;
import calclavia.lib.prefab.block.ILinkable;
import calclavia.lib.utility.WrenchUtility;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockLevitator extends BlockRotatable
{
public BlockLevitator(int id)
{
super(id, UniversalElectricity.machine);
setTextureName(Reference.PREFIX + "material_steel");
rotationMask = Byte.parseByte("111111", 2);
}
@Override
public boolean onMachineActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9)
{
TileLevitator levitator = (TileLevitator) world.getBlockTileEntity(x, y, z);
if (entityPlayer.getCurrentEquippedItem() != null)
{
if (entityPlayer.getCurrentEquippedItem().itemID == Item.dyePowder.itemID)
{
levitator.setDye(entityPlayer.getCurrentEquippedItem().getItemDamage());
if (!entityPlayer.capabilities.isCreativeMode)
{
entityPlayer.inventory.decrStackSize(entityPlayer.inventory.currentItem, 1);
}
return true;
}
}
levitator.suck = !levitator.suck;
levitator.updatePath();
return false;
}
@Override
public boolean onUseWrench(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ)
{
ItemStack itemStack = entityPlayer.getCurrentEquippedItem();
if (WrenchUtility.isWrench(itemStack))
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof ILinkable)
{
ILinkable linkable = (ILinkable) tile;
if (linkable.onLink(entityPlayer, ToolModeLink.getLink(itemStack)))
{
ToolModeLink.clearLink(itemStack);
}
else
{
ToolModeLink.setLink(itemStack, new VectorWorld(world, x, y, z));
}
return true;
}
}
return false;
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int blockID)
{
TileLevitator tileContractor = (TileLevitator) world.getBlockTileEntity(x, y, z);
if (!world.isRemote && !tileContractor.isLatched())
{
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tileEntity = world.getBlockTileEntity(x + side.offsetX, y + side.offsetY, z + side.offsetZ);
if (tileEntity instanceof IInventory)
{
tileContractor.setDirection(side.getOpposite());
return;
}
}
}
}
@SideOnly(Side.CLIENT)
@Override
public int getRenderType()
{
return RIBlockRenderingHandler.INSTANCE.getRenderId();
}
@Override
public TileEntity createNewTileEntity(World world)
{
return new TileLevitator();
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
}

View file

@ -1,45 +0,0 @@
package resonantinduction.electrical.levitator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
public class ItemBlockContractor extends ItemBlock
{
public ItemBlockContractor(int id)
{
super(id);
}
@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)
{
boolean place = super.placeBlockAt(stack, player, world, x, y, z, side, hitX, hitY, hitZ, metadata);
if (place)
{
TileLevitator tileContractor = (TileLevitator) world.getBlockTileEntity(x, y, z);
tileContractor.setDirection(ForgeDirection.getOrientation(side));
if (!tileContractor.isLatched())
{
for (ForgeDirection side1 : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tileEntity = world.getBlockTileEntity(x + side1.offsetX, y + side1.offsetY, z + side1.offsetZ);
if (tileEntity instanceof IInventory)
{
tileContractor.setDirection(side1.getOpposite());
break;
}
}
}
}
return place;
}
}

View file

@ -1,22 +1,21 @@
package resonantinduction.electrical.levitator;
import java.util.ArrayList;
import java.util.HashSet;
import java.awt.geom.CubicCurve2D;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFluid;
import net.minecraft.block.BlockLadder;
import net.minecraft.block.BlockSnow;
import net.minecraft.block.BlockVine;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MovingObjectPosition;
@ -24,29 +23,24 @@ import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.IFluidBlock;
import resonantinduction.core.MultipartUtility;
import resonantinduction.core.ResonantInduction;
import resonantinduction.core.Settings;
import resonantinduction.core.prefab.part.PartFace;
import resonantinduction.electrical.Electrical;
import resonantinduction.electrical.tesla.TileTesla;
import resonantinduction.electrical.transformer.RenderTransformer;
import universalelectricity.api.vector.Vector3;
import universalelectricity.api.vector.VectorWorld;
import calclavia.components.tool.ToolModeLink;
import calclavia.lib.prefab.block.ILinkable;
import calclavia.lib.render.EnumColor;
import calclavia.lib.utility.WrenchUtility;
import calclavia.lib.utility.inventory.InventoryUtility;
import codechicken.lib.data.MCDataInput;
import codechicken.lib.data.MCDataOutput;
import codechicken.lib.vec.Cuboid6;
import codechicken.multipart.TMultiPart;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PartLevitator extends PartFace implements ILinkable
public class PartLevitator extends PartFace
{
private int pushDelay;
@ -56,16 +50,14 @@ public class PartLevitator extends PartFace implements ILinkable
/**
* true = suck, false = push
*/
public boolean suck = true;
public boolean input = true;
/**
* Pathfinding
*/
private ThreadEMPathfinding thread;
private PathfinderEMContractor pathfinder;
private Set<EntityItem> pathfindingTrackers = new HashSet<EntityItem>();
// TODO: WeakReference
private PartLevitator linked;
private ThreadLevitatorPathfinding thread;
private PathfinderLevitator pathfinder;
private WeakReference<PartLevitator> linked;
private int lastCalcTime = 0;
/** Color of beam */
@ -74,28 +66,32 @@ public class PartLevitator extends PartFace implements ILinkable
/**
* Linking
*/
private byte linkSide;
private Vector3 tempLinkVector;
private byte saveLinkSide;
private VectorWorld saveLinkVector;
/**
* Client Side Only
*/
public float renderRotation = 0;
private int ticks;
@Override
public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack itemStack)
{
if (WrenchUtility.isWrench(itemStack))
{
if (onLink(player, ToolModeLink.getLink(itemStack)))
if (tryLink(ToolModeLink.getLink(itemStack), ToolModeLink.getSide(itemStack)))
{
if (world().isRemote)
player.addChatMessage("Successfully linked devices.");
ToolModeLink.clearLink(itemStack);
}
else
{
if (world().isRemote)
player.addChatMessage("Marked link for device.");
ToolModeLink.setLink(itemStack, new VectorWorld(world(), x(), y(), z()));
ToolModeLink.setSide(itemStack, (byte) placementSide.ordinal());
}
return true;
@ -116,61 +112,99 @@ public class PartLevitator extends PartFace implements ILinkable
}
}
suck = !suck;
if (player.isSneaking())
input = !input;
updateBounds();
updatePath();
return true;
}
@Override
protected ItemStack getItem()
/**
* Link methods
*/
public boolean tryLink(VectorWorld linkVector, byte side)
{
return new ItemStack(Electrical.itemLevitator);
}
@Override
public String getType()
{
return "resonant_induction_levitator";
}
public void initiate()
{
updateBounds();
}
@Override
public void update()
{
super.update();
if (ticks++ == 0)
if (linkVector != null)
{
initiate();
}
pushDelay = Math.max(0, pushDelay - 1);
if (tempLinkVector != null)
{
TMultiPart part = MultipartUtility.getMultipart(world(), tempLinkVector, linkSide);
TMultiPart part = MultipartUtility.getMultipart(world(), linkVector, side);
if (part instanceof PartLevitator)
{
setLink((PartLevitator) part, true);
}
tempLinkVector = null;
return true;
}
return false;
}
public PartLevitator getLink()
{
return linked != null ? linked.get() : null;
}
@Override
public void onEntityCollision(Entity entity)
{
/**
* Attempt to pull items in.
*/
if (!world().isRemote && input && canFunction() && entity instanceof EntityItem)
{
EntityItem item = (EntityItem) entity;
IInventory inventory = (IInventory) getLatched();
ItemStack remains = InventoryUtility.putStackInInventory(inventory, item.getEntityItem(), placementSide.getOpposite().getOpposite().ordinal(), false);
if (remains == null)
{
item.setDead();
}
else
{
item.setEntityItemStack(remains);
}
// TODO: Add redstone pulse and reaction?
}
}
@Override
public void update()
{
if (ticks % 60 == 0)
updateBounds();
super.update();
pushDelay = Math.max(0, pushDelay - 1);
/**
* Try to use temp link vectors from save/loads to link.
*/
if (saveLinkVector != null)
{
tryLink(saveLinkVector, saveLinkSide);
saveLinkVector = null;
}
if (canFunction())
{
TileEntity inventoryTile = getLatched();
IInventory inventory = (IInventory) inventoryTile;
IInventory inventory = (IInventory) getLatched();
if (!suck)
/**
* Place items or take items from the inventory into the world.
*/
if (!input)
{
renderRotation = Math.max(0, renderRotation - 0.8f);
renderRotation = Math.min(20, renderRotation + 0.8f);
/**
* Attempt to push items out.
*/
if (pushDelay == 0)
{
ItemStack retrieved = InventoryUtility.takeTopItemFromInventory(inventory, placementSide.getOpposite().getOpposite().ordinal());
@ -188,138 +222,120 @@ public class PartLevitator extends PartFace implements ILinkable
}
}
}
else if (suck)
else if (input)
{
renderRotation = Math.min(20, renderRotation + 0.8f);
if (suckBounds != null)
renderRotation = Math.max(0, renderRotation - 0.8f);
}
final int renderPeriod = 1;
final boolean renderBeam = ticks % renderPeriod == 0 && hasLink() && getLink().input != input;
if (!input)
{
if (hasLink())
{
if (!world().isRemote)
if (getLink().input)
{
for (EntityItem item : (List<EntityItem>) world().getEntitiesWithinAABB(EntityItem.class, suckBounds))
/**
* Linked usage.
*/
if (thread != null)
{
ItemStack remains = InventoryUtility.putStackInInventory(inventory, item.getEntityItem(), placementSide.getOpposite().getOpposite().ordinal(), false);
PathfinderLevitator newPath = thread.getPath();
if (remains == null)
if (newPath != null)
{
item.setDead();
pathfinder = newPath;
pathfinder.results.add(getPosition());
thread = null;
}
else
{
item.setEntityItemStack(remains);
}
// TODO: Add redstone pulse?
}
}
}
}
if (thread != null)
{
PathfinderEMContractor newPath = thread.getPath();
if (newPath != null)
{
pathfinder = newPath;
thread = null;
}
}
final int renderFrequency = 1;
final boolean renderBeam = ticks % renderFrequency == 0 && hasLink() && linked.suck != suck;
if (hasLink())
{
if (!suck)
{
if (renderBeam)
Electrical.proxy.renderElectricShock(world(), getPosition().translate(0.5), getPosition().translate(new Vector3(placementSide.getOpposite())).translate(0.5), EnumColor.DYES[dyeID].toColor(), false);
// Push entity along path.
if (pathfinder != null)
{
List<Vector3> results = pathfinder.results;
for (int i = 0; i < results.size(); i++)
// Push entity along path.
if (pathfinder != null)
{
Vector3 result = results.get(i).clone();
List<Vector3> results = pathfinder.results;
if (PartLevitator.canBePath(world(), result))
/**
* Draw default beams.
*/
if (renderBeam)
{
if (i - 1 >= 0)
Electrical.proxy.renderElectricShock(world(), getBeamSpawnPosition(), getPosition().translate(0.5), EnumColor.DYES[dyeID].toColor(), world().rand.nextFloat() > 0.9);
Electrical.proxy.renderElectricShock(world(), getLink().getPosition().translate(0.5), getLink().getBeamSpawnPosition(), EnumColor.DYES[dyeID].toColor(), world().rand.nextFloat() > 0.9);
}
for (int i = 0; i < results.size(); i++)
{
Vector3 result = results.get(i).clone();
if (canBeMovePath(world(), result))
{
Vector3 prevResult = results.get(i - 1).clone();
Vector3 difference = prevResult.clone().difference(result);
final ForgeDirection direction = difference.toForgeDirection();
if (renderBeam)
if (i - 1 >= 0)
{
Electrical.proxy.renderElectricShock(world(), prevResult.clone().translate(0.5), result.clone().translate(0.5), EnumColor.DYES[dyeID].toColor(), false);
Vector3 prevResult = results.get(i - 1).clone();
Vector3 difference = prevResult.clone().difference(result);
final ForgeDirection direction = difference.toForgeDirection();
if (renderBeam)
Electrical.proxy.renderElectricShock(world(), prevResult.clone().translate(0.5), result.clone().translate(0.5), EnumColor.DYES[dyeID].toColor(), world().rand.nextFloat() > 0.9);
AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(result.x, result.y, result.z, result.x + 1, result.y + 1, result.z + 1);
List<EntityItem> entities = world().getEntitiesWithinAABB(EntityItem.class, bounds);
for (EntityItem entityItem : entities)
{
moveEntity(entityItem, direction, result);
}
}
AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(result.x, result.y, result.z, result.x + 1, result.y + 1, result.z + 1);
List<EntityItem> entities = world().getEntitiesWithinAABB(EntityItem.class, bounds);
for (EntityItem entityItem : entities)
{
moveEntity(entityItem, direction, result);
}
}
}
else
{
updatePath();
break;
else
{
updatePath();
break;
}
}
}
}
else
{
updatePath();
}
}
else
{
if (renderBeam)
{
Electrical.proxy.renderElectricShock(world(), getPosition().translate(0.5), getPosition().translate(new Vector3(placementSide.getOpposite())).translate(0.5), EnumColor.DYES[dyeID].toColor(), false);
}
pathfinder = null;
Vector3 searchVec = getPosition().translate(placementSide.getOpposite());
AxisAlignedBB searchBounds = AxisAlignedBB.getAABBPool().getAABB(searchVec.x, searchVec.y, searchVec.z, searchVec.x + 1, searchVec.y + 1, searchVec.z + 1);
if (searchBounds != null)
{
for (EntityItem entityItem : (List<EntityItem>) world().getEntitiesWithinAABB(EntityItem.class, searchBounds))
else
{
moveEntity(entityItem, placementSide.getOpposite(), getPosition());
updatePath();
}
}
}
}
else if (!hasLink())
{
for (EntityItem entityItem : (List<EntityItem>) world().getEntitiesWithinAABB(EntityItem.class, operationBounds))
else if (operationBounds != null)
{
if (ticks % renderFrequency == 0)
Electrical.proxy.renderElectricShock(world(), getPosition().translate(0.5), new Vector3(entityItem), EnumColor.DYES[dyeID].toColor(), false);
moveEntity(entityItem, placementSide.getOpposite(), getPosition());
}
}
/**
* Non-linked usage.
*/
for (EntityItem entityItem : (List<EntityItem>) world().getEntitiesWithinAABB(EntityItem.class, operationBounds))
{
moveEntity(entityItem, placementSide.getOpposite(), getPosition());
}
if (linked != null)
{
linked = null;
if (ticks % renderPeriod == 0)
Electrical.proxy.renderElectricShock(world(), getBeamSpawnPosition(), new Vector3(operationBounds.maxX - 0.5 - placementSide.offsetX / 3f, operationBounds.maxY - 0.5 - placementSide.offsetY / 3f, operationBounds.maxZ - 0.5 - placementSide.offsetZ / 3f), EnumColor.DYES[dyeID].toColor(), world().rand.nextFloat() > 0.9);
}
}
lastCalcTime--;
}
}
public boolean canBeMovePath(World world, Vector3 position)
{
TMultiPart partSelf = MultipartUtility.getMultipart(new VectorWorld(world, position), placementSide.ordinal());
if (partSelf == this)
return true;
TMultiPart partLink = MultipartUtility.getMultipart(new VectorWorld(world, position), getLink().placementSide.ordinal());
if (partLink == getLink())
return true;
return canBePath(world, position);
}
public static boolean canBePath(World world, Vector3 position)
{
Block block = Block.blocksList[position.getBlockID(world)];
@ -328,7 +344,7 @@ public class PartLevitator extends PartFace implements ILinkable
private boolean hasLink()
{
return linked != null && linked.linked == this;
return getLink() != null && getLink().getLink() == this;
}
private void moveEntity(EntityItem entityItem, ForgeDirection direction, Vector3 lockVector)
@ -341,7 +357,7 @@ public class PartLevitator extends PartFace implements ILinkable
entityItem.motionX = 0;
entityItem.motionZ = 0;
if (!suck)
if (!input)
{
entityItem.motionY = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionY - Settings.LEVITATOR_ACCELERATION);
}
@ -358,7 +374,7 @@ public class PartLevitator extends PartFace implements ILinkable
entityItem.motionX = 0;
entityItem.motionZ = 0;
if (!suck)
if (!input)
{
entityItem.motionY = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionY + .04 + Settings.LEVITATOR_ACCELERATION);
}
@ -375,7 +391,7 @@ public class PartLevitator extends PartFace implements ILinkable
entityItem.motionX = 0;
entityItem.motionY = 0;
if (!suck)
if (!input)
{
entityItem.motionZ = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionZ - Settings.LEVITATOR_ACCELERATION);
}
@ -392,7 +408,7 @@ public class PartLevitator extends PartFace implements ILinkable
entityItem.motionX = 0;
entityItem.motionY = 0;
if (!suck)
if (!input)
{
entityItem.motionZ = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionZ + Settings.LEVITATOR_ACCELERATION);
}
@ -409,7 +425,7 @@ public class PartLevitator extends PartFace implements ILinkable
entityItem.motionY = 0;
entityItem.motionZ = 0;
if (!suck)
if (!input)
{
entityItem.motionX = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionX - Settings.LEVITATOR_ACCELERATION);
}
@ -425,7 +441,7 @@ public class PartLevitator extends PartFace implements ILinkable
entityItem.motionY = 0;
entityItem.motionZ = 0;
if (!suck)
if (!input)
{
entityItem.motionX = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionX + Settings.LEVITATOR_ACCELERATION);
}
@ -447,62 +463,52 @@ public class PartLevitator extends PartFace implements ILinkable
private EntityItem getItemWithPosition(ItemStack toSend)
{
EntityItem item = null;
switch (placementSide.getOpposite())
{
case DOWN:
item = new EntityItem(world(), x() + 0.5, y() - 0.2, z() + 0.5, toSend);
break;
case UP:
item = new EntityItem(world(), x() + 0.5, y() + 1.2, z() + 0.5, toSend);
break;
case NORTH:
item = new EntityItem(world(), x() + 0.5, y() + 0.5, z() - 0.2, toSend);
break;
case SOUTH:
item = new EntityItem(world(), x() + 0.5, y() + 0.5, z() + 1.2, toSend);
break;
case WEST:
item = new EntityItem(world(), x() - 0.2, y() + 0.5, z() + 0.5, toSend);
break;
case EAST:
item = new EntityItem(world(), x() + 1.2, y() + 0.5, z() + 0.5, toSend);
break;
default:
break;
}
EntityItem item = new EntityItem(world(), x() + 0.5, y() + 0.5, z() + 0.5, toSend);
item.motionX = 0;
item.motionY = 0;
item.motionZ = 0;
return item;
}
public void updateBounds()
{
ForgeDirection dir = placementSide;
suckBounds = operationBounds = null;
ForgeDirection dir = placementSide.getOpposite();
MovingObjectPosition mop = world().clip(getPosition().translate(dir).toVec3(), getPosition().translate(dir, Settings.LEVITATOR_MAX_REACH).toVec3());
int reach = Settings.LEVITATOR_MAX_REACH;
if (mop != null)
{
reach = (int) Math.min(getPosition().distance(new Vector3(mop.hitVec)), reach);
}
if (MultipartUtility.getMultipart(world(), mop.blockX, mop.blockY, mop.blockZ, placementSide.getOpposite().ordinal()) instanceof PartLevitator)
{
reach = (int) Math.min(getPosition().distance(new Vector3(mop.hitVec)), reach);
if (dir.offsetX + dir.offsetY + dir.offsetZ < 0)
{
operationBounds = AxisAlignedBB.getBoundingBox(x() + dir.offsetX * reach, y() + dir.offsetY * reach, z() + dir.offsetZ * reach, x() + 1, y() + 1, z() + 1);
suckBounds = AxisAlignedBB.getBoundingBox(x() + dir.offsetX, y() + dir.offsetY, z() + dir.offsetZ, x() + 1, y() + 1, z() + 1);
}
else
{
operationBounds = AxisAlignedBB.getBoundingBox(x(), y(), z(), x() + 1 + dir.offsetX * reach, y() + 1 + dir.offsetY * reach, z() + 1 + dir.offsetZ * reach);
suckBounds = AxisAlignedBB.getBoundingBox(x(), y(), z(), x() + 1 + dir.offsetX, y() + 1 + dir.offsetY, z() + 1 + dir.offsetZ);
if (dir.offsetX + dir.offsetY + dir.offsetZ < 0)
{
operationBounds = AxisAlignedBB.getBoundingBox(x() + dir.offsetX * reach, y() + dir.offsetY * reach, z() + dir.offsetZ * reach, x() + 1, y() + 1, z() + 1);
suckBounds = AxisAlignedBB.getBoundingBox(x() + dir.offsetX, y() + dir.offsetY, z() + dir.offsetZ, x() + 1, y() + 1, z() + 1);
}
else
{
operationBounds = AxisAlignedBB.getBoundingBox(x(), y(), z(), x() + 1 + dir.offsetX * reach, y() + 1 + dir.offsetY * reach, z() + 1 + dir.offsetZ * reach);
suckBounds = AxisAlignedBB.getBoundingBox(x(), y(), z(), x() + 1 + dir.offsetX, y() + 1 + dir.offsetY, z() + 1 + dir.offsetZ);
}
}
}
}
@Override
public void onNeighborChanged()
{
super.onNeighborChanged();
updateBounds();
}
public boolean canFunction()
{
return isLatched() && !world().isBlockIndirectlyGettingPowered(x(), y(), z());
}
public boolean isLatched()
@ -528,12 +534,13 @@ public class PartLevitator extends PartFace implements ILinkable
public void readDesc(MCDataInput packet)
{
super.readDesc(packet);
suck = packet.readBoolean();
input = packet.readBoolean();
dyeID = packet.readByte();
if (packet.readBoolean())
{
tempLinkVector = new Vector3(packet.readInt(), packet.readInt(), packet.readInt());
saveLinkVector = new VectorWorld(packet.readNBTTagCompound());
saveLinkSide = packet.readByte();
}
}
@ -541,15 +548,16 @@ public class PartLevitator extends PartFace implements ILinkable
public void writeDesc(MCDataOutput packet)
{
super.writeDesc(packet);
packet.writeBoolean(suck);
packet.writeBoolean(input);
packet.writeByte(dyeID);
if (linked != null)
if (getLink() != null)
{
packet.writeBoolean(true);
packet.writeInt(linked.x());
packet.writeInt(linked.y());
packet.writeInt(linked.z());
NBTTagCompound nbt = new NBTTagCompound();
new VectorWorld(getLink().world(), getLink().x(), getLink().y(), getLink().z()).writeToNBT(nbt);
packet.writeNBTTagCompound(nbt);
packet.writeByte(getLink().placementSide.ordinal());
}
else
{
@ -558,22 +566,18 @@ public class PartLevitator extends PartFace implements ILinkable
}
public boolean canFunction()
{
return isLatched() && !world().isBlockIndirectlyGettingPowered(x(), y(), z());
}
@Override
public void load(NBTTagCompound nbt)
{
super.load(nbt);
this.suck = nbt.getBoolean("suck");
this.input = nbt.getBoolean("suck");
this.dyeID = nbt.getInteger("dyeID");
if (nbt.hasKey("link"))
{
tempLinkVector = new Vector3(nbt.getCompoundTag("link"));
saveLinkVector = new VectorWorld(nbt.getCompoundTag("link"));
saveLinkSide = nbt.getByte("linkSide");
}
}
@ -582,30 +586,31 @@ public class PartLevitator extends PartFace implements ILinkable
{
super.save(nbt);
nbt.setBoolean("suck", suck);
nbt.setBoolean("suck", input);
nbt.setInteger("dyeID", dyeID);
if (linked != null)
if (getLink() != null && getLink().world() != null)
{
nbt.setCompoundTag("link", new Vector3(linked.x(), linked.y(), linked.z()).writeToNBT(new NBTTagCompound()));
nbt.setCompoundTag("link", new VectorWorld(getLink().world(), getLink().x(), getLink().y(), getLink().z()).writeToNBT(new NBTTagCompound()));
nbt.setByte("linkSide", (byte) getLink().placementSide.ordinal());
}
}
/**
* Link between two TileEntities, do pathfinding operation.
*/
public void setLink(PartLevitator tileEntity, boolean setOpponent)
public void setLink(PartLevitator levitator, boolean setOpponent)
{
if (linked != null && setOpponent)
if (getLink() != null && setOpponent)
{
linked.setLink(null, false);
getLink().setLink(null, false);
}
linked = tileEntity;
linked = new WeakReference(levitator);
if (setOpponent)
{
linked.setLink(this, false);
getLink().setLink(this, false);
}
updatePath();
@ -613,18 +618,18 @@ public class PartLevitator extends PartFace implements ILinkable
public void updatePath()
{
if (thread == null && linked != null && lastCalcTime <= 0)
if (thread == null && getLink() != null && lastCalcTime <= 0)
{
pathfinder = null;
Vector3 start = getPosition().translate(placementSide.getOpposite());
Vector3 target = new Vector3(linked.x(), linked.y(), linked.z()).translate(linked.placementSide.getOpposite());
Vector3 start = getPosition();
Vector3 target = new Vector3(getLink().x(), getLink().y(), getLink().z());
if (start.distance(target) < Settings.MAX_CONTRACTOR_DISTANCE)
{
if (PartLevitator.canBePath(world(), start) && PartLevitator.canBePath(world(), target))
if (canBeMovePath(world(), start) && canBeMovePath(world(), target))
{
thread = new ThreadEMPathfinding(new PathfinderEMContractor(world(), target), start);
thread = new ThreadLevitatorPathfinding(new PathfinderLevitator(world(), target), start);
thread.start();
lastCalcTime = 40;
}
@ -638,18 +643,28 @@ public class PartLevitator extends PartFace implements ILinkable
world().markBlockForUpdate(x(), y(), z());
}
@Override
public boolean onLink(EntityPlayer player, VectorWorld vector)
{
tempLinkVector = vector;
return false;
}
public Vector3 getPosition()
{
return new Vector3(x(), y(), z());
}
public Vector3 getBeamSpawnPosition()
{
return new Vector3(x() + 0.5 + placementSide.offsetX / 3f, y() + 0.5 + placementSide.offsetY / 3f, z() + 0.5 + placementSide.offsetZ / 3f);
}
@Override
protected ItemStack getItem()
{
return new ItemStack(Electrical.itemLevitator);
}
@Override
public String getType()
{
return "resonant_induction_levitator";
}
@Override
@SideOnly(Side.CLIENT)
public void renderDynamic(codechicken.lib.vec.Vector3 pos, float frame, int pass)

View file

@ -1,6 +1,3 @@
/**
*
*/
package resonantinduction.electrical.levitator;
import java.util.HashSet;
@ -19,13 +16,12 @@ import calclavia.lib.path.PathfinderAStar;
* @author Calclavia
*
*/
public class PathfinderEMContractor extends PathfinderAStar
public class PathfinderLevitator extends PathfinderAStar
{
private World world;
private double maxSearchDistance;
public PathfinderEMContractor(final World world, final Vector3 goal)
public PathfinderLevitator(final World world, final Vector3 goal)
{
super(new IPathCallBack()
{
@ -38,7 +34,7 @@ public class PathfinderEMContractor extends PathfinderAStar
{
Vector3 neighbor = currentNode.clone().translate(ForgeDirection.getOrientation(i));
if (TileLevitator.canBePath(world, neighbor))
if (PartLevitator.canBePath(world, neighbor) || neighbor.equals(goal))
{
neighbors.add(neighbor);
}
@ -67,7 +63,7 @@ public class PathfinderEMContractor extends PathfinderAStar
ForgeDirection direction = ForgeDirection.getOrientation(i);
Vector3 neighbor = this.goal.clone().translate(new Vector3(direction.offsetX, direction.offsetY, direction.offsetZ));
if (!TileLevitator.canBePath(this.world, neighbor))
if (!PartLevitator.canBePath(this.world, neighbor))
{
blockCount++;
}

View file

@ -9,13 +9,13 @@ import universalelectricity.api.vector.Vector3;
* @author Calclavia
*
*/
public class ThreadEMPathfinding extends Thread
public class ThreadLevitatorPathfinding extends Thread
{
private boolean isCompleted = false;
private PathfinderEMContractor pathfinder;
private PathfinderLevitator pathfinder;
private Vector3 start;
public ThreadEMPathfinding(PathfinderEMContractor pathfinder, Vector3 start)
public ThreadLevitatorPathfinding(PathfinderLevitator pathfinder, Vector3 start)
{
this.pathfinder = pathfinder;
this.start = start;
@ -29,7 +29,7 @@ public class ThreadEMPathfinding extends Thread
this.isCompleted = true;
}
public PathfinderEMContractor getPath()
public PathfinderLevitator getPath()
{
if (this.isCompleted)
{

View file

@ -1,619 +0,0 @@
package resonantinduction.electrical.levitator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFluid;
import net.minecraft.block.BlockLadder;
import net.minecraft.block.BlockSnow;
import net.minecraft.block.BlockVine;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.fluids.IFluidBlock;
import resonantinduction.core.ResonantInduction;
import resonantinduction.core.Settings;
import resonantinduction.electrical.Electrical;
import resonantinduction.electrical.tesla.TileTesla;
import universalelectricity.api.vector.Vector3;
import universalelectricity.api.vector.VectorWorld;
import calclavia.lib.network.IPacketReceiver;
import calclavia.lib.network.IPacketSender;
import calclavia.lib.prefab.block.ILinkable;
import calclavia.lib.prefab.tile.TileAdvanced;
import calclavia.lib.render.EnumColor;
import calclavia.lib.utility.inventory.InventoryUtility;
import com.google.common.io.ByteArrayDataInput;
/**
*
* @author Calclavia
*
*/
@Deprecated
public class TileLevitator extends TileAdvanced implements IPacketReceiver, IPacketSender, ILinkable
{
private int pushDelay;
private AxisAlignedBB operationBounds;
private AxisAlignedBB suckBounds;
/**
* true = suck, false = push
*/
public boolean suck = true;
/**
* Pathfinding
*/
private ThreadEMPathfinding thread;
private PathfinderEMContractor pathfinder;
private Set<EntityItem> pathfindingTrackers = new HashSet<EntityItem>();
private TileLevitator linked;
private int lastCalcTime = 0;
/** Color of beam */
private int dyeID = TileTesla.DEFAULT_COLOR;
private Vector3 tempLinkVector;
/**
* Client Side Only
*/
public float renderRotation = 0;
@Override
public void initiate()
{
super.initiate();
updateBounds();
}
@Override
public void updateEntity()
{
super.updateEntity();
pushDelay = Math.max(0, pushDelay - 1);
if (tempLinkVector != null)
{
if (tempLinkVector.getTileEntity(worldObj) instanceof TileLevitator)
{
setLink((TileLevitator) tempLinkVector.getTileEntity(worldObj), true);
}
tempLinkVector = null;
}
if (canFunction())
{
TileEntity inventoryTile = getLatched();
IInventory inventory = (IInventory) inventoryTile;
if (!suck)
{
renderRotation = Math.max(0, renderRotation - 0.8f);
if (pushDelay == 0)
{
ItemStack retrieved = InventoryUtility.takeTopItemFromInventory(inventory, getDirection().getOpposite().ordinal());
if (retrieved != null)
{
EntityItem item = getItemWithPosition(retrieved);
if (!worldObj.isRemote)
{
worldObj.spawnEntityInWorld(item);
}
pushDelay = Settings.LEVITATOR_PUSH_DELAY;
}
}
}
else if (suck)
{
renderRotation = Math.min(20, renderRotation + 0.8f);
if (suckBounds != null)
{
if (!worldObj.isRemote)
{
for (EntityItem item : (List<EntityItem>) worldObj.getEntitiesWithinAABB(EntityItem.class, suckBounds))
{
ItemStack remains = InventoryUtility.putStackInInventory(inventory, item.getEntityItem(), getDirection().getOpposite().ordinal(), false);
if (remains == null)
{
item.setDead();
}
else
{
item.setEntityItemStack(remains);
}
// TODO: Add redstone pulse?
}
}
}
}
if (thread != null)
{
PathfinderEMContractor newPath = thread.getPath();
if (newPath != null)
{
pathfinder = newPath;
thread = null;
}
}
final int renderFrequency = 1;
final boolean renderBeam = ticks % renderFrequency == 0 && hasLink() && linked.suck != suck;
if (hasLink())
{
if (!suck)
{
if (renderBeam)
Electrical.proxy.renderElectricShock(worldObj, new Vector3(this).translate(0.5), new Vector3(this).translate(new Vector3(getDirection())).translate(0.5), EnumColor.DYES[dyeID].toColor(), false);
// Push entity along path.
if (pathfinder != null)
{
List<Vector3> results = pathfinder.results;
for (int i = 0; i < results.size(); i++)
{
Vector3 result = results.get(i).clone();
if (TileLevitator.canBePath(worldObj, result))
{
if (i - 1 >= 0)
{
Vector3 prevResult = results.get(i - 1).clone();
Vector3 difference = prevResult.clone().difference(result);
final ForgeDirection direction = difference.toForgeDirection();
if (renderBeam)
{
Electrical.proxy.renderElectricShock(worldObj, prevResult.clone().translate(0.5), result.clone().translate(0.5), EnumColor.DYES[dyeID].toColor(), false);
}
AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(result.x, result.y, result.z, result.x + 1, result.y + 1, result.z + 1);
List<EntityItem> entities = worldObj.getEntitiesWithinAABB(EntityItem.class, bounds);
for (EntityItem entityItem : entities)
{
moveEntity(entityItem, direction, result);
}
}
}
else
{
updatePath();
break;
}
}
}
else
{
updatePath();
}
}
else
{
if (renderBeam)
{
Electrical.proxy.renderElectricShock(worldObj, new Vector3(this).translate(0.5), new Vector3(this).translate(new Vector3(getDirection())).translate(0.5), EnumColor.DYES[dyeID].toColor(), false);
}
pathfinder = null;
Vector3 searchVec = new Vector3(this).translate(getDirection());
AxisAlignedBB searchBounds = AxisAlignedBB.getAABBPool().getAABB(searchVec.x, searchVec.y, searchVec.z, searchVec.x + 1, searchVec.y + 1, searchVec.z + 1);
if (searchBounds != null)
{
for (EntityItem entityItem : (List<EntityItem>) worldObj.getEntitiesWithinAABB(EntityItem.class, searchBounds))
{
moveEntity(entityItem, getDirection(), new Vector3(this));
}
}
}
}
else if (!hasLink())
{
for (EntityItem entityItem : (List<EntityItem>) worldObj.getEntitiesWithinAABB(EntityItem.class, operationBounds))
{
if (ticks % renderFrequency == 0)
Electrical.proxy.renderElectricShock(worldObj, new Vector3(this).translate(0.5), new Vector3(entityItem), EnumColor.DYES[dyeID].toColor(), false);
moveEntity(entityItem, getDirection(), new Vector3(this));
}
}
if (linked != null && linked.isInvalid())
{
linked = null;
}
lastCalcTime--;
}
}
public static boolean canBePath(World world, Vector3 position)
{
Block block = Block.blocksList[position.getBlockID(world)];
return block == null || (block instanceof BlockSnow || block instanceof BlockVine || block instanceof BlockLadder || ((block instanceof BlockFluid || block instanceof IFluidBlock) && block.blockID != Block.lavaMoving.blockID && block.blockID != Block.lavaStill.blockID));
}
private boolean hasLink()
{
return linked != null && !linked.isInvalid() && linked.linked == this;
}
private void moveEntity(EntityItem entityItem, ForgeDirection direction, Vector3 lockVector)
{
switch (direction)
{
case DOWN:
entityItem.setPosition(lockVector.x + 0.5, entityItem.posY, lockVector.z + 0.5);
entityItem.motionX = 0;
entityItem.motionZ = 0;
if (!suck)
{
entityItem.motionY = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionY - Settings.LEVITATOR_ACCELERATION);
}
else
{
entityItem.motionY = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionY + .04 + Settings.LEVITATOR_ACCELERATION);
}
break;
case UP:
entityItem.setPosition(lockVector.x + 0.5, entityItem.posY, lockVector.z + 0.5);
entityItem.motionX = 0;
entityItem.motionZ = 0;
if (!suck)
{
entityItem.motionY = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionY + .04 + Settings.LEVITATOR_ACCELERATION);
}
else
{
entityItem.motionY = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionY - Settings.LEVITATOR_ACCELERATION);
}
break;
case NORTH:
entityItem.setPosition(lockVector.x + 0.5, lockVector.y + 0.5, entityItem.posZ);
entityItem.motionX = 0;
entityItem.motionY = 0;
if (!suck)
{
entityItem.motionZ = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionZ - Settings.LEVITATOR_ACCELERATION);
}
else
{
entityItem.motionZ = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionZ + Settings.LEVITATOR_ACCELERATION);
}
break;
case SOUTH:
entityItem.setPosition(lockVector.x + 0.5, lockVector.y + 0.5, entityItem.posZ);
entityItem.motionX = 0;
entityItem.motionY = 0;
if (!suck)
{
entityItem.motionZ = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionZ + Settings.LEVITATOR_ACCELERATION);
}
else
{
entityItem.motionZ = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionZ - Settings.LEVITATOR_ACCELERATION);
}
break;
case WEST:
entityItem.setPosition(entityItem.posX, lockVector.y + 0.5, lockVector.z + 0.5);
entityItem.motionY = 0;
entityItem.motionZ = 0;
if (!suck)
{
entityItem.motionX = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionX - Settings.LEVITATOR_ACCELERATION);
}
else
{
entityItem.motionX = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionX + Settings.LEVITATOR_ACCELERATION);
}
break;
case EAST:
entityItem.setPosition(entityItem.posX, lockVector.y + 0.5, lockVector.z + 0.5);
entityItem.motionY = 0;
entityItem.motionZ = 0;
if (!suck)
{
entityItem.motionX = Math.min(Settings.LEVITATOR_MAX_SPEED, entityItem.motionX + Settings.LEVITATOR_ACCELERATION);
}
else
{
entityItem.motionX = Math.max(-Settings.LEVITATOR_MAX_SPEED, entityItem.motionX - Settings.LEVITATOR_ACCELERATION);
}
break;
default:
break;
}
entityItem.ticksExisted = 1;
entityItem.isAirBorne = true;
entityItem.delayBeforeCanPickup = 1;
entityItem.age = Math.max(entityItem.age - 1, 0);
}
private EntityItem getItemWithPosition(ItemStack toSend)
{
EntityItem item = null;
switch (getDirection())
{
case DOWN:
item = new EntityItem(worldObj, xCoord + 0.5, yCoord - 0.2, zCoord + 0.5, toSend);
break;
case UP:
item = new EntityItem(worldObj, xCoord + 0.5, yCoord + 1.2, zCoord + 0.5, toSend);
break;
case NORTH:
item = new EntityItem(worldObj, xCoord + 0.5, yCoord + 0.5, zCoord - 0.2, toSend);
break;
case SOUTH:
item = new EntityItem(worldObj, xCoord + 0.5, yCoord + 0.5, zCoord + 1.2, toSend);
break;
case WEST:
item = new EntityItem(worldObj, xCoord - 0.2, yCoord + 0.5, zCoord + 0.5, toSend);
break;
case EAST:
item = new EntityItem(worldObj, xCoord + 1.2, yCoord + 0.5, zCoord + 0.5, toSend);
break;
default:
break;
}
item.motionX = 0;
item.motionY = 0;
item.motionZ = 0;
return item;
}
public void updateBounds()
{
ForgeDirection dir = getDirection();
MovingObjectPosition mop = worldObj.clip(new Vector3(this).translate(dir).toVec3(), new Vector3(this).translate(dir, Settings.LEVITATOR_MAX_REACH).toVec3());
int reach = Settings.LEVITATOR_MAX_REACH;
if (mop != null)
{
reach = (int) Math.min(new Vector3(this).distance(new Vector3(mop.hitVec)), reach);
}
if (dir.offsetX + dir.offsetY + dir.offsetZ < 0)
{
operationBounds = AxisAlignedBB.getBoundingBox(xCoord + dir.offsetX * reach, yCoord + dir.offsetY * reach, zCoord + dir.offsetZ * reach, xCoord + 1, yCoord + 1, zCoord + 1);
suckBounds = AxisAlignedBB.getBoundingBox(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, xCoord + 1, yCoord + 1, zCoord + 1);
}
else
{
operationBounds = AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord + 1 + dir.offsetX * reach, yCoord + 1 + dir.offsetY * reach, zCoord + 1 + dir.offsetZ * reach);
suckBounds = AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord + 1 + dir.offsetX, yCoord + 1 + dir.offsetY, zCoord + 1 + dir.offsetZ);
}
}
public boolean isLatched()
{
return getLatched() != null;
}
public TileEntity getLatched()
{
ForgeDirection side = getDirection().getOpposite();
TileEntity tile = worldObj.getBlockTileEntity(xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ);
if (tile instanceof IInventory)
{
return tile;
}
return null;
}
@Override
public ForgeDirection getDirection()
{
return ForgeDirection.getOrientation(getBlockType() != null ? getBlockMetadata() : 0);
}
@Override
public void setDirection(ForgeDirection side)
{
this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, side.ordinal(), 3);
this.updateBounds();
}
@Override
public ArrayList getPacketData(int type)
{
ArrayList data = new ArrayList();
data.add(suck);
data.add(dyeID);
if (linked != null)
{
data.add(true);
data.add(linked.xCoord);
data.add(linked.yCoord);
data.add(linked.zCoord);
}
else
{
data.add(false);
}
return data;
}
@Override
public Packet getDescriptionPacket()
{
return ResonantInduction.PACKET_TILE.getPacket(this, getPacketData(0).toArray());
}
@Override
public void onReceivePacket(ByteArrayDataInput data, EntityPlayer player, Object... extra)
{
suck = data.readBoolean();
dyeID = data.readInt();
if (data.readBoolean())
{
tempLinkVector = new Vector3(data.readInt(), data.readInt(), data.readInt());
}
worldObj.markBlockForRenderUpdate(xCoord, yCoord, zCoord);
updateBounds();
}
public boolean canFunction()
{
return isLatched() && !worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
this.suck = nbt.getBoolean("suck");
this.dyeID = nbt.getInteger("dyeID");
if (nbt.hasKey("link"))
{
tempLinkVector = new Vector3(nbt.getCompoundTag("link"));
}
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setBoolean("suck", suck);
nbt.setInteger("dyeID", dyeID);
if (linked != null)
{
nbt.setCompoundTag("link", new Vector3(linked).writeToNBT(new NBTTagCompound()));
}
}
/**
* Link between two TileEntities, do pathfinding operation.
*/
public void setLink(TileLevitator tileEntity, boolean setOpponent)
{
if (linked != null && setOpponent)
{
linked.setLink(null, false);
}
linked = tileEntity;
if (setOpponent)
{
linked.setLink(this, false);
}
updatePath();
}
public void updatePath()
{
if (thread == null && linked != null && lastCalcTime <= 0)
{
pathfinder = null;
Vector3 start = new Vector3(this).translate(getDirection());
Vector3 target = new Vector3(linked).translate(linked.getDirection());
if (start.distance(target) < Settings.MAX_CONTRACTOR_DISTANCE)
{
if (TileLevitator.canBePath(worldObj, start) && TileLevitator.canBePath(worldObj, target))
{
thread = new ThreadEMPathfinding(new PathfinderEMContractor(worldObj, target), start);
thread.start();
lastCalcTime = 40;
}
}
}
}
public void setDye(int dye)
{
dyeID = dye;
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@Override
public boolean onLink(EntityPlayer player, VectorWorld vector)
{
if (vector != null)
{
if (vector.getTileEntity(this.worldObj) instanceof TileLevitator)
{
this.setLink((TileLevitator) vector.getTileEntity(this.worldObj), true);
if (this.worldObj.isRemote)
{
player.addChatMessage("Linked " + this.getBlockType().getLocalizedName() + " with " + " [" + (int) vector.x + ", " + (int) vector.y + ", " + (int) vector.z + "]");
}
return true;
}
}
return false;
}
}

View file

@ -51,6 +51,21 @@ public abstract class PartFace extends JCuboidPart implements JNormalOcclusion,
this.facing = (byte) (facing - 2);
}
public void initiate()
{
}
@Override
public void update()
{
super.update();
if (ticks++ == 0)
{
initiate();
}
}
@Override
public void readDesc(MCDataInput packet)
{