package micdoodle8.mods.galacticraft.core.entities; import io.netty.buffer.ByteBuf; import micdoodle8.mods.galacticraft.api.vector.Vector3; import micdoodle8.mods.galacticraft.core.Constants; import micdoodle8.mods.galacticraft.core.GalacticraftCore; import micdoodle8.mods.galacticraft.core.network.PacketEntityUpdate; import micdoodle8.mods.galacticraft.core.network.PacketEntityUpdate.IEntityFullSync; import micdoodle8.mods.galacticraft.core.util.GCCoreUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.particle.EntityFX; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.world.World; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; public abstract class EntityAdvancedMotion extends InventoryEntity implements IControllableEntity, IEntityFullSync { protected long ticks = 0; public float currentDamage; public int timeSinceHit; public int rockDirection; public double advancedPositionX; public double advancedPositionY; public double advancedPositionZ; public double advancedYaw; public double advancedPitch; public int posRotIncrements; protected boolean lastOnGround; public EntityAdvancedMotion(World world) { super(world); this.preventEntitySpawning = true; this.ignoreFrustumCheck = true; this.isImmuneToFire = true; } public EntityAdvancedMotion(World world, double var2, double var4, double var6) { this(world); this.setPosition(var2, var4, var6); } @Override protected void entityInit() { } @Override protected boolean canTriggerWalking() { return false; } @Override public boolean canBePushed() { return false; } @Override public double getMountedYOffset() { return this.height - 1.0D; } @Override public boolean canBeCollidedWith() { return !this.isDead; } @Override public void updateRiderPosition() { if (this.riddenByEntity != null) { final double var1 = Math.cos(this.rotationYaw * Constants.RADIANS_TO_DEGREES_D + 114.8) * -0.5D; final double var3 = Math.sin(this.rotationYaw * Constants.RADIANS_TO_DEGREES_D + 114.8) * -0.5D; this.riddenByEntity.setPosition(this.posX + var1, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3); } } @Override public void setPositionRotationAndMotion(double x, double y, double z, float yaw, float pitch, double motX, double motY, double motZ, boolean onGround) { if (this.worldObj.isRemote) { this.advancedPositionX = x; this.advancedPositionY = y; this.advancedPositionZ = z; this.advancedYaw = yaw; this.advancedPitch = pitch; this.motionX = motX; this.motionY = motY; this.motionZ = motZ; this.posRotIncrements = 5; } else { this.setPosition(x, y, z); this.setRotation(yaw, pitch); this.motionX = motX; this.motionY = motY; this.motionZ = motZ; if (onGround || this.forceGroundUpdate()) { this.onGround = onGround; } } } protected boolean forceGroundUpdate() { return true; } @Override public void performHurtAnimation() { this.rockDirection = -this.rockDirection; this.timeSinceHit = 10; this.currentDamage *= 5; } @Override public boolean attackEntityFrom(DamageSource var1, float var2) { if (this.isDead || var1.equals(DamageSource.cactus) || !this.allowDamageSource(var1)) { return true; } else { Entity e = var1.getEntity(); if (this.isEntityInvulnerable(var1) || this.posY > 300 || (e instanceof EntityLivingBase && !(e instanceof EntityPlayer))) { return false; } else { this.rockDirection = -this.rockDirection; this.timeSinceHit = 10; this.currentDamage = this.currentDamage + var2 * 10; this.setBeenAttacked(); if (e instanceof EntityPlayer && ((EntityPlayer) e).capabilities.isCreativeMode) { this.currentDamage = 100; } if (this.currentDamage > 70) { if (this.riddenByEntity != null) { this.riddenByEntity.mountEntity(this); return false; } if (!this.worldObj.isRemote) { this.dropItems(); this.setDead(); } } return true; } } } public abstract List<ItemStack> getItemsDropped(); public abstract boolean shouldMove(); public abstract boolean shouldSpawnParticles(); /** * @return map of the particle vectors. Map key is the position and map * value is the motion of the particles. Each entry will be spawned * as a separate particle */ public abstract Map<Vector3, Vector3> getParticleMap(); @SideOnly(Side.CLIENT) public abstract EntityFX getParticle(Random rand, double x, double y, double z, double motX, double motY, double motZ); public abstract void tickInAir(); public abstract void tickOnGround(); public abstract void onGroundHit(); public abstract Vector3 getMotionVec(); /** * Can be called in the superclass init method * before the subclass fields have been initialised! * Therefore include null checks!!! */ public abstract ArrayList<Object> getNetworkedData(); /** * @return ticks between packets being sent to client */ public abstract int getPacketTickSpacing(); /** * @return players within this distance will recieve packets from this * entity */ public abstract double getPacketSendDistance(); public abstract void readNetworkedData(ByteBuf buffer); public abstract boolean allowDamageSource(DamageSource damageSource); public void dropItems() { if (this.getItemsDropped() == null) { return; } for (final ItemStack item : this.getItemsDropped()) { if (item != null) { this.entityDropItem(item, 0); } } } @Override public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean b) { if (this.riddenByEntity != null) { if (this.riddenByEntity instanceof EntityPlayer && FMLClientHandler.instance().getClient().thePlayer.equals(this.riddenByEntity)) { } else { this.posRotIncrements = posRotationIncrements + 5; this.advancedPositionX = x; this.advancedPositionY = y + (this.riddenByEntity == null ? 1 : 0); this.advancedPositionZ = z; this.advancedYaw = yaw; this.advancedPitch = pitch; } } } @Override public void moveEntity(double par1, double par3, double par5) { if (this.shouldMove()) { super.moveEntity(par1, par3, par5); } } public abstract boolean canSetPositionClient(); public abstract boolean shouldSendAdvancedMotionPacket(); @Override public void onUpdate() { this.ticks++; super.onUpdate(); if (this.canSetPositionClient() && this.worldObj.isRemote && (this.riddenByEntity == null || !(this.riddenByEntity instanceof EntityPlayer) || !FMLClientHandler.instance().getClient().thePlayer.equals(this.riddenByEntity))) { double x; double y; double var12; double z; if (this.posRotIncrements > 0) { x = this.posX + (this.advancedPositionX - this.posX) / this.posRotIncrements; y = this.posY + (this.advancedPositionY - this.posY) / this.posRotIncrements; z = this.posZ + (this.advancedPositionZ - this.posZ) / this.posRotIncrements; var12 = MathHelper.wrapAngleTo180_double(this.advancedYaw - this.rotationYaw); this.rotationYaw = (float) (this.rotationYaw + var12 / this.posRotIncrements); this.rotationPitch = (float) (this.rotationPitch + (this.advancedPitch - this.rotationPitch) / this.posRotIncrements); --this.posRotIncrements; this.setPosition(x, y, z); this.setRotation(this.rotationYaw, this.rotationPitch); } else { // x = this.posX + this.motionX; // y = this.posY + this.motionY; // z = this.posZ + this.motionZ; // this.setPosition(x, y, z); } } if (this.timeSinceHit > 0) { this.timeSinceHit--; } if (this.currentDamage > 0) { this.currentDamage--; } if (this.shouldSpawnParticles() && this.worldObj.isRemote) { this.spawnParticles(this.getParticleMap()); } if (this.onGround) { this.tickOnGround(); } else { this.tickInAir(); } if (this.worldObj.isRemote) { Vector3 mot = this.getMotionVec(); this.motionX = mot.x; this.motionY = mot.y; this.motionZ = mot.z; } //Necessary on both server and client to achieve a correct this.onGround setting this.moveEntity(this.motionX, this.motionY, this.motionZ); if (this.onGround && !this.lastOnGround) { this.onGroundHit(); } if (shouldSendAdvancedMotionPacket()) { if (this.worldObj.isRemote) { GalacticraftCore.packetPipeline.sendToServer(new PacketEntityUpdate(this)); } if (!this.worldObj.isRemote && this.ticks % 5 == 0) { GalacticraftCore.packetPipeline.sendToAllAround(new PacketEntityUpdate(this), new TargetPoint(GCCoreUtil.getDimensionID(this.worldObj), this.posX, this.posY, this.posZ, 50.0D)); } } this.prevPosX = this.posX; this.prevPosY = this.posY; this.prevPosZ = this.posZ; this.lastOnGround = this.onGround; } @Override public void getNetworkedData(ArrayList<Object> sendData) { sendData.addAll(this.getNetworkedData()); } @Override public void decodePacketdata(ByteBuf buffer) { this.readNetworkedData(buffer); } @SideOnly(Side.CLIENT) public void spawnParticles(Map<Vector3, Vector3> points) { for (final Entry<Vector3, Vector3> vec : points.entrySet()) { final Vector3 posVec = vec.getKey(); final Vector3 motionVec = vec.getValue(); this.spawnParticle(this.getParticle(this.rand, posVec.x, posVec.y, posVec.z, motionVec.x, motionVec.y, motionVec.z)); } } @SideOnly(Side.CLIENT) public void spawnParticle(EntityFX fx) { final Minecraft mc = FMLClientHandler.instance().getClient(); if (mc != null && mc.getRenderViewEntity() != null && mc.effectRenderer != null) { if (fx != null) { mc.effectRenderer.addEffect(fx); } } } }