mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
437 lines
13 KiB
Java
437 lines
13 KiB
Java
package com.hbm.tileentity.machine;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
|
|
import com.hbm.blocks.ModBlocks;
|
|
import com.hbm.blocks.generic.BlockTallPlant.EnumTallFlower;
|
|
import com.hbm.handler.threading.PacketThreading;
|
|
import com.hbm.inventory.fluid.FluidType;
|
|
import com.hbm.inventory.fluid.Fluids;
|
|
import com.hbm.inventory.fluid.tank.FluidTank;
|
|
import com.hbm.lib.ModDamageSource;
|
|
import com.hbm.tileentity.IFluidCopiable;
|
|
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
|
import com.hbm.tileentity.IBufPacketReceiver;
|
|
import com.hbm.tileentity.TileEntityLoadedBase;
|
|
|
|
import api.hbm.fluid.IFluidStandardReceiver;
|
|
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import io.netty.buffer.ByteBuf;
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.BlockLeaves;
|
|
import net.minecraft.block.IGrowable;
|
|
import net.minecraft.block.material.Material;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.item.EntityItem;
|
|
import net.minecraft.init.Blocks;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.util.AxisAlignedBB;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.Vec3;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.IPlantable;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
|
|
public class TileEntityMachineAutosaw extends TileEntityLoadedBase implements IBufPacketReceiver, IFluidStandardReceiver, IFluidCopiable {
|
|
|
|
public static final HashSet<FluidType> acceptedFuels = new HashSet();
|
|
|
|
static {
|
|
acceptedFuels.add(Fluids.WOODOIL);
|
|
acceptedFuels.add(Fluids.ETHANOL);
|
|
acceptedFuels.add(Fluids.FISHOIL);
|
|
acceptedFuels.add(Fluids.HEAVYOIL);
|
|
}
|
|
|
|
public FluidTank tank;
|
|
|
|
public boolean isOn;
|
|
public boolean isSuspended;
|
|
private int forceSkip;
|
|
public float syncYaw;
|
|
public float rotationYaw;
|
|
public float prevRotationYaw;
|
|
public float syncPitch;
|
|
public float rotationPitch;
|
|
public float prevRotationPitch;
|
|
|
|
// 0: searching, 1: extending, 2: retracting
|
|
private int state = 0;
|
|
|
|
private int turnProgress;
|
|
|
|
public float spin;
|
|
public float lastSpin;
|
|
|
|
public TileEntityMachineAutosaw() {
|
|
this.tank = new FluidTank(Fluids.WOODOIL, 100);
|
|
}
|
|
|
|
@Override
|
|
public void updateEntity() {
|
|
|
|
if(!worldObj.isRemote) {
|
|
|
|
if(!isSuspended && worldObj.getTotalWorldTime() % 20 == 0) {
|
|
if(tank.getFill() > 0) {
|
|
tank.setFill(tank.getFill() - 1);
|
|
this.isOn = true;
|
|
} else {
|
|
this.isOn = false;
|
|
}
|
|
|
|
this.subscribeToAllAround(tank.getTankType(), this);
|
|
}
|
|
|
|
if(isOn && !isSuspended) {
|
|
Vec3 pivot = Vec3.createVectorHelper(xCoord + 0.5, yCoord + 1.75, zCoord + 0.5);
|
|
Vec3 upperArm = Vec3.createVectorHelper(0, 0, -4);
|
|
upperArm.rotateAroundX((float) Math.toRadians(80 - rotationPitch));
|
|
upperArm.rotateAroundY(-(float) Math.toRadians(rotationYaw));
|
|
Vec3 lowerArm = Vec3.createVectorHelper(0, 0, -4);
|
|
lowerArm.rotateAroundX((float) -Math.toRadians(80 - rotationPitch));
|
|
lowerArm.rotateAroundY(-(float) Math.toRadians(rotationYaw));
|
|
Vec3 armTip = Vec3.createVectorHelper(0, 0, -2);
|
|
armTip.rotateAroundY(-(float) Math.toRadians(rotationYaw));
|
|
|
|
double cX = pivot.xCoord + upperArm.xCoord + lowerArm.xCoord + armTip.xCoord;
|
|
double cY = pivot.yCoord;
|
|
double cZ = pivot.zCoord + upperArm.zCoord + lowerArm.zCoord + armTip.zCoord;
|
|
|
|
List<EntityLivingBase> affected = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(cX - 1, cY - 0.25, cZ - 1, cX + 1, cY + 0.25, cZ + 1));
|
|
|
|
for(EntityLivingBase e : affected) {
|
|
if(e.isEntityAlive() && e.attackEntityFrom(ModDamageSource.turbofan, 100)) {
|
|
worldObj.playSoundEffect(e.posX, e.posY, e.posZ, "mob.zombie.woodbreak", 2.0F, 0.95F + worldObj.rand.nextFloat() * 0.2F);
|
|
int count = Math.min((int)Math.ceil(e.getMaxHealth() / 4), 250);
|
|
NBTTagCompound data = new NBTTagCompound();
|
|
data.setString("type", "vanillaburst");
|
|
data.setInteger("count", count * 4);
|
|
data.setDouble("motion", 0.1D);
|
|
data.setString("mode", "blockdust");
|
|
data.setInteger("block", Block.getIdFromBlock(Blocks.redstone_block));
|
|
PacketThreading.createAllAroundThreadedPacket(new AuxParticlePacketNT(data, e.posX, e.posY + e.height * 0.5, e.posZ), new TargetPoint(e.dimension, e.posX, e.posY, e.posZ, 50));
|
|
}
|
|
}
|
|
|
|
if(state == 0) {
|
|
|
|
this.rotationYaw += 1;
|
|
|
|
if(this.rotationYaw >= 360) {
|
|
this.rotationYaw -= 360;
|
|
}
|
|
|
|
if(forceSkip > 0) {
|
|
forceSkip--;
|
|
} else {
|
|
final double CUT_ANGLE = Math.toRadians(5);
|
|
double rotationYawRads = Math.toRadians((rotationYaw + 270) % 360);
|
|
|
|
outer:
|
|
for(int dx = -9; dx <= 9; dx++) {
|
|
for(int dz = -9; dz <= 9; dz++) {
|
|
int sqrDst = dx * dx + dz * dz;
|
|
|
|
if(sqrDst <= 4 || sqrDst > 81)
|
|
continue;
|
|
|
|
double angle = Math.atan2(dz, dx);
|
|
double relAngle = Math.abs(angle - rotationYawRads);
|
|
relAngle = Math.abs((relAngle + Math.PI) % (2 * Math.PI) - Math.PI);
|
|
|
|
if(relAngle > CUT_ANGLE)
|
|
continue;
|
|
|
|
int x = xCoord + dx;
|
|
int y = yCoord + 1;
|
|
int z = zCoord + dz;
|
|
|
|
Block b = worldObj.getBlock(x, y, z);
|
|
if(!(b.getMaterial() == Material.wood || b.getMaterial() == Material.leaves || b.getMaterial() == Material.plants))
|
|
continue;
|
|
|
|
int meta = worldObj.getBlockMetadata(x, y, z);
|
|
if(shouldIgnore(worldObj, x, y, z, b, meta))
|
|
continue;
|
|
|
|
state = 1;
|
|
break outer;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int hitY = (int) Math.floor(cY);
|
|
int hitX0 = (int) Math.floor(cX - 0.5);
|
|
int hitZ0 = (int) Math.floor(cZ - 0.5);
|
|
int hitX1 = (int) Math.floor(cX + 0.5);
|
|
int hitZ1 = (int) Math.floor(cZ + 0.5);
|
|
|
|
this.tryInteract(hitX0, hitY, hitZ0);
|
|
this.tryInteract(hitX1, hitY, hitZ0);
|
|
this.tryInteract(hitX0, hitY, hitZ1);
|
|
this.tryInteract(hitX1, hitY, hitZ1);
|
|
|
|
if(state == 1) {
|
|
this.rotationPitch += 2;
|
|
|
|
if(this.rotationPitch > 80) {
|
|
this.rotationPitch = 80;
|
|
state = 2;
|
|
}
|
|
}
|
|
|
|
if(state == 2) {
|
|
this.rotationPitch -= 2;
|
|
|
|
if(this.rotationPitch <= 0) {
|
|
this.rotationPitch = 0;
|
|
state = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
networkPackNT(100);
|
|
} else {
|
|
|
|
this.lastSpin = this.spin;
|
|
|
|
if(isOn && !isSuspended) {
|
|
this.spin += 15F;
|
|
|
|
Vec3 vec = Vec3.createVectorHelper(0.625, 0, 1.625);
|
|
vec.rotateAroundY(-(float) Math.toRadians(rotationYaw));
|
|
|
|
worldObj.spawnParticle("smoke", xCoord + 0.5 + vec.xCoord, yCoord + 2.0625, zCoord + 0.5 + vec.zCoord, 0, 0, 0);
|
|
}
|
|
|
|
if(this.spin >= 360F) {
|
|
this.spin -= 360F;
|
|
this.lastSpin -= 360F;
|
|
}
|
|
|
|
this.prevRotationYaw = this.rotationYaw;
|
|
this.prevRotationPitch = this.rotationPitch;
|
|
|
|
if(this.turnProgress > 0) {
|
|
double d0 = MathHelper.wrapAngleTo180_double(this.syncYaw - (double) this.rotationYaw);
|
|
double d1 = MathHelper.wrapAngleTo180_double(this.syncPitch - (double) this.rotationPitch);
|
|
this.rotationYaw = (float) ((double) this.rotationYaw + d0 / (double) this.turnProgress);
|
|
this.rotationPitch = (float) ((double) this.rotationPitch + d1 / (double) this.turnProgress);
|
|
--this.turnProgress;
|
|
} else {
|
|
this.rotationYaw = this.syncYaw;
|
|
this.rotationPitch = this.syncPitch;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Anything additionally that the detector nor the blades should pick up on, like non-mature willows */
|
|
public static boolean shouldIgnore(World world, int x, int y, int z, Block b, int meta) {
|
|
if(b == ModBlocks.plant_tall) {
|
|
return meta == EnumTallFlower.CD2.ordinal() + 8 || meta == EnumTallFlower.CD3.ordinal() + 8;
|
|
}
|
|
|
|
if((b instanceof IGrowable)) {
|
|
return ((IGrowable) b).func_149851_a(world, x, y, z, world.isRemote);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected void tryInteract(int x, int y, int z) {
|
|
|
|
Block b = worldObj.getBlock(x, y, z);
|
|
int meta = worldObj.getBlockMetadata(x, y, z);
|
|
|
|
if(!shouldIgnore(worldObj, x, y, z, b, meta)) {
|
|
if(b.getMaterial() == Material.leaves || b.getMaterial() == Material.plants) {
|
|
cutCrop(x, y, z);
|
|
} else if(b.getMaterial() == Material.wood) {
|
|
fellTree(x, y, z);
|
|
if(state == 1) {
|
|
state = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return when hitting a wall
|
|
if(state == 1 && worldObj.getBlock(x, y, z).isNormalCube(worldObj, x, y, z)) {
|
|
state = 2;
|
|
forceSkip = 5;
|
|
}
|
|
}
|
|
|
|
protected void cutCrop(int x, int y, int z) {
|
|
|
|
Block soil = worldObj.getBlock(x, y - 1, z);
|
|
|
|
Block b = worldObj.getBlock(x, y, z);
|
|
int meta = worldObj.getBlockMetadata(x, y, z);
|
|
|
|
worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(b) + (meta << 12));
|
|
|
|
Block replacementBlock = Blocks.air;
|
|
int replacementMeta = 0;
|
|
|
|
if (!worldObj.isRemote && !worldObj.restoringBlockSnapshots) {
|
|
ArrayList<ItemStack> drops = b.getDrops(worldObj, x, y, z, meta, 0);
|
|
boolean replanted = false;
|
|
|
|
for (ItemStack drop : drops) {
|
|
if (!replanted && drop.getItem() instanceof IPlantable) {
|
|
IPlantable seed = (IPlantable) drop.getItem();
|
|
|
|
if(soil.canSustainPlant(worldObj, x, y - 1, z, ForgeDirection.UP, seed)) {
|
|
replacementBlock = seed.getPlant(worldObj, x, y, z);
|
|
replacementMeta = seed.getPlantMetadata(worldObj, x, y, z);
|
|
replanted = true;
|
|
drop.stackSize -= 1;
|
|
}
|
|
}
|
|
|
|
float delta = 0.7F;
|
|
double dx = (double)(worldObj.rand.nextFloat() * delta) + (double)(1.0F - delta) * 0.5D;
|
|
double dy = (double)(worldObj.rand.nextFloat() * delta) + (double)(1.0F - delta) * 0.5D;
|
|
double dz = (double)(worldObj.rand.nextFloat() * delta) + (double)(1.0F - delta) * 0.5D;
|
|
|
|
EntityItem entityItem = new EntityItem(worldObj, x + dx, y + dy, z + dz, drop);
|
|
entityItem.delayBeforeCanPickup = 10;
|
|
worldObj.spawnEntityInWorld(entityItem);
|
|
}
|
|
|
|
// Apparently, until 1.14 full-grown wheat could sometimes drop no seeds at all
|
|
// This is a quick and dirty workaround for that.
|
|
if (b == Blocks.wheat && !replanted) {
|
|
replacementBlock = b;
|
|
replacementMeta = 0;
|
|
replanted = true;
|
|
}
|
|
}
|
|
|
|
worldObj.setBlock(x, y, z, replacementBlock, replacementMeta, 3);
|
|
}
|
|
|
|
protected void fellTree(int x, int y, int z) {
|
|
|
|
if(worldObj.getBlock(x, y - 1, z).getMaterial() == Material.wood) {
|
|
y--;
|
|
if(worldObj.getBlock(x, y - 2, z).getMaterial() == Material.wood) {
|
|
y--;
|
|
}
|
|
}
|
|
|
|
int meta = -1;
|
|
|
|
for(int i = y; i < y + 10; i++) {
|
|
|
|
int[][] dir = new int[][] {{0, 0}, {1, 0}, {-1, 0}, {0, 1}, {0, -1}};
|
|
|
|
for(int[] d : dir) {
|
|
Block b = worldObj.getBlock(x + d[0], i, z + d[1]);
|
|
|
|
if(b.getMaterial() == Material.wood) {
|
|
worldObj.func_147480_a(x + d[0], i, z + d[1], true);
|
|
} else if(b instanceof BlockLeaves) {
|
|
meta = worldObj.getBlockMetadata(x + d[0], i, z + d[1]) & 3;
|
|
worldObj.func_147480_a(x + d[0], i, z + d[1], true);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(meta >= 0) {
|
|
if(Blocks.sapling.canPlaceBlockAt(worldObj, x, y, z)) {
|
|
worldObj.setBlock(x, y, z, Blocks.sapling, meta, 3);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void serialize(ByteBuf buf) {
|
|
buf.writeBoolean(this.isOn);
|
|
buf.writeBoolean(this.isSuspended);
|
|
buf.writeFloat(this.rotationYaw);
|
|
buf.writeFloat(this.rotationPitch);
|
|
this.tank.serialize(buf);
|
|
}
|
|
|
|
@Override
|
|
public void deserialize(ByteBuf buf) {
|
|
this.isOn = buf.readBoolean();
|
|
this.isSuspended = buf.readBoolean();
|
|
this.syncYaw = buf.readFloat();
|
|
this.syncPitch = buf.readFloat();
|
|
this.turnProgress = 3; //use 3-ply for extra smoothness
|
|
this.tank.deserialize(buf);
|
|
}
|
|
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound nbt) {
|
|
super.readFromNBT(nbt);
|
|
this.isOn = nbt.getBoolean("isOn");
|
|
this.isSuspended = nbt.getBoolean("isSuspended");
|
|
this.forceSkip = nbt.getInteger("skip");
|
|
this.rotationYaw = nbt.getFloat("yaw");
|
|
this.rotationPitch = nbt.getFloat("pitch");
|
|
this.state = nbt.getInteger("state");
|
|
this.tank.readFromNBT(nbt, "t");
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound nbt) {
|
|
super.writeToNBT(nbt);
|
|
nbt.setBoolean("isOn", this.isOn);
|
|
nbt.setBoolean("isSuspended", this.isSuspended);
|
|
nbt.setInteger("skip", this.forceSkip);
|
|
nbt.setFloat("yaw", this.rotationYaw);
|
|
nbt.setFloat("pitch", this.rotationPitch);
|
|
nbt.setInteger("state", this.state);
|
|
tank.writeToNBT(nbt, "t");
|
|
}
|
|
|
|
@Override
|
|
public FluidTank[] getAllTanks() {
|
|
return new FluidTank[] {tank};
|
|
}
|
|
|
|
@Override
|
|
public FluidTank[] getReceivingTanks() {
|
|
return new FluidTank[] {tank};
|
|
}
|
|
|
|
AxisAlignedBB bb = null;
|
|
|
|
@Override
|
|
public AxisAlignedBB getRenderBoundingBox() {
|
|
|
|
if(bb == null) {
|
|
bb = AxisAlignedBB.getBoundingBox(
|
|
xCoord - 12,
|
|
yCoord,
|
|
zCoord - 12,
|
|
xCoord + 13,
|
|
yCoord + 10,
|
|
zCoord + 13
|
|
);
|
|
}
|
|
|
|
return bb;
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public double getMaxRenderDistanceSquared() {
|
|
return 65536.0D;
|
|
}
|
|
@Override
|
|
public FluidTank getTankToPaste() {
|
|
return tank;
|
|
}
|
|
}
|