mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
485 lines
14 KiB
Java
485 lines
14 KiB
Java
package com.hbm.tileentity.machine;
|
|
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
|
|
import com.hbm.blocks.BlockDummyable;
|
|
import com.hbm.blocks.ModBlocks;
|
|
import com.hbm.inventory.UpgradeManager;
|
|
import com.hbm.inventory.container.ContainerAssemfac;
|
|
import com.hbm.inventory.fluid.Fluids;
|
|
import com.hbm.inventory.fluid.tank.FluidTank;
|
|
import com.hbm.inventory.gui.GUIAssemfac;
|
|
import com.hbm.items.machine.ItemMachineUpgrade;
|
|
import com.hbm.items.machine.ItemMachineUpgrade.UpgradeType;
|
|
import com.hbm.tileentity.IFluidCopiable;
|
|
import com.hbm.tileentity.IUpgradeInfoProvider;
|
|
import com.hbm.util.BobMathUtil;
|
|
import com.hbm.util.I18nUtil;
|
|
import com.hbm.util.fauxpointtwelve.DirPos;
|
|
|
|
import api.hbm.fluid.IFluidStandardTransceiver;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import io.netty.buffer.ByteBuf;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.inventory.Container;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.util.AxisAlignedBB;
|
|
import net.minecraft.util.EnumChatFormatting;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
|
|
public class TileEntityMachineAssemfac extends TileEntityMachineAssemblerBase implements IFluidStandardTransceiver, IUpgradeInfoProvider, IFluidCopiable {
|
|
|
|
public AssemblerArm[] arms;
|
|
|
|
public FluidTank water;
|
|
public FluidTank steam;
|
|
|
|
public TileEntityMachineAssemfac() {
|
|
super(14 * 8 + 4 + 1); //8 assembler groups with 14 slots, 4 upgrade slots, 1 battery slot
|
|
|
|
arms = new AssemblerArm[6];
|
|
for(int i = 0; i < arms.length; i++) {
|
|
arms[i] = new AssemblerArm(i % 3 == 1 ? 1 : 0); //the second of every group of three becomes a welder
|
|
}
|
|
|
|
water = new FluidTank(Fluids.WATER, 64_000);
|
|
steam = new FluidTank(Fluids.SPENTSTEAM, 64_000);
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "container.assemfac";
|
|
}
|
|
|
|
@Override
|
|
public void setInventorySlotContents(int i, ItemStack stack) {
|
|
super.setInventorySlotContents(i, stack);
|
|
|
|
if(stack != null && i >= 1 && i <= 4 && stack.getItem() instanceof ItemMachineUpgrade) {
|
|
worldObj.playSoundEffect(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, "hbm:item.upgradePlug", 1.0F, 1.0F);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity() {
|
|
super.updateEntity();
|
|
|
|
if(!worldObj.isRemote) {
|
|
|
|
if(worldObj.getTotalWorldTime() % 20 == 0) {
|
|
this.updateConnections();
|
|
}
|
|
|
|
this.speed = 100;
|
|
this.consumption = 100;
|
|
|
|
UpgradeManager.eval(slots, 1, 4);
|
|
|
|
int speedLevel = Math.min(UpgradeManager.getLevel(UpgradeType.SPEED), 6);
|
|
int powerLevel = Math.min(UpgradeManager.getLevel(UpgradeType.POWER), 3);
|
|
int overLevel = UpgradeManager.getLevel(UpgradeType.OVERDRIVE);
|
|
|
|
this.speed -= speedLevel * 15;
|
|
this.consumption += speedLevel * 300;
|
|
this.speed += powerLevel * 5;
|
|
this.consumption -= powerLevel * 30;
|
|
this.speed /= (overLevel + 1);
|
|
this.consumption *= (overLevel + 1);
|
|
|
|
for(DirPos pos : getConPos()) {
|
|
this.sendFluid(steam, worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
|
|
}
|
|
|
|
this.networkPackNT(150);
|
|
|
|
} else {
|
|
|
|
for(AssemblerArm arm : arms) {
|
|
arm.updateInterp();
|
|
if(isProgressing) {
|
|
arm.updateArm();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void serialize(ByteBuf buf) {
|
|
super.serialize(buf);
|
|
buf.writeLong(power);
|
|
for(int i = 0; i < getRecipeCount(); i++) {
|
|
buf.writeInt(progress[i]);
|
|
buf.writeInt(maxProgress[i]);
|
|
}
|
|
buf.writeBoolean(isProgressing);
|
|
water.serialize(buf);
|
|
steam.serialize(buf);
|
|
}
|
|
|
|
@Override
|
|
public void deserialize(ByteBuf buf) {
|
|
super.deserialize(buf);
|
|
power = buf.readLong();
|
|
for(int i = 0; i < getRecipeCount(); i++) {
|
|
progress[i] = buf.readInt();
|
|
maxProgress[i] = buf.readInt();
|
|
}
|
|
isProgressing = buf.readBoolean();
|
|
water.deserialize(buf);
|
|
steam.deserialize(buf);
|
|
}
|
|
|
|
@Override
|
|
public void networkUnpack(NBTTagCompound nbt) {
|
|
super.networkUnpack(nbt);
|
|
|
|
this.power = nbt.getLong("power");
|
|
this.progress = nbt.getIntArray("progress");
|
|
this.maxProgress = nbt.getIntArray("maxProgress");
|
|
this.isProgressing = nbt.getBoolean("isProgressing");
|
|
|
|
water.readFromNBT(nbt, "w");
|
|
steam.readFromNBT(nbt, "s");
|
|
}
|
|
|
|
private int getWaterRequired() {
|
|
return 1000 / this.speed;
|
|
}
|
|
|
|
@Override
|
|
protected boolean canProcess(int index) {
|
|
return super.canProcess(index) && this.water.getFill() >= getWaterRequired() && this.steam.getFill() + getWaterRequired() <= this.steam.getMaxFill();
|
|
}
|
|
|
|
@Override
|
|
protected void process(int index) {
|
|
super.process(index);
|
|
this.water.setFill(this.water.getFill() - getWaterRequired());
|
|
this.steam.setFill(this.steam.getFill() + getWaterRequired());
|
|
}
|
|
|
|
private void updateConnections() {
|
|
for(DirPos pos : getConPos()) {
|
|
this.trySubscribe(worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
|
|
this.trySubscribe(water.getTankType(), worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
|
|
}
|
|
}
|
|
|
|
public DirPos[] getConPos() {
|
|
|
|
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset);
|
|
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
|
|
|
|
return new DirPos[] {
|
|
new DirPos(xCoord - dir.offsetX * 3 + rot.offsetX * 5, yCoord, zCoord - dir.offsetZ * 3 + rot.offsetZ * 5, rot),
|
|
new DirPos(xCoord + dir.offsetX * 2 + rot.offsetX * 5, yCoord, zCoord + dir.offsetZ * 2 + rot.offsetZ * 5, rot),
|
|
new DirPos(xCoord - dir.offsetX * 3 - rot.offsetX * 4, yCoord, zCoord - dir.offsetZ * 3 - rot.offsetZ * 4, rot.getOpposite()),
|
|
new DirPos(xCoord + dir.offsetX * 2 - rot.offsetX * 4, yCoord, zCoord + dir.offsetZ * 2 - rot.offsetZ * 4, rot.getOpposite()),
|
|
new DirPos(xCoord - dir.offsetX * 5 + rot.offsetX * 3, yCoord, zCoord - dir.offsetZ * 5 + rot.offsetZ * 3, dir.getOpposite()),
|
|
new DirPos(xCoord - dir.offsetX * 5 - rot.offsetX * 2, yCoord, zCoord - dir.offsetZ * 5 - rot.offsetZ * 2, dir.getOpposite()),
|
|
new DirPos(xCoord + dir.offsetX * 4 + rot.offsetX * 3, yCoord, zCoord + dir.offsetZ * 4 + rot.offsetZ * 3, dir),
|
|
new DirPos(xCoord + dir.offsetX * 4 - rot.offsetX * 2, yCoord, zCoord + dir.offsetZ * 4 - rot.offsetZ * 2, dir)
|
|
};
|
|
}
|
|
|
|
public static class AssemblerArm {
|
|
public double[] angles = new double[4];
|
|
public double[] prevAngles = new double[4];
|
|
public double[] targetAngles = new double[4];
|
|
public double[] speed = new double[4];
|
|
|
|
Random rand = new Random();
|
|
|
|
int actionMode;
|
|
ArmActionState state;
|
|
int actionDelay = 0;
|
|
|
|
public AssemblerArm(int actionMode) {
|
|
this.actionMode = actionMode;
|
|
|
|
if(this.actionMode == 0) {
|
|
speed[0] = 15; //Pivot
|
|
speed[1] = 15; //Arm
|
|
speed[2] = 15; //Piston
|
|
speed[3] = 0.5; //Striker
|
|
} else if(this.actionMode == 1) {
|
|
speed[0] = 3; //Pivot
|
|
speed[1] = 3; //Arm
|
|
speed[2] = 1; //Piston
|
|
speed[3] = 0.125; //Striker
|
|
}
|
|
|
|
state = ArmActionState.ASSUME_POSITION;
|
|
chooseNewArmPoistion();
|
|
actionDelay = rand.nextInt(20);
|
|
}
|
|
|
|
public void updateArm() {
|
|
|
|
if(actionDelay > 0) {
|
|
actionDelay--;
|
|
return;
|
|
}
|
|
|
|
switch(state) {
|
|
//Move. If done moving, set a delay and progress to EXTEND
|
|
case ASSUME_POSITION:
|
|
if(move()) {
|
|
if(this.actionMode == 0) {
|
|
actionDelay = 2;
|
|
} else if(this.actionMode == 1) {
|
|
actionDelay = 10;
|
|
}
|
|
state = ArmActionState.EXTEND_STRIKER;
|
|
targetAngles[3] = 1D;
|
|
}
|
|
break;
|
|
case EXTEND_STRIKER:
|
|
if(move()) {
|
|
if(this.actionMode == 0) {
|
|
state = ArmActionState.RETRACT_STRIKER;
|
|
targetAngles[3] = 0D;
|
|
} else if(this.actionMode == 1) {
|
|
state = ArmActionState.WELD;
|
|
targetAngles[2] -= 20;
|
|
actionDelay = 5 + rand.nextInt(5);
|
|
}
|
|
}
|
|
break;
|
|
case WELD:
|
|
if(move()) {
|
|
state = ArmActionState.RETRACT_STRIKER;
|
|
targetAngles[3] = 0D;
|
|
actionDelay = 10 + rand.nextInt(5);
|
|
}
|
|
break;
|
|
case RETRACT_STRIKER:
|
|
if(move()) {
|
|
if(this.actionMode == 0) {
|
|
actionDelay = 2 + rand.nextInt(5);
|
|
} else if(this.actionMode == 1) {
|
|
actionDelay = 5 + rand.nextInt(3);
|
|
}
|
|
chooseNewArmPoistion();
|
|
state = ArmActionState.ASSUME_POSITION;
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
public void chooseNewArmPoistion() {
|
|
|
|
if(this.actionMode == 0) {
|
|
targetAngles[0] = -rand.nextInt(50); //Pivot
|
|
targetAngles[1] = -targetAngles[0]; //Arm
|
|
targetAngles[2] = rand.nextInt(30) - 15; //Piston
|
|
} else if(this.actionMode == 1) {
|
|
targetAngles[0] = -rand.nextInt(30) + 10; //Pivot
|
|
targetAngles[1] = -targetAngles[0]; //Arm
|
|
targetAngles[2] = rand.nextInt(10) + 10; //Piston
|
|
}
|
|
}
|
|
|
|
private void updateInterp() {
|
|
for(int i = 0; i < angles.length; i++) {
|
|
prevAngles[i] = angles[i];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return True when it has finished moving
|
|
*/
|
|
private boolean move() {
|
|
boolean didMove = false;
|
|
|
|
for(int i = 0; i < angles.length; i++) {
|
|
if(angles[i] == targetAngles[i])
|
|
continue;
|
|
|
|
didMove = true;
|
|
|
|
double angle = angles[i];
|
|
double target = targetAngles[i];
|
|
double turn = speed[i];
|
|
double delta = Math.abs(angle - target);
|
|
|
|
if(delta <= turn) {
|
|
angles[i] = targetAngles[i];
|
|
continue;
|
|
}
|
|
|
|
if(angle < target) {
|
|
angles[i] += turn;
|
|
} else {
|
|
angles[i] -= turn;
|
|
}
|
|
}
|
|
|
|
return !didMove;
|
|
}
|
|
|
|
public static enum ArmActionState {
|
|
ASSUME_POSITION,
|
|
EXTEND_STRIKER,
|
|
WELD,
|
|
RETRACT_STRIKER
|
|
}
|
|
}
|
|
|
|
AxisAlignedBB bb = null;
|
|
|
|
@Override
|
|
public AxisAlignedBB getRenderBoundingBox() {
|
|
|
|
if(bb == null) {
|
|
bb = AxisAlignedBB.getBoundingBox(
|
|
xCoord - 5,
|
|
yCoord,
|
|
zCoord - 5,
|
|
xCoord + 5,
|
|
yCoord + 4,
|
|
zCoord + 5
|
|
);
|
|
}
|
|
|
|
return bb;
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public double getMaxRenderDistanceSquared() {
|
|
return 65536.0D;
|
|
}
|
|
|
|
@Override
|
|
public long getMaxPower() {
|
|
return 10_000_000;
|
|
}
|
|
|
|
@Override
|
|
public int getRecipeCount() {
|
|
return 8;
|
|
}
|
|
|
|
@Override
|
|
public int getTemplateIndex(int index) {
|
|
return 17 + index * 14;
|
|
}
|
|
|
|
@Override
|
|
public int[] getSlotIndicesFromIndex(int index) {
|
|
return new int[] { 5 + index * 14, 16 + index * 14, 18 + index * 14};
|
|
}
|
|
|
|
DirPos[] inpos;
|
|
DirPos[] outpos;
|
|
|
|
@Override
|
|
public DirPos[] getInputPositions() {
|
|
|
|
if(inpos != null)
|
|
return inpos;
|
|
|
|
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset);
|
|
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
|
|
|
|
inpos = new DirPos[] {
|
|
new DirPos(xCoord + dir.offsetX * 4 - rot.offsetX * 1, yCoord, zCoord + dir.offsetZ * 4 - rot.offsetZ * 1, dir),
|
|
new DirPos(xCoord - dir.offsetX * 5 + rot.offsetX * 2, yCoord, zCoord - dir.offsetZ * 5 + rot.offsetZ * 2, dir.getOpposite()),
|
|
new DirPos(xCoord - dir.offsetX * 2 - rot.offsetX * 4, yCoord, zCoord - dir.offsetZ * 2 - rot.offsetZ * 4, rot.getOpposite()),
|
|
new DirPos(xCoord + dir.offsetX * 1 + rot.offsetX * 5, yCoord, zCoord + dir.offsetZ * 1 + rot.offsetZ * 5, rot)
|
|
};
|
|
|
|
return inpos;
|
|
}
|
|
|
|
@Override
|
|
public DirPos[] getOutputPositions() {
|
|
|
|
if(outpos != null)
|
|
return outpos;
|
|
|
|
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset);
|
|
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
|
|
|
|
outpos = new DirPos[] {
|
|
new DirPos(xCoord + dir.offsetX * 4 + rot.offsetX * 2, yCoord, zCoord + dir.offsetZ * 4 + rot.offsetZ * 2, dir),
|
|
new DirPos(xCoord - dir.offsetX * 5 - rot.offsetX * 1, yCoord, zCoord - dir.offsetZ * 5 - rot.offsetZ * 1, dir.getOpposite()),
|
|
new DirPos(xCoord + dir.offsetX * 1 - rot.offsetX * 4, yCoord, zCoord + dir.offsetZ * 1 - rot.offsetZ * 4, rot.getOpposite()),
|
|
new DirPos(xCoord - dir.offsetX * 2 + rot.offsetX * 5, yCoord, zCoord - dir.offsetZ * 2 + rot.offsetZ * 5, rot)
|
|
};
|
|
|
|
return outpos;
|
|
}
|
|
|
|
@Override
|
|
public int getPowerSlot() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public FluidTank[] getSendingTanks() {
|
|
return new FluidTank[] { steam };
|
|
}
|
|
|
|
@Override
|
|
public FluidTank[] getReceivingTanks() {
|
|
return new FluidTank[] { water };
|
|
}
|
|
|
|
@Override
|
|
public FluidTank[] getAllTanks() {
|
|
return new FluidTank[] { water, steam };
|
|
}
|
|
|
|
@Override
|
|
public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
|
return new ContainerAssemfac(player.inventory, this);
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
|
return new GUIAssemfac(player.inventory, this);
|
|
}
|
|
|
|
@Override
|
|
public boolean canProvideInfo(UpgradeType type, int level, boolean extendedInfo) {
|
|
return type == UpgradeType.SPEED || type == UpgradeType.POWER || type == UpgradeType.OVERDRIVE;
|
|
}
|
|
|
|
@Override
|
|
public void provideInfo(UpgradeType type, int level, List<String> info, boolean extendedInfo) {
|
|
info.add(IUpgradeInfoProvider.getStandardLabel(ModBlocks.machine_assemfac));
|
|
if(type == UpgradeType.SPEED) {
|
|
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(this.KEY_DELAY, "-" + (level * 15) + "%"));
|
|
info.add(EnumChatFormatting.RED + I18nUtil.resolveKey(this.KEY_CONSUMPTION, "+" + (level * 300) + "%"));
|
|
}
|
|
if(type == UpgradeType.POWER) {
|
|
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(this.KEY_CONSUMPTION, "-" + (level * 30) + "%"));
|
|
info.add(EnumChatFormatting.RED + I18nUtil.resolveKey(this.KEY_DELAY, "+" + (level * 5) + "%"));
|
|
}
|
|
if(type == UpgradeType.OVERDRIVE) {
|
|
info.add((BobMathUtil.getBlink() ? EnumChatFormatting.RED : EnumChatFormatting.DARK_GRAY) + "YES");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getMaxLevel(UpgradeType type) {
|
|
if(type == UpgradeType.SPEED) return 6;
|
|
if(type == UpgradeType.POWER) return 3;
|
|
if(type == UpgradeType.OVERDRIVE) return 12;
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public FluidTank getTankToPaste() {
|
|
return null;
|
|
}
|
|
}
|