buildcraft/common/buildcraft/core/robots/EntityRobot.java
2014-06-13 13:36:02 +02:00

574 lines
14 KiB
Java
Executable file

/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* 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
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.robots;
import java.util.Date;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
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;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.boards.RedstoneBoardNBT;
import buildcraft.api.boards.RedstoneBoardRegistry;
import buildcraft.api.boards.RedstoneBoardRobot;
import buildcraft.api.boards.RedstoneBoardRobotNBT;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.api.robots.DockingStationRegistry;
import buildcraft.api.robots.EntityRobotBase;
import buildcraft.api.robots.IDockingStation;
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;
public class EntityRobot extends EntityRobotBase implements
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");
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 mainDockingStation;
public boolean isDocked = false;
public RedstoneBoardRobot board;
public AIRobotMain mainAI;
public ItemStack itemInUse;
public float itemAngle1 = 0;
public float itemAngle2 = 0;
public boolean itemActive = false;
public float itemActiveStage = 0;
public long lastUpdateTime = 0;
private boolean needsUpdate = false;
private ItemStack[] inv = new ItemStack[6];
private String boardID;
private ResourceLocation texture;
private DockingStation currentDockingStation;
private double mjStored;
public EntityRobot(World world, NBTTagCompound boardNBT) {
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();
}
}
public EntityRobot(World world) {
super(world);
motionX = 0;
motionY = 0;
motionZ = 0;
ignoreFrustumCheck = true;
laser.isVisible = false;
entityCollisionReduction = 1F;
width = 0.5F;
height = 0.5F;
}
@Override
protected void entityInit() {
super.entityInit();
setNullBoundingBox();
preventEntitySpawning = false;
noClip = true;
isImmuneToFire = true;
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));
dataWatcher.addObject(16, "");
dataWatcher.addObject(17, Float.valueOf(0));
dataWatcher.addObject(18, Float.valueOf(0));
}
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;
RedstoneBoardNBT boardNBT = RedstoneBoardRegistry.instance.getRedstoneBoard(dataWatcher
.getWatchableObjectString(16));
if (boardNBT != null) {
texture = ((RedstoneBoardRobotNBT) boardNBT).getRobotTexture();
}
itemAngle1 = dataWatcher.getWatchableObjectFloat(17);
itemAngle2 = dataWatcher.getWatchableObjectFloat(18);
}
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)));
dataWatcher.updateObject(17, Float.valueOf(itemAngle1));
dataWatcher.updateObject(18, Float.valueOf(itemAngle2));
}
protected void init() {
if (worldObj.isRemote) {
RPCHandler.rpcServer(this, "requestInitialization");
}
}
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;
needsUpdate = true;
}
}
public void showLaser () {
if (!laser.isVisible) {
laser.isVisible = true;
needsUpdate = true;
}
}
public void hideLaser () {
if (laser.isVisible) {
laser.isVisible = false;
needsUpdate = true;
}
}
@Override
public void onUpdate() {
if (!worldObj.isRemote && needsUpdate) {
updateDataServer();
needsUpdate = false;
}
if (worldObj.isRemote) {
updateDataClient();
}
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;
}
if (!worldObj.isRemote) {
mainAI.cycle();
}
super.onUpdate();
}
public void setRegularBoundingBox () {
width = 0.5F;
height = 0.5F;
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);
boundingBox.maxX = Math.max(posX, laser.tail.x);
boundingBox.maxY = Math.max(posY, laser.tail.y);
boundingBox.maxZ = Math.max(posZ, laser.tail.z);
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;
boundingBox.maxX = posX + 0.25F;
boundingBox.maxY = posY + 0.25F;
boundingBox.maxZ = posZ + 0.25F;
}
}
public void setNullBoundingBox () {
width = 0F;
height = 0F;
boundingBox.minX = posX;
boundingBox.minY = posY;
boundingBox.minZ = posZ;
boundingBox.maxX = posX;
boundingBox.maxY = posY;
boundingBox.maxZ = posZ;
}
private void iterateBehaviorDocked () {
motionX = 0F;
motionY = 0F;
motionZ = 0F;
setNullBoundingBox ();
}
@Override
public void writeSpawnData(ByteBuf data) {
}
@Override
public void readSpawnData(ByteBuf data) {
init();
}
@Override
public ItemStack getHeldItem() {
return null;
}
@Override
public void setCurrentItemOrArmor(int i, ItemStack itemstack) {
}
@Override
public ItemStack[] getLastActiveItems() {
return new ItemStack [0];
}
@Override
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);
}
@Override
public boolean isOnLadder() {
return false;
}
public ResourceLocation getTexture () {
return texture;
}
@Override
public void writeEntityToNBT(NBTTagCompound nbt) {
super.writeEntityToNBT(nbt);
if (mainDockingStation != null) {
nbt.setInteger("dockX", mainDockingStation.pipe.xCoord);
nbt.setInteger("dockY", mainDockingStation.pipe.yCoord);
nbt.setInteger("dockZ", mainDockingStation.pipe.zCoord);
nbt.setInteger("dockSide", mainDockingStation.side.ordinal());
}
NBTTagCompound nbtLaser = new NBTTagCompound();
laser.writeToNBT(nbtLaser);
nbt.setTag("laser", nbtLaser);
for (int i = 0; i < inv.length; ++i) {
NBTTagCompound stackNbt = new NBTTagCompound();
if (inv[i] != null) {
nbt.setTag("inv[" + i + "]", inv[i].writeToNBT(stackNbt));
}
}
}
@Override
public void readEntityFromNBT(NBTTagCompound nbt) {
super.readEntityFromNBT(nbt);
if (nbt.hasKey("dockX")) {
mainDockingStation = (DockingStation) DockingStationRegistry.getStation(
nbt.getInteger("dockX"),
nbt.getInteger("dockY"),
nbt.getInteger("dockZ"),
ForgeDirection.values()[nbt.getInteger("dockSide")]);
}
/*
* if (nbt.hasKey("ai")) { try { nextAI = (RobotAIBase)
* Class.forName(nbt.getString("ai")).newInstance(); } catch (Throwable
* t) { t.printStackTrace(); } }
*/
laser.readFromNBT(nbt.getCompoundTag("laser"));
for (int i = 0; i < inv.length; ++i) {
inv[i] = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("inv[" + i + "]"));
}
setDead();
}
public void setMainDockingStation(DockingStation station) {
mainDockingStation = station;
}
@Override
public ItemStack getEquipmentInSlot(int var1) {
return null;
}
public boolean acceptTask (IRobotTask task) {
return false;
}
@Override
protected boolean isAIEnabled() {
return true;
}
@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
+ var2.stackSize <= inv[var1].getItem()
.getItemStackLimit());
}
@Override
public boolean isMoving() {
return motionX != 0 || motionY != 0 || motionZ != 0;
}
@Override
public void setItemInUse(ItemStack stack) {
itemInUse = stack;
RPCHandler.rpcBroadcastPlayers(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;
}
@Override
public void setHealth(float par1) {
// deactivate healh management
}
@Override
public void aimItemAt(int x, int y, int z) {
itemAngle1 = (float) Math.atan2(z - Math.floor(posZ),
x - Math.floor(posX));
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;
}
}
updateDataServer();
}
@Override
public void setItemActive(boolean isActive) {
RPCHandler.rpcBroadcastPlayers(worldObj, this, "rpcSetItemActive", isActive);
}
@RPC(RPCSide.CLIENT)
private void rpcSetItemActive(boolean isActive) {
itemActive = isActive;
itemActiveStage = 0;
lastUpdateTime = new Date().getTime();
}
@Override
public void setCurrentDockingStation(IDockingStation station) {
if (currentDockingStation != null) {
currentDockingStation.reserved = null;
}
currentDockingStation = (DockingStation) station;
if (currentDockingStation != null) {
currentDockingStation.reserved = this;
}
}
@Override
public ItemStack getItemInUse() {
return itemInUse;
}
@Override
public RedstoneBoardRobot getBoard() {
return board;
}
@Override
public DockingStation getCurrentDockingStation() {
return currentDockingStation;
}
@Override
public DockingStation getMainDockingStation() {
return mainDockingStation;
}
@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;
}
}