diff --git a/src/resonantinduction/base/Vector3.java b/src/resonantinduction/base/Vector3.java index cca2d2bf0..119a029d8 100644 --- a/src/resonantinduction/base/Vector3.java +++ b/src/resonantinduction/base/Vector3.java @@ -109,10 +109,10 @@ public class Vector3 { return this.x * vec2.x + this.y * vec2.y + this.z * vec2.z; } - + public Vector3 getFromSide(ForgeDirection side) { - return new Vector3(x+side.offsetX, y+side.offsetY, z+side.offsetZ); + return new Vector3(x + side.offsetX, y + side.offsetY, z + side.offsetZ); } /** @@ -306,7 +306,7 @@ public class Vector3 { return new Vector3(this.x, this.y, this.z); } - + @Override public int hashCode() { @@ -316,22 +316,22 @@ public class Vector3 code = 31 * new Double(z).hashCode(); return code; } - + @Override public boolean equals(Object obj) { - if(!(obj instanceof Vector3)) + if (!(obj instanceof Vector3)) { return false; } - - Vector3 vec = (Vector3)obj; - - if(vec.x != x || vec.y != y || vec.z != z) + + Vector3 vec = (Vector3) obj; + + if (vec.x != x || vec.y != y || vec.z != z) { return false; } - + return true; } @@ -340,4 +340,26 @@ public class Vector3 { return "Vector3 [" + this.x + "," + this.y + "," + this.z + "]"; } + + /** + * @param world + * @return + */ + public int getBlockID(World world) + { + return world.getBlockId((int) this.x, (int) this.y, (int) this.z); + } + + public ForgeDirection toForgeDirection() + { + for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) + { + if (this.x == direction.offsetX && this.y == direction.offsetY && this.z == direction.offsetZ) + { + return direction; + } + } + + return ForgeDirection.UNKNOWN; + } } diff --git a/src/resonantinduction/contractor/BlockEMContractor.java b/src/resonantinduction/contractor/BlockEMContractor.java index 0c6bf2df1..bc327bd76 100644 --- a/src/resonantinduction/contractor/BlockEMContractor.java +++ b/src/resonantinduction/contractor/BlockEMContractor.java @@ -47,7 +47,11 @@ public class BlockEMContractor extends BlockBase implements ITileEntityProvider if (linkVec.getTileEntity(world) instanceof TileEntityEMContractor) { contractor.setLink((TileEntityEMContractor) linkVec.getTileEntity(world)); - entityPlayer.addChatMessage("Linked " + this.getLocalizedName() + " with " + " [" + (int) linkVec.x + ", " + (int) linkVec.y + ", " + (int) linkVec.z + "]"); + + if (!world.isRemote) + { + entityPlayer.addChatMessage("Linked " + this.getLocalizedName() + " with " + " [" + (int) linkVec.x + ", " + (int) linkVec.y + ", " + (int) linkVec.z + "]"); + } return true; } } diff --git a/src/resonantinduction/contractor/Pathfinder.java b/src/resonantinduction/contractor/PathfinderEMContractor.java similarity index 56% rename from src/resonantinduction/contractor/Pathfinder.java rename to src/resonantinduction/contractor/PathfinderEMContractor.java index cba416687..3ddd657cc 100644 --- a/src/resonantinduction/contractor/Pathfinder.java +++ b/src/resonantinduction/contractor/PathfinderEMContractor.java @@ -3,10 +3,13 @@ */ package resonantinduction.contractor; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Set; +import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; import resonantinduction.base.Vector3; @@ -16,7 +19,7 @@ import resonantinduction.base.Vector3; * @author Calclavia * */ -public class Pathfinder +public class PathfinderEMContractor { public Set openSet, closedSet; @@ -26,10 +29,13 @@ public class Pathfinder public Vector3 target; - public Set results; + public List results; - public Pathfinder(Vector3 target) + private World world; + + public PathfinderEMContractor(World world, Vector3 target) { + this.world = world; this.target = target; } @@ -43,12 +49,32 @@ public class Pathfinder this.navMap = new HashMap(); this.gScore = new HashMap(); this.fScore = new HashMap(); - this.results = new HashSet(); + this.results = new ArrayList(); this.openSet.add(start); this.gScore.put(start, (double) 0); this.fScore.put(start, this.gScore.get(start) + getEstimate(start, this.target)); + int blockCount = 0; + + for (int i = 0; i < 6; i++) + { + ForgeDirection direction = ForgeDirection.getOrientation(i); + Vector3 neighbor = this.target.clone().translate(new Vector3(direction.offsetX, direction.offsetY, direction.offsetZ)); + + if (!TileEntityEMContractor.canBePath(this.world, neighbor)) + { + blockCount++; + } + } + + if (blockCount >= 6) + { + return false; + } + + double maxSearchDistance = start.distance(this.target) * 2; + while (!this.openSet.isEmpty()) { Vector3 currentNode = null; @@ -63,13 +89,11 @@ public class Pathfinder } } - if (currentNode == null) + if (currentNode == null && start.distance(currentNode) > maxSearchDistance) { break; } - // Break case here; - if (currentNode.equals(this.target)) { this.results = this.reconstructPath(this.navMap, this.target); @@ -82,24 +106,28 @@ public class Pathfinder for (int i = 0; i < 6; i++) { ForgeDirection direction = ForgeDirection.getOrientation(i); + Vector3 neighbor = currentNode.clone().translate(new Vector3(direction.offsetX, direction.offsetY, direction.offsetZ)); - double tentativeG = this.gScore.get(currentNode); - - if (this.closedSet.contains(neighbor)) + if (TileEntityEMContractor.canBePath(this.world, neighbor)) { - if (tentativeG >= this.gScore.get(neighbor)) + double tentativeG = this.gScore.get(currentNode) + currentNode.distance(neighbor); + + if (this.closedSet.contains(neighbor)) { - continue; + if (tentativeG >= this.gScore.get(neighbor)) + { + continue; + } } - } - if (!this.openSet.contains(neighbor) || tentativeG < this.gScore.get(neighbor)) - { - this.navMap.put(neighbor, currentNode); - this.gScore.put(neighbor, tentativeG); - this.fScore.put(neighbor, this.gScore.get(neighbor) + this.getEstimate(neighbor, this.target)); - this.openSet.add(neighbor); + if (!this.openSet.contains(neighbor) || tentativeG < this.gScore.get(neighbor)) + { + this.navMap.put(neighbor, currentNode); + this.gScore.put(neighbor, tentativeG); + this.fScore.put(neighbor, this.gScore.get(neighbor) + this.getEstimate(neighbor, this.target)); + this.openSet.add(neighbor); + } } } } @@ -107,9 +135,9 @@ public class Pathfinder return false; } - private Set reconstructPath(HashMap naviMap, Vector3 currentNode) + private List reconstructPath(HashMap naviMap, Vector3 currentNode) { - Set path = new HashSet(); + List path = new ArrayList(); path.add(currentNode); if (naviMap.containsKey(currentNode)) diff --git a/src/resonantinduction/contractor/TileEntityEMContractor.java b/src/resonantinduction/contractor/TileEntityEMContractor.java index 353df3a13..963a234ca 100644 --- a/src/resonantinduction/contractor/TileEntityEMContractor.java +++ b/src/resonantinduction/contractor/TileEntityEMContractor.java @@ -11,6 +11,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; import resonantinduction.PacketHandler; import resonantinduction.ResonantInduction; @@ -49,16 +50,16 @@ public class TileEntityEMContractor extends TileEntityBase implements IPacketRec */ public boolean suck = true; - private Pathfinder pathfinder; + private PathfinderEMContractor pathfinder; private Set pathfindingTrackers = new HashSet(); - private TileEntityEMContractor linked; + public TileEntityEMContractor linked; @Override public void updateEntity() { super.updateEntity(); - pushDelay = Math.max(0, pushDelay - 1); + this.pushDelay = Math.max(0, this.pushDelay - 1); if (canFunction()) { @@ -67,7 +68,7 @@ public class TileEntityEMContractor extends TileEntityBase implements IPacketRec if (!suck && pushDelay == 0) { - ItemStack retrieved = InventoryUtil.takeTopItemFromInventory(inventory, facing.ordinal()); + ItemStack retrieved = InventoryUtil.takeTopItemFromInventory(inventory, this.facing.ordinal()); if (retrieved != null) { @@ -75,7 +76,7 @@ public class TileEntityEMContractor extends TileEntityBase implements IPacketRec if (!worldObj.isRemote) { - worldObj.spawnEntityInWorld(item); + this.worldObj.spawnEntityInWorld(item); } pushDelay = PUSH_DELAY; @@ -100,146 +101,179 @@ public class TileEntityEMContractor extends TileEntityBase implements IPacketRec } } } - } - if (operationBounds != null && canFunction()) - { - energyStored -= ENERGY_USAGE; - - for (EntityItem entityItem : (List) worldObj.getEntitiesWithinAABB(EntityItem.class, operationBounds)) + if (!this.suck && this.linked != null && !this.linked.isInvalid()) { - if (this.worldObj.isRemote && this.ticks % 5 == 0) + if (this.pathfinder != null) { - ResonantInduction.proxy.renderElectricShock(this.worldObj, new Vector3(this).translate(0.5), new Vector3(entityItem)); + for (int i = 0; i < this.pathfinder.results.size(); i++) + { + Vector3 result = this.pathfinder.results.get(i); + + if (this.canBePath(this.worldObj, result)) + { + if (i - 1 >= 0) + { + Vector3 prevResult = this.pathfinder.results.get(i - 1); + ResonantInduction.proxy.renderElectricShock(this.worldObj, prevResult.translate(0.5), result.translate(0.5)); + + Vector3 difference = prevResult.difference(result); + final ForgeDirection direction = difference.toForgeDirection(); + System.out.println(direction); + AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(result.x, result.y, result.z, result.x + 1, result.y + 1, result.z + 1); + List entities = this.worldObj.getEntitiesWithinAABB(EntityItem.class, bounds); + + for (EntityItem entityItem : entities) + { + this.moveEntity(entityItem, direction); + } + } + } + else + { + this.updatePath(); + break; + } + } } + } + else + { + this.pathfinder = null; - switch (facing) + if (operationBounds != null) { - case DOWN: - if (!worldObj.isRemote) + energyStored -= ENERGY_USAGE; + + for (EntityItem entityItem : (List) worldObj.getEntitiesWithinAABB(EntityItem.class, operationBounds)) + { + if (this.worldObj.isRemote && this.ticks % 5 == 0) { - entityItem.setPosition(xCoord + 0.5, entityItem.posY, zCoord + 0.5); + ResonantInduction.proxy.renderElectricShock(this.worldObj, new Vector3(this).translate(0.5), new Vector3(entityItem)); } - entityItem.motionX = 0; - entityItem.motionZ = 0; - - if (!suck) - { - entityItem.motionY = Math.max(-MAX_SPEED, entityItem.motionY - ACCELERATION); - } - else - { - entityItem.motionY = Math.min(MAX_SPEED, entityItem.motionY + .04 + ACCELERATION); - } - - entityItem.isAirBorne = true; - break; - case UP: - if (!worldObj.isRemote) - { - entityItem.setPosition(xCoord + 0.5, entityItem.posY, zCoord + 0.5); - } - - entityItem.motionX = 0; - entityItem.motionZ = 0; - - if (!suck) - { - entityItem.motionY = Math.min(MAX_SPEED, entityItem.motionY + .04 + ACCELERATION); - } - else - { - entityItem.motionY = Math.max(-MAX_SPEED, entityItem.motionY - ACCELERATION); - } - - entityItem.isAirBorne = true; - break; - case NORTH: - if (!worldObj.isRemote) - { - entityItem.setPosition(xCoord + 0.5, yCoord + 0.5, entityItem.posZ); - } - - entityItem.motionX = 0; - entityItem.motionY = 0; - - if (!suck) - { - entityItem.motionZ = Math.max(-MAX_SPEED, entityItem.motionZ - ACCELERATION); - } - else - { - entityItem.motionZ = Math.min(MAX_SPEED, entityItem.motionZ + ACCELERATION); - } - - entityItem.isAirBorne = true; - break; - case SOUTH: - if (!worldObj.isRemote) - { - entityItem.setPosition(xCoord + 0.5, yCoord + 0.5, entityItem.posZ); - } - - entityItem.motionX = 0; - entityItem.motionY = 0; - - if (!suck) - { - entityItem.motionZ = Math.min(MAX_SPEED, entityItem.motionZ + ACCELERATION); - } - else - { - entityItem.motionZ = Math.max(-MAX_SPEED, entityItem.motionZ - ACCELERATION); - } - - entityItem.isAirBorne = true; - break; - case WEST: - if (!worldObj.isRemote) - { - entityItem.setPosition(entityItem.posX, yCoord + 0.5, zCoord + 0.5); - } - - entityItem.motionY = 0; - entityItem.motionZ = 0; - - if (!suck) - { - entityItem.motionX = Math.max(-MAX_SPEED, entityItem.motionX - ACCELERATION); - } - else - { - entityItem.motionX = Math.min(MAX_SPEED, entityItem.motionX + ACCELERATION); - } - - entityItem.isAirBorne = true; - break; - case EAST: - if (!worldObj.isRemote) - { - entityItem.setPosition(entityItem.posX, yCoord + 0.5, zCoord + 0.5); - } - - entityItem.motionY = 0; - entityItem.motionZ = 0; - - if (!suck) - { - entityItem.motionX = Math.min(MAX_SPEED, entityItem.motionX + ACCELERATION); - } - else - { - entityItem.motionX = Math.max(-MAX_SPEED, entityItem.motionX - ACCELERATION); - } - - entityItem.isAirBorne = true; - break; + this.moveEntity(entityItem, this.getFacing()); + } } } } } + public static boolean canBePath(World world, Vector3 position) + { + return position.getBlockID(world) == 0 || position.getTileEntity(world) instanceof TileEntityEMContractor; + } + + private void moveEntity(EntityItem entityItem, ForgeDirection direction) + { + switch (direction) + { + case DOWN: + entityItem.setPosition(Math.floor(entityItem.posX) + 0.5, entityItem.posY, Math.floor(entityItem.posZ) + 0.5); + + entityItem.motionX = 0; + entityItem.motionZ = 0; + + if (!suck) + { + entityItem.motionY = Math.max(-MAX_SPEED, entityItem.motionY - ACCELERATION); + } + else + { + entityItem.motionY = Math.min(MAX_SPEED, entityItem.motionY + .04 + ACCELERATION); + } + + break; + case UP: + + entityItem.setPosition(xCoord + 0.5, entityItem.posY, zCoord + 0.5); + + entityItem.motionX = 0; + entityItem.motionZ = 0; + + if (!suck) + { + entityItem.motionY = Math.min(MAX_SPEED, entityItem.motionY + .04 + ACCELERATION); + } + else + { + entityItem.motionY = Math.max(-MAX_SPEED, entityItem.motionY - ACCELERATION); + } + + break; + case NORTH: + + entityItem.setPosition(xCoord + 0.5, yCoord + 0.5, entityItem.posZ); + + entityItem.motionX = 0; + entityItem.motionY = 0; + + if (!suck) + { + entityItem.motionZ = Math.max(-MAX_SPEED, entityItem.motionZ - ACCELERATION); + } + else + { + entityItem.motionZ = Math.min(MAX_SPEED, entityItem.motionZ + ACCELERATION); + } + + break; + case SOUTH: + + entityItem.setPosition(xCoord + 0.5, yCoord + 0.5, entityItem.posZ); + + entityItem.motionX = 0; + entityItem.motionY = 0; + + if (!suck) + { + entityItem.motionZ = Math.min(MAX_SPEED, entityItem.motionZ + ACCELERATION); + } + else + { + entityItem.motionZ = Math.max(-MAX_SPEED, entityItem.motionZ - ACCELERATION); + } + + break; + case WEST: + + entityItem.setPosition(entityItem.posX, yCoord + 0.5, zCoord + 0.5); + + entityItem.motionY = 0; + entityItem.motionZ = 0; + + if (!suck) + { + entityItem.motionX = Math.max(-MAX_SPEED, entityItem.motionX - ACCELERATION); + } + else + { + entityItem.motionX = Math.min(MAX_SPEED, entityItem.motionX + ACCELERATION); + } + + break; + case EAST: + entityItem.setPosition(entityItem.posX, yCoord + 0.5, zCoord + 0.5); + + entityItem.motionY = 0; + entityItem.motionZ = 0; + + if (!suck) + { + entityItem.motionX = Math.min(MAX_SPEED, entityItem.motionX + ACCELERATION); + } + else + { + entityItem.motionX = Math.max(-MAX_SPEED, entityItem.motionX - ACCELERATION); + } + + break; + } + + entityItem.isAirBorne = true; + entityItem.delayBeforeCanPickup = 1; + } + private EntityItem getItemWithPosition(ItemStack toSend) { EntityItem item = null; @@ -357,7 +391,7 @@ public class TileEntityEMContractor extends TileEntityBase implements IPacketRec public boolean canFunction() { - return isLatched() && worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); + return isLatched() && !this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord); } @Override @@ -434,6 +468,7 @@ public class TileEntityEMContractor extends TileEntityBase implements IPacketRec public void setLink(TileEntityEMContractor tileEntity) { this.linked = tileEntity; + this.linked.linked = this; this.updatePath(); } @@ -443,8 +478,8 @@ public class TileEntityEMContractor extends TileEntityBase implements IPacketRec if (this.linked != null) { - this.pathfinder = new Pathfinder(new Vector3(this)); - this.pathfinder.find(new Vector3(this.linked)); + this.pathfinder = new PathfinderEMContractor(this.worldObj, new Vector3(this.linked)); + this.pathfinder.find(new Vector3(this)); } } }