mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
492 lines
14 KiB
Java
492 lines
14 KiB
Java
package com.hbm.entity.item;
|
|
|
|
import java.util.List;
|
|
|
|
import com.hbm.items.ModItems;
|
|
import com.hbm.util.TrackerUtil;
|
|
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.material.Material;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.EntityTrackerEntry;
|
|
import net.minecraft.entity.item.EntityBoat;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.init.Blocks;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.util.AxisAlignedBB;
|
|
import net.minecraft.util.DamageSource;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.Vec3;
|
|
import net.minecraft.world.World;
|
|
import net.minecraft.world.WorldServer;
|
|
|
|
public class EntityBoatRubber extends Entity {
|
|
|
|
private boolean isBoatEmpty;
|
|
private double speedMultiplier;
|
|
private int boatPosRotationIncrements;
|
|
private double boatX;
|
|
private double boatY;
|
|
private double boatZ;
|
|
private double boatYaw;
|
|
private double boatPitch;
|
|
@SideOnly(Side.CLIENT) private double velocityX;
|
|
@SideOnly(Side.CLIENT) private double velocityY;
|
|
@SideOnly(Side.CLIENT) private double velocityZ;
|
|
public float prevRenderYaw;
|
|
|
|
public EntityBoatRubber(World world) {
|
|
super(world);
|
|
this.isBoatEmpty = true;
|
|
this.speedMultiplier = 0.07D;
|
|
this.preventEntitySpawning = true;
|
|
this.setSize(1.5F, 0.6F);
|
|
this.yOffset = this.height / 2.0F;
|
|
}
|
|
|
|
public EntityBoatRubber(World world, double x, double y, double z) {
|
|
this(world);
|
|
this.setPosition(x, y + (double) this.yOffset, z);
|
|
this.motionX = 0.0D;
|
|
this.motionY = 0.0D;
|
|
this.motionZ = 0.0D;
|
|
this.prevPosX = x;
|
|
this.prevPosY = y;
|
|
this.prevPosZ = z;
|
|
}
|
|
|
|
protected void entityInit() {
|
|
this.dataWatcher.addObject(17, new Integer(0));
|
|
this.dataWatcher.addObject(18, new Integer(1));
|
|
this.dataWatcher.addObject(19, new Float(0.0F));
|
|
}
|
|
|
|
@Override
|
|
protected boolean canTriggerWalking() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public AxisAlignedBB getCollisionBox(Entity entity) {
|
|
return entity.boundingBox;
|
|
}
|
|
@Override
|
|
public AxisAlignedBB getBoundingBox() {
|
|
return this.boundingBox;
|
|
}
|
|
@Override
|
|
public boolean canBePushed() {
|
|
return true;
|
|
}
|
|
@Override
|
|
public double getMountedYOffset() {
|
|
return (double) this.height * 0.0D - 0.3D;
|
|
}
|
|
|
|
@Override
|
|
public boolean attackEntityFrom(DamageSource source, float amount) {
|
|
if(this.isEntityInvulnerable()) {
|
|
return false;
|
|
} else if(!this.worldObj.isRemote && !this.isDead) {
|
|
this.setForwardDirection(-this.getForwardDirection());
|
|
this.setTimeSinceHit(10);
|
|
this.setDamageTaken(this.getDamageTaken() + amount * 10.0F);
|
|
this.setBeenAttacked();
|
|
boolean hitByCreative = source.getEntity() instanceof EntityPlayer && ((EntityPlayer) source.getEntity()).capabilities.isCreativeMode;
|
|
|
|
if(hitByCreative || this.getDamageTaken() > 40.0F) {
|
|
if(this.riddenByEntity != null) {
|
|
this.riddenByEntity.mountEntity(this);
|
|
}
|
|
|
|
if(!hitByCreative) {
|
|
this.dropBoat();
|
|
}
|
|
|
|
this.setDead();
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public void performHurtAnimation() {
|
|
this.setForwardDirection(-this.getForwardDirection());
|
|
this.setTimeSinceHit(10);
|
|
this.setDamageTaken(this.getDamageTaken() * 11.0F);
|
|
}
|
|
|
|
@Override
|
|
public boolean canBeCollidedWith() {
|
|
return !this.isDead;
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int interp) {
|
|
if(this.isBoatEmpty) {
|
|
this.boatPosRotationIncrements = interp;
|
|
} else {
|
|
double d3 = x - this.posX;
|
|
double d4 = y - this.posY;
|
|
double d5 = z - this.posZ;
|
|
double d6 = d3 * d3 + d4 * d4 + d5 * d5;
|
|
|
|
if(d6 <= 1.0D) {
|
|
return;
|
|
}
|
|
|
|
this.boatPosRotationIncrements = 3;
|
|
}
|
|
|
|
this.boatX = x;
|
|
this.boatY = y;
|
|
this.boatZ = z;
|
|
this.boatYaw = (double) yaw;
|
|
this.boatPitch = (double) pitch;
|
|
this.motionX = this.velocityX;
|
|
this.motionY = this.velocityY;
|
|
this.motionZ = this.velocityZ;
|
|
}
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public void setVelocity(double x, double y, double z) {
|
|
this.velocityX = this.motionX = x;
|
|
this.velocityY = this.motionY = y;
|
|
this.velocityZ = this.motionZ = z;
|
|
}
|
|
|
|
@Override
|
|
public void onUpdate() {
|
|
super.onUpdate();
|
|
|
|
if(this.getTimeSinceHit() > 0) {
|
|
this.setTimeSinceHit(this.getTimeSinceHit() - 1);
|
|
}
|
|
|
|
if(this.getDamageTaken() > 0.0F) {
|
|
this.setDamageTaken(this.getDamageTaken() - 1.0F);
|
|
}
|
|
|
|
this.prevPosX = this.posX;
|
|
this.prevPosY = this.posY;
|
|
this.prevPosZ = this.posZ;
|
|
|
|
byte b0 = 5;
|
|
double d0 = 0.0D;
|
|
|
|
for(int i = 0; i < b0; ++i) {
|
|
double d1 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (i + 0) / (double) b0 - 0.125D;
|
|
double d3 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (i + 1) / (double) b0 - 0.125D;
|
|
AxisAlignedBB axisalignedbb = AxisAlignedBB.getBoundingBox(this.boundingBox.minX, d1, this.boundingBox.minZ, this.boundingBox.maxX, d3, this.boundingBox.maxZ);
|
|
|
|
if(this.worldObj.isAABBInMaterial(axisalignedbb, Material.water)) {
|
|
d0 += 1.0D / (double) b0;
|
|
}
|
|
}
|
|
|
|
if(this.worldObj.isRemote && this.isBoatEmpty) {
|
|
if(this.boatPosRotationIncrements > 0) {
|
|
double x = this.posX + (this.boatX - this.posX) / (double) this.boatPosRotationIncrements;
|
|
double y = this.posY + (this.boatY - this.posY) / (double) this.boatPosRotationIncrements;
|
|
double z = this.posZ + (this.boatZ - this.posZ) / (double) this.boatPosRotationIncrements;
|
|
double yaw = MathHelper.wrapAngleTo180_double(this.boatYaw - (double) this.rotationYaw);
|
|
this.rotationYaw = (float) ((double) this.rotationYaw + yaw / (double) this.boatPosRotationIncrements);
|
|
this.rotationPitch = (float) ((double) this.rotationPitch + (this.boatPitch - (double) this.rotationPitch) / (double) this.boatPosRotationIncrements);
|
|
--this.boatPosRotationIncrements;
|
|
this.setPosition(x, y, z);
|
|
|
|
} else {
|
|
double x = this.posX + this.motionX;
|
|
double y = this.posY + this.motionY;
|
|
double z = this.posZ + this.motionZ;
|
|
this.setPosition(x, y, z);
|
|
|
|
if(this.onGround) {
|
|
this.motionX *= 0.5D;
|
|
this.motionY *= 0.5D;
|
|
this.motionZ *= 0.5D;
|
|
}
|
|
|
|
this.passiveDeccelerate();
|
|
}
|
|
} else {
|
|
if(d0 < 1.0D) {
|
|
double d2 = d0 * 2.0D - 1.0D;
|
|
this.motionY += 0.04D * d2;
|
|
} else {
|
|
if(this.motionY < 0.0D) {
|
|
this.motionY /= 2.0D;
|
|
}
|
|
|
|
this.motionY += 0.007000000216066837D;
|
|
}
|
|
|
|
double prevSpeedSq = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
|
|
|
this.isAirBorne = false;
|
|
|
|
if(this.riddenByEntity != null && this.riddenByEntity instanceof EntityLivingBase) {
|
|
EntityLivingBase entitylivingbase = (EntityLivingBase) this.riddenByEntity;
|
|
|
|
if(entitylivingbase.moveForward != 0 || entitylivingbase.moveStrafing != 0) {
|
|
|
|
Vec3 dir = Vec3.createVectorHelper(0, 0, 1);
|
|
dir.rotateAroundY((float) -((this.rotationYaw + 90) * Math.PI / 180D));
|
|
this.motionX += dir.xCoord * this.speedMultiplier * entitylivingbase.moveForward * 0.05D;
|
|
this.motionZ += dir.zCoord * this.speedMultiplier * entitylivingbase.moveForward * 0.05D;
|
|
|
|
float prevYaw = this.rotationYaw;
|
|
this.rotationYaw -= entitylivingbase.moveStrafing * 3;
|
|
|
|
Vec3 newMotion = Vec3.createVectorHelper(motionX, 0, motionZ);
|
|
newMotion.rotateAroundY((float) (-(this.rotationYaw - prevYaw) * Math.PI / 180D));
|
|
this.motionX = newMotion.xCoord;
|
|
this.motionZ = newMotion.zCoord;
|
|
|
|
//HOLY HELL! if we don't shit ourselves over packets and send them at proper intervals, entities are suddenly smooth! who would have thought! mojang certainly didn't!
|
|
EntityTrackerEntry entry = TrackerUtil.getTrackerEntry((WorldServer) worldObj, this.getEntityId());
|
|
entry.lastYaw = MathHelper.floor_float(this.rotationYaw * 256.0F / 360.0F) + 10; //force-trigger rotation update
|
|
}
|
|
} else {
|
|
this.motionX *= 0.95D;
|
|
this.motionY *= 0.95D;
|
|
this.motionZ *= 0.95D;
|
|
}
|
|
|
|
double speedSq = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
|
|
|
if(speedSq > 0.5D) {
|
|
double d4 = 0.5D / speedSq;
|
|
this.motionX *= d4;
|
|
this.motionZ *= d4;
|
|
speedSq = 0.5D;
|
|
}
|
|
|
|
if(speedSq > prevSpeedSq && this.speedMultiplier < 0.5D) {
|
|
this.speedMultiplier += (0.5D - this.speedMultiplier) / 50.0D;
|
|
|
|
if(this.speedMultiplier > 0.5D) {
|
|
this.speedMultiplier = 0.5D;
|
|
}
|
|
} else {
|
|
this.speedMultiplier -= (this.speedMultiplier - 0.07D) / 35.0D;
|
|
|
|
if(this.speedMultiplier < 0.07D) {
|
|
this.speedMultiplier = 0.07D;
|
|
}
|
|
}
|
|
|
|
for(int index = 0; index < 4; ++index) {
|
|
int x = MathHelper.floor_double(this.posX + ((double) (index % 2) - 0.5D) * 0.8D);
|
|
int z = MathHelper.floor_double(this.posZ + ((double) (index / 2) - 0.5D) * 0.8D);
|
|
|
|
for(int yOff = 0; yOff < 2; ++yOff) {
|
|
int y = MathHelper.floor_double(this.posY) + yOff;
|
|
Block block = this.worldObj.getBlock(x, y, z);
|
|
|
|
if(block == Blocks.snow_layer) {
|
|
this.worldObj.setBlockToAir(x, y, z);
|
|
this.isCollidedHorizontally = false;
|
|
} else if(block == Blocks.waterlily) {
|
|
this.worldObj.func_147480_a(x, y, z, true);
|
|
this.isCollidedHorizontally = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.onGround) {
|
|
this.motionX *= 0.5D;
|
|
this.motionY *= 0.5D;
|
|
this.motionZ *= 0.5D;
|
|
}
|
|
|
|
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
|
|
|
if(this.isCollidedHorizontally && prevSpeedSq > 0.2D) {
|
|
this.motionX *= 0.25D;
|
|
this.motionY *= 0.25D;
|
|
this.motionZ *= 0.25D;
|
|
|
|
} else {
|
|
this.passiveDeccelerate();
|
|
}
|
|
|
|
this.rotationPitch = 0.0F;
|
|
|
|
if(!(this.riddenByEntity instanceof EntityLivingBase)) {
|
|
double yaw = (double) this.rotationYaw;
|
|
double deltaX = this.prevPosX - this.posX;
|
|
double deltaZ = this.prevPosZ - this.posZ;
|
|
|
|
if(deltaX * deltaX + deltaZ * deltaZ > 0.001D) {
|
|
yaw = (double) ((float) (Math.atan2(deltaZ, deltaX) * 180.0D / Math.PI));
|
|
}
|
|
|
|
double rotationSpeed = MathHelper.wrapAngleTo180_double(yaw - (double) this.rotationYaw);
|
|
|
|
if(rotationSpeed > 20.0D) {
|
|
rotationSpeed = 20.0D;
|
|
}
|
|
|
|
if(rotationSpeed < -20.0D) {
|
|
rotationSpeed = -20.0D;
|
|
}
|
|
|
|
this.rotationYaw = (float) ((double) this.rotationYaw + rotationSpeed);
|
|
}
|
|
|
|
this.setRotation(this.rotationYaw, this.rotationPitch);
|
|
|
|
if(!this.worldObj.isRemote) {
|
|
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.2D, 0.0D, 0.2D));
|
|
|
|
if(list != null && !list.isEmpty()) {
|
|
for(int k1 = 0; k1 < list.size(); ++k1) {
|
|
Entity entity = (Entity) list.get(k1);
|
|
|
|
if(entity != this.riddenByEntity && entity.canBePushed() && (entity instanceof EntityBoatRubber || entity instanceof EntityBoat)) {
|
|
entity.applyEntityCollision(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.riddenByEntity != null && this.riddenByEntity.isDead) {
|
|
this.riddenByEntity = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
double moX = this.prevPosX - this.posX;
|
|
double moZ = this.prevPosZ - this.posZ;
|
|
double prevSpeedSq = Math.sqrt(moX * moX + moZ * moZ);
|
|
|
|
if(prevSpeedSq > 0.2625D) {
|
|
double cosYaw = Math.cos(this.rotationYaw * Math.PI / 180.0D);
|
|
double sinYaw = Math.sin(this.rotationYaw * Math.PI / 180.0D);
|
|
|
|
for(double j = 0; j < 1.0D + prevSpeedSq * 60.0D; ++j) {
|
|
double offset = (double) (this.rand.nextFloat() * 2.0F - 1.0F);
|
|
double side = (double) (this.rand.nextInt(2) * 2 - 1) * 0.7D;
|
|
double magX;
|
|
double magZ;
|
|
|
|
if(this.rand.nextBoolean()) {
|
|
magX = this.posX - cosYaw * offset * 0.8D + sinYaw * side;
|
|
magZ = this.posZ - sinYaw * offset * 0.8D - cosYaw * side;
|
|
this.worldObj.spawnParticle("splash", magX, this.posY - 0.125D, magZ, moX, 0.1, moZ);
|
|
} else {
|
|
magX = this.posX + cosYaw + sinYaw * offset * 0.7D;
|
|
magZ = this.posZ + sinYaw - cosYaw * offset * 0.7D;
|
|
this.worldObj.spawnParticle("splash", magX, this.posY - 0.125D, magZ, moX, 0.1, moZ);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void passiveDeccelerate() {
|
|
this.motionX *= 0.99D;
|
|
this.motionY *= 0.95D;
|
|
this.motionZ *= 0.99D;
|
|
}
|
|
|
|
@Override
|
|
public void updateRiderPosition() {
|
|
if(this.riddenByEntity != null) {
|
|
double offX = Math.cos((double) this.rotationYaw * Math.PI / 180.0D) * 0.4D;
|
|
double offZ = Math.sin((double) this.rotationYaw * Math.PI / 180.0D) * 0.4D;
|
|
this.riddenByEntity.setPosition(this.posX + offX, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + offZ);
|
|
|
|
if(this.riddenByEntity instanceof EntityPlayer) {
|
|
EntityPlayer player = (EntityPlayer) this.riddenByEntity;
|
|
player.renderYawOffset = MathHelper.wrapAngleTo180_float(this.rotationYaw + 90F);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override protected void writeEntityToNBT(NBTTagCompound p_70014_1_) { }
|
|
@Override protected void readEntityFromNBT(NBTTagCompound p_70037_1_) { }
|
|
|
|
@Override
|
|
@SideOnly(Side.CLIENT)
|
|
public float getShadowSize() {
|
|
return 0.0F;
|
|
}
|
|
|
|
@Override
|
|
public boolean interactFirst(EntityPlayer player) {
|
|
if(this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != player) {
|
|
return true;
|
|
} else {
|
|
if(!this.worldObj.isRemote) {
|
|
player.mountEntity(this);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void updateFallState(double fall, boolean onGround) {
|
|
int x = MathHelper.floor_double(this.posX);
|
|
int y = MathHelper.floor_double(this.posY);
|
|
int z = MathHelper.floor_double(this.posZ);
|
|
|
|
if(onGround) {
|
|
if(this.fallDistance > 5.0F) {
|
|
this.fall(this.fallDistance);
|
|
|
|
if(!this.worldObj.isRemote && !this.isDead) {
|
|
this.setDead();
|
|
this.dropBoat();
|
|
}
|
|
|
|
this.fallDistance = 0.0F;
|
|
}
|
|
} else if(this.worldObj.getBlock(x, y - 1, z).getMaterial() != Material.water && fall < 0.0D) {
|
|
this.fallDistance = (float) ((double) this.fallDistance - fall);
|
|
}
|
|
}
|
|
|
|
public void dropBoat() {
|
|
this.func_145778_a(ModItems.boat_rubber, 1, 0.0F);
|
|
}
|
|
|
|
public void setDamageTaken(float amount) {
|
|
this.dataWatcher.updateObject(19, Float.valueOf(amount));
|
|
}
|
|
|
|
public float getDamageTaken() {
|
|
return this.dataWatcher.getWatchableObjectFloat(19);
|
|
}
|
|
|
|
public void setTimeSinceHit(int time) {
|
|
this.dataWatcher.updateObject(17, Integer.valueOf(time));
|
|
}
|
|
|
|
public int getTimeSinceHit() {
|
|
return this.dataWatcher.getWatchableObjectInt(17);
|
|
}
|
|
|
|
public void setForwardDirection(int dir) {
|
|
this.dataWatcher.updateObject(18, Integer.valueOf(dir));
|
|
}
|
|
|
|
public int getForwardDirection() {
|
|
return this.dataWatcher.getWatchableObjectInt(18);
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
public void setIsBoatEmpty(boolean empty) {
|
|
this.isBoatEmpty = empty;
|
|
}
|
|
}
|