Levitator now functions properly
This commit is contained in:
parent
0f15e6d1fa
commit
85a074e1a9
8 changed files with 277 additions and 1048 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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++;
|
||||
}
|
|
@ -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)
|
||||
{
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue