buildcraft/common/buildcraft/core/robots/EntityRobot.java

629 lines
14 KiB
Java
Raw Normal View History

2012-07-25 12:45:15 +02:00
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
2014-01-19 11:02:11 +01:00
* http://www.mod-buildcraft.com
2012-07-25 12:45:15 +02:00
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
2012-07-25 12:45:15 +02:00
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.robots;
2014-06-09 00:56:58 +02:00
import java.util.Date;
2014-02-16 12:10:01 +01:00
import io.netty.buffer.ByteBuf;
2014-05-29 21:58:08 +02:00
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
2014-01-19 11:02:11 +01:00
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
2014-02-16 12:10:01 +01:00
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.boards.RedstoneBoardNBT;
2014-05-29 21:58:08 +02:00
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.api.robots.AIRobot;
2014-06-13 13:36:02 +02:00
import buildcraft.api.robots.DockingStationRegistry;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IDockingStation;
2014-02-16 12:10:01 +01:00
import buildcraft.core.DefaultProps;
import buildcraft.core.LaserData;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
2012-07-25 12:45:15 +02:00
public class EntityRobot extends EntityRobotBase implements
2014-05-29 21:58:08 +02:00
IEntityAdditionalSpawnData, IInventory {
public static final ResourceLocation ROBOT_BASE = new ResourceLocation("buildcraft",
DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_base.png");
public static final ResourceLocation ROBOT_BUILDER = new ResourceLocation("buildcraft",
DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_builder.png");
public static final ResourceLocation ROBOT_TRANSPORT = new ResourceLocation("buildcraft",
DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_picker.png");
public static final ResourceLocation ROBOT_FACTORY = new ResourceLocation("buildcraft",
DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_factory.png");
2012-07-25 12:45:15 +02:00
private static ResourceLocation defaultTexture = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_ENTITIES + "/robot_base.png");
public SafeTimeTracker scanForTasks = new SafeTimeTracker (40, 10);
public LaserData laser = new LaserData();
public DockingStation reservedDockingStation;
2014-06-15 02:41:00 +02:00
public DockingStation linkedDockingStation;
public boolean isDocked = false;
public RedstoneBoardRobot board;
public AIRobotMain mainAI;
2014-05-29 21:58:08 +02:00
public ItemStack itemInUse;
2014-06-09 00:56:58 +02:00
public float itemAngle1 = 0;
public float itemAngle2 = 0;
public boolean itemActive = false;
public float itemActiveStage = 0;
public long lastUpdateTime = 0;
private boolean needsUpdate = false;
2014-05-29 21:58:08 +02:00
private ItemStack[] inv = new ItemStack[6];
private String boardID;
private ResourceLocation texture;
private DockingStation currentDockingStation;
private double mjStored;
public EntityRobot(World world, NBTTagCompound boardNBT) {
2014-05-29 21:58:08 +02:00
this(world);
board = (RedstoneBoardRobot) RedstoneBoardRegistry.instance.getRedstoneBoard(boardNBT).create(boardNBT, this);
dataWatcher.updateObject(16, board.getNBTHandler().getID());
if (!world.isRemote) {
mainAI = new AIRobotMain(this);
mainAI.start();
}
2014-05-29 21:58:08 +02:00
}
public EntityRobot(World world) {
super(world);
2012-07-25 12:45:15 +02:00
motionX = 0;
motionY = 0;
motionZ = 0;
2014-01-19 11:02:11 +01:00
ignoreFrustumCheck = true;
laser.isVisible = false;
2014-06-08 12:46:17 +02:00
entityCollisionReduction = 1F;
width = 0.5F;
height = 0.5F;
2012-07-25 12:45:15 +02:00
}
@Override
2014-01-19 11:02:11 +01:00
protected void entityInit() {
super.entityInit();
2012-08-24 15:20:43 +02:00
2014-06-09 00:56:58 +02:00
setNullBoundingBox();
2014-01-19 11:02:11 +01:00
preventEntitySpawning = false;
noClip = true;
isImmuneToFire = true;
2012-08-24 15:20:43 +02:00
dataWatcher.addObject(12, Float.valueOf(0));
dataWatcher.addObject(13, Float.valueOf(0));
dataWatcher.addObject(14, Float.valueOf(0));
dataWatcher.addObject(15, Byte.valueOf((byte) 0));
2014-05-29 21:58:08 +02:00
dataWatcher.addObject(16, "");
2014-06-09 00:56:58 +02:00
dataWatcher.addObject(17, Float.valueOf(0));
dataWatcher.addObject(18, Float.valueOf(0));
2012-07-25 12:45:15 +02:00
}
2014-01-19 11:02:11 +01:00
protected void updateDataClient() {
laser.tail.x = dataWatcher.getWatchableObjectFloat(12);
laser.tail.y = dataWatcher.getWatchableObjectFloat(13);
laser.tail.z = dataWatcher.getWatchableObjectFloat(14);
laser.isVisible = dataWatcher.getWatchableObjectByte(15) == 1;
2014-05-29 21:58:08 +02:00
2014-06-15 19:27:17 +02:00
RedstoneBoardNBT<?> boardNBT = RedstoneBoardRegistry.instance.getRedstoneBoard(dataWatcher
2014-05-29 21:58:08 +02:00
.getWatchableObjectString(16));
if (boardNBT != null) {
texture = ((RedstoneBoardRobotNBT) boardNBT).getRobotTexture();
2014-05-29 21:58:08 +02:00
}
2014-06-09 00:56:58 +02:00
itemAngle1 = dataWatcher.getWatchableObjectFloat(17);
itemAngle2 = dataWatcher.getWatchableObjectFloat(18);
2012-12-17 23:30:54 +01:00
}
2012-07-25 12:45:15 +02:00
2014-01-19 11:02:11 +01:00
protected void updateDataServer() {
dataWatcher.updateObject(12, Float.valueOf((float) laser.tail.x));
dataWatcher.updateObject(13, Float.valueOf((float) laser.tail.y));
dataWatcher.updateObject(14, Float.valueOf((float) laser.tail.z));
dataWatcher.updateObject(15, Byte.valueOf((byte) (laser.isVisible ? 1 : 0)));
2014-06-09 00:56:58 +02:00
dataWatcher.updateObject(17, Float.valueOf(itemAngle1));
dataWatcher.updateObject(18, Float.valueOf(itemAngle2));
2012-12-17 23:30:54 +01:00
}
2012-07-25 12:45:15 +02:00
2014-01-19 11:02:11 +01:00
protected void init() {
if (worldObj.isRemote) {
RPCHandler.rpcServer(this, "requestInitialization");
}
2012-12-17 23:30:54 +01:00
}
2012-07-25 12:45:15 +02:00
2014-01-19 11:02:11 +01:00
public void setLaserDestination (float x, float y, float z) {
if (x != laser.tail.x || y != laser.tail.y || z != laser.tail.z) {
laser.tail.x = x;
laser.tail.y = y;
laser.tail.z = z;
2012-07-25 12:45:15 +02:00
needsUpdate = true;
}
2012-07-25 12:45:15 +02:00
}
2014-06-15 19:27:17 +02:00
public void showLaser() {
if (!laser.isVisible) {
2014-01-19 11:02:11 +01:00
laser.isVisible = true;
needsUpdate = true;
}
}
2012-07-25 12:45:15 +02:00
2014-06-15 19:27:17 +02:00
public void hideLaser() {
if (laser.isVisible) {
2014-01-19 11:02:11 +01:00
laser.isVisible = false;
needsUpdate = true;
}
}
2012-07-25 12:45:15 +02:00
2014-01-19 11:02:11 +01:00
@Override
public void onUpdate() {
2014-02-16 12:10:01 +01:00
if (!worldObj.isRemote && needsUpdate) {
2014-01-19 11:02:11 +01:00
updateDataServer();
needsUpdate = false;
2012-07-25 12:45:15 +02:00
}
2014-02-16 12:10:01 +01:00
if (worldObj.isRemote) {
2014-01-19 11:02:11 +01:00
updateDataClient();
}
2012-07-25 12:45:15 +02:00
if (currentDockingStation != null) {
motionX = 0;
motionY = 0;
motionZ = 0;
posX = currentDockingStation.pipe.xCoord + 0.5F + currentDockingStation.side.offsetX * 0.5F;
posY = currentDockingStation.pipe.yCoord + 0.5F + currentDockingStation.side.offsetY * 0.5F;
posZ = currentDockingStation.pipe.zCoord + 0.5F + currentDockingStation.side.offsetZ * 0.5F;
2014-05-08 15:28:23 +02:00
}
2012-07-25 12:45:15 +02:00
if (!worldObj.isRemote) {
mainAI.cycle();
}
super.onUpdate();
}
2012-07-25 12:45:15 +02:00
2014-06-15 19:27:17 +02:00
public void setRegularBoundingBox() {
width = 0.5F;
height = 0.5F;
2012-07-25 12:45:15 +02:00
2014-01-19 11:02:11 +01:00
if (laser.isVisible) {
boundingBox.minX = Math.min(posX, laser.tail.x);
boundingBox.minY = Math.min(posY, laser.tail.y);
boundingBox.minZ = Math.min(posZ, laser.tail.z);
2012-07-25 12:45:15 +02:00
2014-01-19 11:02:11 +01:00
boundingBox.maxX = Math.max(posX, laser.tail.x);
boundingBox.maxY = Math.max(posY, laser.tail.y);
boundingBox.maxZ = Math.max(posZ, laser.tail.z);
2012-07-25 12:45:15 +02:00
2014-01-19 11:02:11 +01:00
boundingBox.minX--;
boundingBox.minY--;
boundingBox.minZ--;
boundingBox.maxX++;
boundingBox.maxY++;
boundingBox.maxZ++;
} else {
boundingBox.minX = posX - 0.25F;
boundingBox.minY = posY - 0.25F;
boundingBox.minZ = posZ - 0.25F;
2014-01-19 11:02:11 +01:00
boundingBox.maxX = posX + 0.25F;
boundingBox.maxY = posY + 0.25F;
boundingBox.maxZ = posZ + 0.25F;
2012-07-25 12:45:15 +02:00
}
}
2014-06-15 19:27:17 +02:00
public void setNullBoundingBox() {
width = 0F;
height = 0F;
boundingBox.minX = posX;
boundingBox.minY = posY;
boundingBox.minZ = posZ;
2012-07-25 12:45:15 +02:00
boundingBox.maxX = posX;
boundingBox.maxY = posY;
boundingBox.maxZ = posZ;
2012-07-25 12:45:15 +02:00
}
2014-06-15 19:27:17 +02:00
private void iterateBehaviorDocked() {
motionX = 0F;
motionY = 0F;
motionZ = 0F;
setNullBoundingBox ();
2014-01-19 11:02:11 +01:00
}
2012-08-24 15:20:43 +02:00
2014-01-19 11:02:11 +01:00
@Override
2014-02-16 12:10:01 +01:00
public void writeSpawnData(ByteBuf data) {
2012-08-24 15:20:43 +02:00
2014-01-19 11:02:11 +01:00
}
2012-08-24 15:20:43 +02:00
2014-01-19 11:02:11 +01:00
@Override
2014-02-16 12:10:01 +01:00
public void readSpawnData(ByteBuf data) {
2014-01-19 11:02:11 +01:00
init();
2012-07-25 12:45:15 +02:00
}
2014-01-19 11:02:11 +01:00
@Override
public ItemStack getHeldItem() {
return null;
2012-07-25 12:45:15 +02:00
}
2014-01-19 11:02:11 +01:00
@Override
public void setCurrentItemOrArmor(int i, ItemStack itemstack) {
2012-07-25 12:45:15 +02:00
}
2014-01-19 11:02:11 +01:00
@Override
public ItemStack[] getLastActiveItems() {
return new ItemStack [0];
2012-07-25 12:45:15 +02:00
}
2014-01-19 11:02:11 +01:00
2012-07-25 12:45:15 +02:00
@Override
2014-01-19 11:02:11 +01:00
protected void fall(float par1) {}
@Override
protected void updateFallState(double par1, boolean par3) {}
@Override
public void moveEntityWithHeading(float par1, float par2) {
this.setPosition(posX + motionX, posY + motionY, posZ + motionZ);
2012-07-25 12:45:15 +02:00
}
2014-01-19 11:02:11 +01:00
@Override
public boolean isOnLadder() {
return false;
}
2014-02-16 12:10:01 +01:00
public ResourceLocation getTexture () {
2014-05-29 21:58:08 +02:00
return texture;
}
@Override
2014-02-16 22:29:46 +01:00
public void writeEntityToNBT(NBTTagCompound nbt) {
super.writeEntityToNBT(nbt);
2014-06-15 02:41:00 +02:00
if (linkedDockingStation != null) {
nbt.setInteger("dockX", linkedDockingStation.pipe.xCoord);
nbt.setInteger("dockY", linkedDockingStation.pipe.yCoord);
nbt.setInteger("dockZ", linkedDockingStation.pipe.zCoord);
nbt.setInteger("dockSide", linkedDockingStation.side.ordinal());
}
2014-02-16 22:29:46 +01:00
NBTTagCompound nbtLaser = new NBTTagCompound();
laser.writeToNBT(nbtLaser);
nbt.setTag("laser", nbtLaser);
2014-05-29 21:58:08 +02:00
for (int i = 0; i < inv.length; ++i) {
NBTTagCompound stackNbt = new NBTTagCompound();
if (inv[i] != null) {
nbt.setTag("inv[" + i + "]", inv[i].writeToNBT(stackNbt));
}
}
2014-02-16 22:29:46 +01:00
}
@Override
public void readEntityFromNBT(NBTTagCompound nbt) {
super.readEntityFromNBT(nbt);
if (nbt.hasKey("dockX")) {
2014-06-15 02:41:00 +02:00
linkedDockingStation = (DockingStation) DockingStationRegistry.getStation(
2014-06-13 13:36:02 +02:00
nbt.getInteger("dockX"),
nbt.getInteger("dockY"),
nbt.getInteger("dockZ"),
ForgeDirection.values()[nbt.getInteger("dockSide")]);
}
2014-02-16 22:29:46 +01:00
2014-05-08 15:28:23 +02:00
/*
* if (nbt.hasKey("ai")) { try { nextAI = (RobotAIBase)
* Class.forName(nbt.getString("ai")).newInstance(); } catch (Throwable
* t) { t.printStackTrace(); } }
*/
2014-02-16 22:29:46 +01:00
laser.readFromNBT(nbt.getCompoundTag("laser"));
2014-05-29 21:58:08 +02:00
for (int i = 0; i < inv.length; ++i) {
inv[i] = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("inv[" + i + "]"));
}
setDead();
2014-02-16 12:10:01 +01:00
}
@Override
public void dock(IDockingStation station) {
currentDockingStation = (DockingStation) station;
}
@Override
public void undock() {
if (currentDockingStation != null) {
currentDockingStation.release(this);
currentDockingStation = null;
}
}
@Override
public DockingStation getDockingStation() {
return currentDockingStation;
}
@Override
2014-06-15 17:33:09 +02:00
public boolean reserveStation(IDockingStation iStation) {
DockingStation station = (DockingStation) iStation;
if (station == null) {
if (reservedDockingStation != null) {
reservedDockingStation.release(this);
}
reservedDockingStation = null;
return true;
}
if (station.reserved() == this) {
return true;
}
if (station.reserve(this)) {
if (reservedDockingStation != null) {
reservedDockingStation.release(this);
}
reservedDockingStation = station;
return true;
} else {
return false;
}
}
@Override
2014-06-15 17:33:09 +02:00
public boolean linkToStation(IDockingStation iStation) {
DockingStation station = (DockingStation) iStation;
if (station.linked() == this) {
return true;
}
if (station.link(this)) {
if (linkedDockingStation != null) {
linkedDockingStation.unlink(this);
}
linkedDockingStation = station;
return true;
} else {
return false;
}
}
2014-02-16 12:10:01 +01:00
@Override
public ItemStack getEquipmentInSlot(int var1) {
return null;
}
public boolean acceptTask (IRobotTask task) {
return false;
}
@Override
protected boolean isAIEnabled() {
return true;
}
2014-05-29 21:58:08 +02:00
@Override
public int getSizeInventory() {
return inv.length;
}
@Override
public ItemStack getStackInSlot(int var1) {
return inv[var1];
}
@Override
public ItemStack decrStackSize(int var1, int var2) {
ItemStack result = inv[var1].splitStack(var2);
if (inv[var1].stackSize == 0) {
inv[var1] = null;
}
return result;
}
@Override
public ItemStack getStackInSlotOnClosing(int var1) {
return inv[var1].splitStack(var1);
}
@Override
public void setInventorySlotContents(int var1, ItemStack var2) {
inv[var1] = var2;
}
@Override
public String getInventoryName() {
return null;
}
@Override
public boolean hasCustomInventoryName() {
return false;
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public void markDirty() {
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1) {
return false;
}
@Override
public void openInventory() {
}
@Override
public void closeInventory() {
}
@Override
public boolean isItemValidForSlot(int var1, ItemStack var2) {
return inv[var1] == null
|| (inv[var1].isItemEqual(var2) && inv[var1].isStackable() && inv[var1].stackSize
2014-06-15 19:27:17 +02:00
+ var2.stackSize <= inv[var1].getItem().getItemStackLimit());
2014-05-29 21:58:08 +02:00
}
@Override
public boolean isMoving() {
return motionX != 0 || motionY != 0 || motionZ != 0;
}
@Override
public void setItemInUse(ItemStack stack) {
itemInUse = stack;
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "clientSetItemInUse", stack);
}
@RPC(RPCSide.CLIENT)
private void clientSetItemInUse(ItemStack stack) {
itemInUse = stack;
}
@RPC(RPCSide.SERVER)
public void requestInitialization(RPCMessageInfo info) {
RPCHandler.rpcPlayer(info.sender, this, "rpcInitialize", itemInUse, itemActive);
}
@RPC(RPCSide.CLIENT)
private void rpcInitialize(ItemStack stack, boolean active) {
itemInUse = stack;
itemActive = active;
}
2014-06-08 14:14:16 +02:00
@Override
public void setHealth(float par1) {
// deactivate healh management
}
2014-06-09 00:56:58 +02:00
@Override
public void aimItemAt(int x, int y, int z) {
2014-06-12 13:49:05 +02:00
itemAngle1 = (float) Math.atan2(z - Math.floor(posZ),
x - Math.floor(posX));
2014-06-12 13:49:05 +02:00
itemAngle2 = 0;
if (Math.floor(posY) < y) {
itemAngle2 = (float) -Math.PI / 4;
if (Math.floor(posX) == x && Math.floor(posZ) == z) {
itemAngle2 -= (float) Math.PI / 4;
}
} else if (Math.floor(posY) > y) {
itemAngle2 = (float) Math.PI / 2;
if (Math.floor(posX) == x && Math.floor(posZ) == z) {
itemAngle2 += (float) Math.PI / 4;
}
}
2014-06-09 00:56:58 +02:00
updateDataServer();
}
@Override
2014-06-09 00:56:58 +02:00
public void setItemActive(boolean isActive) {
RPCHandler.rpcBroadcastWorldPlayers(worldObj, this, "rpcSetItemActive", isActive);
2014-06-09 00:56:58 +02:00
}
@RPC(RPCSide.CLIENT)
private void rpcSetItemActive(boolean isActive) {
itemActive = isActive;
itemActiveStage = 0;
lastUpdateTime = new Date().getTime();
}
@Override
public ItemStack getItemInUse() {
return itemInUse;
}
@Override
public RedstoneBoardRobot getBoard() {
return board;
}
@Override
public DockingStation getLinkedStation() {
2014-06-15 02:41:00 +02:00
return linkedDockingStation;
}
@SideOnly(Side.CLIENT)
@Override
public boolean isInRangeToRenderDist(double par1) {
return true;
}
@Override
public double getEnergy() {
return mjStored;
}
@Override
public void setEnergy(double energy) {
mjStored = energy;
if (mjStored > MAX_ENERGY) {
mjStored = MAX_ENERGY;
}
}
@Override
protected boolean canDespawn() {
return false;
}
public AIRobot getOverridingAI() {
return mainAI.getOverridingAI();
}
public void overrideAI(AIRobot ai) {
mainAI.setOverridingAI(ai);
}
2012-07-25 12:45:15 +02:00
}