package com.zivilon.cinder_loe.mixins; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Overwrite; import lotr.common.item.LOTRWeaponStats; import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.Enchantment; import lotr.common.enchant.LOTREnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.play.server.S2BPacketChangeGameState; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import java.util.List; import net.minecraft.entity.monster.EntityEnderman; @Mixin(EntityArrow.class) public abstract class MixinEntityArrow extends Entity { public MixinEntityArrow(World world) { super(world); } @Shadow public abstract void setIsCritical(boolean p_70243_1_); @Shadow public abstract boolean getIsCritical(); @Shadow private Block field_145790_g; @Shadow private int field_145791_d; @Shadow private int field_145792_e; @Shadow private int field_145789_f; @Shadow private boolean inGround; @Shadow public int arrowShake; @Shadow private int inData; @Shadow private int ticksInGround; @Shadow private int ticksInAir; @Shadow public Entity shootingEntity; @Shadow private int knockbackStrength; @Shadow private double damage; /** * @author Shinare * @reason Having full knockbackResistance attribute now negates bonus knockback as well */ @Overwrite public void onUpdate() { super.onUpdate(); EntityArrow arrow = (EntityArrow)(Object)this; if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(this.motionY, (double)f) * 180.0D / Math.PI); } Block block = this.worldObj.getBlock(this.field_145791_d, this.field_145792_e, this.field_145789_f); if (block.getMaterial() != Material.air) { block.setBlockBoundsBasedOnState(this.worldObj, this.field_145791_d, this.field_145792_e, this.field_145789_f); AxisAlignedBB axisalignedbb = block.getCollisionBoundingBoxFromPool(this.worldObj, this.field_145791_d, this.field_145792_e, this.field_145789_f); if (axisalignedbb != null && axisalignedbb.isVecInside(Vec3.createVectorHelper(this.posX, this.posY, this.posZ))) { this.inGround = true; } } if (this.arrowShake > 0) { --this.arrowShake; } if (this.inGround) { int j = this.worldObj.getBlockMetadata(this.field_145791_d, this.field_145792_e, this.field_145789_f); if (block == this.field_145790_g && j == this.inData) { ++this.ticksInGround; if (this.ticksInGround == 1200) { this.setDead(); } } else { this.inGround = false; this.motionX *= (double)(this.rand.nextFloat() * 0.2F); this.motionY *= (double)(this.rand.nextFloat() * 0.2F); this.motionZ *= (double)(this.rand.nextFloat() * 0.2F); this.ticksInGround = 0; this.ticksInAir = 0; } } else { ++this.ticksInAir; Vec3 vec31 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); Vec3 vec3 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); MovingObjectPosition movingobjectposition = this.worldObj.func_147447_a(vec31, vec3, false, true, false); vec31 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); vec3 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); if (movingobjectposition != null) { vec3 = Vec3.createVectorHelper(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); } Entity entity = null; List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); double d0 = 0.0D; int i; float f1; for (i = 0; i < list.size(); ++i) { Entity entity1 = (Entity)list.get(i); if (entity1.canBeCollidedWith() && (entity1 != this.shootingEntity || this.ticksInAir >= 5)) { f1 = 0.3F; AxisAlignedBB axisalignedbb1 = entity1.boundingBox.expand((double)f1, (double)f1, (double)f1); MovingObjectPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(vec31, vec3); if (movingobjectposition1 != null) { double d1 = vec31.distanceTo(movingobjectposition1.hitVec); if (d1 < d0 || d0 == 0.0D) { entity = entity1; d0 = d1; } } } } if (entity != null) { movingobjectposition = new MovingObjectPosition(entity); } if (movingobjectposition != null && movingobjectposition.entityHit != null && movingobjectposition.entityHit instanceof EntityPlayer) { EntityPlayer entityplayer = (EntityPlayer)movingobjectposition.entityHit; if (entityplayer.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer && !((EntityPlayer)this.shootingEntity).canAttackPlayer(entityplayer)) { movingobjectposition = null; } } float f2; float f4; if (movingobjectposition != null) { if (movingobjectposition.entityHit != null) { f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); int k = MathHelper.ceiling_double_int((double)f2 * this.damage); if (this.getIsCritical()) { k += this.rand.nextInt(k / 2 + 2); } DamageSource damagesource = null; if (this.shootingEntity == null) { damagesource = DamageSource.causeArrowDamage(arrow, this); } else { damagesource = DamageSource.causeArrowDamage(arrow, this.shootingEntity); } if (arrow.isBurning() && !(movingobjectposition.entityHit instanceof EntityEnderman)) { movingobjectposition.entityHit.setFire(5); } if (movingobjectposition.entityHit.attackEntityFrom(damagesource, (float)k)) { if (movingobjectposition.entityHit instanceof EntityLivingBase) { EntityLivingBase entitylivingbase = (EntityLivingBase)movingobjectposition.entityHit; if (!this.worldObj.isRemote) { entitylivingbase.setArrowCountInEntity(entitylivingbase.getArrowCountInEntity() + 1); } double knockback_resistance = entitylivingbase.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).getAttributeValue(); if (this.knockbackStrength > 0 && knockback_resistance < 1.0D) { f4 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); if (f4 > 0.0F) { entitylivingbase.addVelocity(this.motionX * (double)this.knockbackStrength * 0.6000000238418579D / (double)f4, 0.1D, this.motionZ * (double)this.knockbackStrength * 0.6000000238418579D / (double)f4); } } if (this.shootingEntity != null && this.shootingEntity instanceof EntityLivingBase) { EnchantmentHelper.func_151384_a(entitylivingbase, this.shootingEntity); EnchantmentHelper.func_151385_b((EntityLivingBase)this.shootingEntity, entitylivingbase); } if (this.shootingEntity != null && entitylivingbase != this.shootingEntity && entitylivingbase instanceof EntityPlayer && this.shootingEntity instanceof EntityPlayerMP) { ((EntityPlayerMP)this.shootingEntity).playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(6, 0.0F)); } } arrow.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); if (!(movingobjectposition.entityHit instanceof EntityEnderman)) { arrow.setDead(); } } else { this.motionX *= -0.10000000149011612D; this.motionY *= -0.10000000149011612D; this.motionZ *= -0.10000000149011612D; this.rotationYaw += 180.0F; this.prevRotationYaw += 180.0F; this.ticksInAir = 0; } } else { this.field_145791_d = movingobjectposition.blockX; this.field_145792_e = movingobjectposition.blockY; this.field_145789_f = movingobjectposition.blockZ; this.field_145790_g = this.worldObj.getBlock(this.field_145791_d, this.field_145792_e, this.field_145789_f); this.inData = arrow.worldObj.getBlockMetadata(this.field_145791_d, this.field_145792_e, this.field_145789_f); this.motionX = (double)((float)(movingobjectposition.hitVec.xCoord - this.posX)); this.motionY = (double)((float)(movingobjectposition.hitVec.yCoord - this.posY)); this.motionZ = (double)((float)(movingobjectposition.hitVec.zCoord - this.posZ)); f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); this.posX -= this.motionX / (double)f2 * 0.05000000074505806D; this.posY -= this.motionY / (double)f2 * 0.05000000074505806D; this.posZ -= this.motionZ / (double)f2 * 0.05000000074505806D; this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); this.inGround = true; this.arrowShake = 7; this.setIsCritical(false); if (this.field_145790_g.getMaterial() != Material.air) { this.field_145790_g.onEntityCollidedWithBlock(this.worldObj, this.field_145791_d, this.field_145792_e, this.field_145789_f, this); } } } if (arrow.getIsCritical()) { for (i = 0; i < 4; ++i) { arrow.worldObj.spawnParticle("crit", arrow.posX + arrow.motionX * (double)i / 4.0D, arrow.posY + arrow.motionY * (double)i / 4.0D, arrow.posZ + arrow.motionZ * (double)i / 4.0D, -arrow.motionX, -arrow.motionY + 0.2D, -arrow.motionZ); } } arrow.posX += arrow.motionX; arrow.posY += arrow.motionY; arrow.posZ += arrow.motionZ; f2 = MathHelper.sqrt_double(arrow.motionX * arrow.motionX + arrow.motionZ * arrow.motionZ); arrow.rotationYaw = (float)(Math.atan2(arrow.motionX, arrow.motionZ) * 180.0D / Math.PI); for (arrow.rotationPitch = (float)(Math.atan2(arrow.motionY, (double)f2) * 180.0D / Math.PI); arrow.rotationPitch - arrow.prevRotationPitch < -180.0F; arrow.prevRotationPitch -= 360.0F) { ; } while (arrow.rotationPitch - arrow.prevRotationPitch >= 180.0F) { arrow.prevRotationPitch += 360.0F; } while (arrow.rotationYaw - arrow.prevRotationYaw < -180.0F) { arrow.prevRotationYaw -= 360.0F; } while (arrow.rotationYaw - arrow.prevRotationYaw >= 180.0F) { arrow.prevRotationYaw += 360.0F; } arrow.rotationPitch = arrow.prevRotationPitch + (arrow.rotationPitch - arrow.prevRotationPitch) * 0.2F; arrow.rotationYaw = arrow.prevRotationYaw + (arrow.rotationYaw - arrow.prevRotationYaw) * 0.2F; float f3 = 0.99F; f1 = 0.05F; if (arrow.isInWater()) { for (int l = 0; l < 4; ++l) { f4 = 0.25F; arrow.worldObj.spawnParticle("bubble", arrow.posX - arrow.motionX * (double)f4, arrow.posY - arrow.motionY * (double)f4, arrow.posZ - arrow.motionZ * (double)f4, arrow.motionX, arrow.motionY, arrow.motionZ); } f3 = 0.8F; } if (arrow.isWet()) { arrow.extinguish(); } arrow.motionX *= (double)f3; arrow.motionY *= (double)f3; arrow.motionZ *= (double)f3; arrow.motionY -= (double)f1; arrow.setPosition(arrow.posX, arrow.posY, arrow.posZ); this.func_145775_I(); } } }