|  |  |  | @ -1,15 +1,15 @@ | 
		
	
		
			
				|  |  |  |  | package com.zivilon.cinder_loe.mixins; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import com.zivilon.cinder_loe.util.Pair; | 
		
	
		
			
				|  |  |  |  | import com.zivilon.cinder_loe.util.DamageEvent; | 
		
	
		
			
				|  |  |  |  | import com.zivilon.cinder_loe.util.*; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import org.spongepowered.asm.mixin.Mixin; | 
		
	
		
			
				|  |  |  |  | import org.spongepowered.asm.mixin.Shadow; | 
		
	
		
			
				|  |  |  |  | import org.spongepowered.asm.mixin.Overwrite; | 
		
	
		
			
				|  |  |  |  | import org.spongepowered.asm.mixin.*; | 
		
	
		
			
				|  |  |  |  | import org.spongepowered.asm.mixin.injection.*; | 
		
	
		
			
				|  |  |  |  | import org.spongepowered.asm.mixin.injection.callback.*; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import net.minecraft.potion.Potion; | 
		
	
		
			
				|  |  |  |  | import net.minecraft.entity.Entity; | 
		
	
		
			
				|  |  |  |  | import net.minecraft.entity.EntityLivingBase; | 
		
	
		
			
				|  |  |  |  | import net.minecraft.entity.passive.EntityTameable; | 
		
	
		
			
				|  |  |  |  | import net.minecraft.entity.player.EntityPlayer; | 
		
	
		
			
				|  |  |  |  | import net.minecraft.item.ItemStack; | 
		
	
		
			
				|  |  |  |  | import net.minecraft.util.DamageSource; | 
		
	
	
		
			
				
					|  |  |  | @ -18,10 +18,14 @@ import net.minecraft.entity.effect.EntityLightningBolt; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import net.minecraftforge.common.ForgeHooks; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import java.lang.reflect.*; | 
		
	
		
			
				|  |  |  |  | import java.util.List; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | @Mixin(EntityLivingBase.class) | 
		
	
		
			
				|  |  |  |  | public abstract class MixinEntityLivingBase extends Entity { | 
		
	
		
			
				|  |  |  |  |     private static boolean checked_cauldron = false; | 
		
	
		
			
				|  |  |  |  |     private static Method cauldron_method; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
		
			
				|  |  |  |  |     protected int entityAge; | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
	
		
			
				
					|  |  |  | @ -50,13 +54,13 @@ public abstract class MixinEntityLivingBase extends Entity { | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
		
			
				|  |  |  |  |     protected abstract String getHurtSound(); | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
		
			
				|  |  |  |  |     public abstract void onDeath(DamageSource p_70645_1_); | 
		
	
		
			
				|  |  |  |  |     public abstract void onDeath(DamageSource source); | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
		
			
				|  |  |  |  |     protected abstract String getDeathSound(); | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
		
			
				|  |  |  |  |     public abstract float getHealth(); | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
		
			
				|  |  |  |  |     public abstract void knockBack(Entity p_70653_1_, float p_70653_2_, double p_70653_3_, double p_70653_5_); | 
		
	
		
			
				|  |  |  |  |     public abstract void knockBack(Entity entity, float strength, double direction_x, double direction_z); | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
		
			
				|  |  |  |  |     public abstract void setRevengeTarget(EntityLivingBase p_70604_1_); | 
		
	
		
			
				|  |  |  |  |     @Shadow | 
		
	
	
		
			
				
					|  |  |  | @ -79,40 +83,53 @@ public abstract class MixinEntityLivingBase extends Entity { | 
		
	
		
			
				|  |  |  |  |     @Overwrite | 
		
	
		
			
				|  |  |  |  |     public boolean attackEntityFrom(DamageSource source, float damage) { | 
		
	
		
			
				|  |  |  |  |         if (ForgeHooks.onLivingAttack((EntityLivingBase)(Object)this, source, damage)) return false; | 
		
	
		
			
				|  |  |  |  |         if (this.isEntityInvulnerable()) { | 
		
	
		
			
				|  |  |  |  |             return false; | 
		
	
		
			
				|  |  |  |  |         } else if (this.worldObj.isRemote) { | 
		
	
		
			
				|  |  |  |  |             return false; | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
		
			
				|  |  |  |  |             this.entityAge = 0; | 
		
	
		
			
				|  |  |  |  |         if (this.isEntityInvulnerable()) return false; | 
		
	
		
			
				|  |  |  |  |         if (this.worldObj.isRemote) return false; | 
		
	
		
			
				|  |  |  |  |         this.entityAge = 0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (this.getHealth() <= 0.0F) { | 
		
	
		
			
				|  |  |  |  |                 return false; | 
		
	
		
			
				|  |  |  |  |             } else if (source.isFireDamage() && this.isPotionActive(Potion.fireResistance)) { | 
		
	
		
			
				|  |  |  |  |                 return false; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         if (this.getHealth() <= 0.0F) return false; | 
		
	
		
			
				|  |  |  |  |         if (source.isFireDamage() && isPotionActive(Potion.fireResistance)) return false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             DamageEvent event = new DamageEvent(source, damage, (EntityLivingBase)(Object)this, source.getEntity()); | 
		
	
		
			
				|  |  |  |  |             Pair<DamageEvent, Boolean> result = DamageEvent.run_events(event); | 
		
	
		
			
				|  |  |  |  |             if (result.value) return false; | 
		
	
		
			
				|  |  |  |  |             damage = result.key.damage; | 
		
	
		
			
				|  |  |  |  |         if (!(checked_cauldron)) { | 
		
	
		
			
				|  |  |  |  |             check_cauldron(); | 
		
	
		
			
				|  |  |  |  |             checked_cauldron = true; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         DamageEvent event = new DamageEvent(source, damage, (EntityLivingBase)(Object)this, source.getEntity()); | 
		
	
		
			
				|  |  |  |  |         Pair<DamageEvent, Boolean> result = DamageEvent.run_events(event); | 
		
	
		
			
				|  |  |  |  |         if (result.value) return false; | 
		
	
		
			
				|  |  |  |  |         damage = result.key.damage; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (cauldron_method == null) { | 
		
	
		
			
				|  |  |  |  |             if ((source == DamageSource.anvil || source == DamageSource.fallingBlock) && this.getEquipmentInSlot(4) != null) { | 
		
	
		
			
				|  |  |  |  |                 this.getEquipmentInSlot(4).damageItem((int)(damage * 4.0F + this.rand.nextFloat() * damage * 2.0F), (EntityLivingBase)(Object)this); | 
		
	
		
			
				|  |  |  |  |                 damage *= 0.75F; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             this.limbSwingAmount = 1.5F; | 
		
	
		
			
				|  |  |  |  |             boolean flag = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if ((float)this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F) { | 
		
	
		
			
				|  |  |  |  |                 if (damage <= this.lastDamage) { | 
		
	
		
			
				|  |  |  |  |                     return false; | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |         this.limbSwingAmount = 1.5F; | 
		
	
		
			
				|  |  |  |  |         boolean flag = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F) { | 
		
	
		
			
				|  |  |  |  |             if (damage <= this.lastDamage) return false; | 
		
	
		
			
				|  |  |  |  |             if (cauldron_method != null) { | 
		
	
		
			
				|  |  |  |  |                 boolean cauldron_cancel = entitydamage_cauldron(source, damage - this.lastDamage); | 
		
	
		
			
				|  |  |  |  |                 if (!cauldron_cancel) return false; | 
		
	
		
			
				|  |  |  |  |             } else { | 
		
	
		
			
				|  |  |  |  |                 this.damageEntity(source, damage - this.lastDamage); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             this.lastDamage = damage; | 
		
	
		
			
				|  |  |  |  |             flag = false; | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
		
			
				|  |  |  |  |             if (cauldron_method != null) { | 
		
	
		
			
				|  |  |  |  |                 float previousHealth = getHealth(); | 
		
	
		
			
				|  |  |  |  |                 boolean cauldron_cancel = entitydamage_cauldron(source, damage); | 
		
	
		
			
				|  |  |  |  |                 if (!cauldron_cancel) return false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 this.lastDamage = damage; | 
		
	
		
			
				|  |  |  |  |                 flag = false; | 
		
	
		
			
				|  |  |  |  |                 this.prevHealth = previousHealth; | 
		
	
		
			
				|  |  |  |  |                 this.hurtResistantTime = this.maxHurtResistantTime; | 
		
	
		
			
				|  |  |  |  |                 this.hurtTime = this.maxHurtTime = 10; | 
		
	
		
			
				|  |  |  |  |             } else { | 
		
	
		
			
				|  |  |  |  |                 this.lastDamage = damage; | 
		
	
		
			
				|  |  |  |  |                 this.prevHealth = this.getHealth(); | 
		
	
	
		
			
				
					|  |  |  | @ -120,69 +137,100 @@ public abstract class MixinEntityLivingBase extends Entity { | 
		
	
		
			
				|  |  |  |  |                 this.damageEntity(source, damage); | 
		
	
		
			
				|  |  |  |  |                 this.hurtTime = this.maxHurtTime = 10; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             this.attackedAtYaw = 0.0F; | 
		
	
		
			
				|  |  |  |  |             Entity entity = source.getEntity(); | 
		
	
		
			
				|  |  |  |  |         this.attackedAtYaw = 0.0F; | 
		
	
		
			
				|  |  |  |  |         Entity entity = source.getEntity(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (entity != null) { | 
		
	
		
			
				|  |  |  |  |                 if (entity instanceof EntityLivingBase) { | 
		
	
		
			
				|  |  |  |  |                     this.setRevengeTarget((EntityLivingBase)entity); | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |         if (entity != null) { | 
		
	
		
			
				|  |  |  |  |             if (entity instanceof EntityLivingBase) | 
		
	
		
			
				|  |  |  |  |                 this.setRevengeTarget((EntityLivingBase)entity); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 if (entity instanceof EntityPlayer) { | 
		
	
		
			
				|  |  |  |  |                     this.recentlyHit = 100; | 
		
	
		
			
				|  |  |  |  |                     this.attackingPlayer = (EntityPlayer)entity; | 
		
	
		
			
				|  |  |  |  |                 } else if (entity instanceof net.minecraft.entity.passive.EntityTameable) { | 
		
	
		
			
				|  |  |  |  |                     net.minecraft.entity.passive.EntityTameable entitywolf = (net.minecraft.entity.passive.EntityTameable)entity; | 
		
	
		
			
				|  |  |  |  |             if (entity instanceof EntityPlayer) { | 
		
	
		
			
				|  |  |  |  |                 this.recentlyHit = 100; | 
		
	
		
			
				|  |  |  |  |                 this.attackingPlayer = (EntityPlayer)entity; | 
		
	
		
			
				|  |  |  |  |             } else if (entity instanceof EntityTameable) { | 
		
	
		
			
				|  |  |  |  |                 EntityTameable entitywolf = (EntityTameable)entity; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                     if (entitywolf.isTamed()) { | 
		
	
		
			
				|  |  |  |  |                         this.recentlyHit = 100; | 
		
	
		
			
				|  |  |  |  |                         this.attackingPlayer = null; | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 if (entitywolf.isTamed()) { | 
		
	
		
			
				|  |  |  |  |                     this.recentlyHit = 100; | 
		
	
		
			
				|  |  |  |  |                     this.attackingPlayer = null; | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (flag) { | 
		
	
		
			
				|  |  |  |  |                 this.worldObj.setEntityState(this, (byte)2); | 
		
	
		
			
				|  |  |  |  |         if (flag) { | 
		
	
		
			
				|  |  |  |  |             this.worldObj.setEntityState((Entity)this, (byte)2); | 
		
	
		
			
				|  |  |  |  |             if (source != DamageSource.drown) | 
		
	
		
			
				|  |  |  |  |                 this.setBeenAttacked(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 if (source != DamageSource.drown) { | 
		
	
		
			
				|  |  |  |  |                     this.setBeenAttacked(); | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 if (entity != null) { | 
		
	
		
			
				|  |  |  |  |                     double d1 = entity.posX - this.posX; | 
		
	
		
			
				|  |  |  |  |                     double d0; | 
		
	
		
			
				|  |  |  |  |             if (entity != null) { | 
		
	
		
			
				|  |  |  |  |                 double d1 = entity.posX - this.posX; | 
		
	
		
			
				|  |  |  |  |                 double d0; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                     for (d0 = entity.posZ - this.posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) { | 
		
	
		
			
				|  |  |  |  |                         d1 = (Math.random() - Math.random()) * 0.01D; | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 for (d0 = entity.posZ - this.posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) | 
		
	
		
			
				|  |  |  |  |                     d1 = (Math.random() - Math.random()) * 0.01D; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                     this.attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - this.rotationYaw; | 
		
	
		
			
				|  |  |  |  |                     this.knockBack(entity, damage, d1, d0); | 
		
	
		
			
				|  |  |  |  |                 } else { | 
		
	
		
			
				|  |  |  |  |                     this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180); | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |                 this.attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - this.rotationYaw; | 
		
	
		
			
				|  |  |  |  |                 this.knockBack(entity, damage, d1, d0); | 
		
	
		
			
				|  |  |  |  |             } else { | 
		
	
		
			
				|  |  |  |  |                 this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             String s; | 
		
	
		
			
				|  |  |  |  |         String sound; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (this.getHealth() <= 0.0F) { | 
		
	
		
			
				|  |  |  |  |                 s = this.getDeathSound(); | 
		
	
		
			
				|  |  |  |  |         if (getHealth() <= 0.0F) { | 
		
	
		
			
				|  |  |  |  |             sound = getDeathSound(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 if (flag && s != null) { | 
		
	
		
			
				|  |  |  |  |                     this.playSound(s, this.getSoundVolume(), this.getSoundPitch()); | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             if (flag && sound != null) | 
		
	
		
			
				|  |  |  |  |                 this.playSound(sound, getSoundVolume(), getSoundPitch()); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 this.onDeath(source); | 
		
	
		
			
				|  |  |  |  |             } else { | 
		
	
		
			
				|  |  |  |  |                 s = this.getHurtSound(); | 
		
	
		
			
				|  |  |  |  |             onDeath(source); | 
		
	
		
			
				|  |  |  |  |         } else { | 
		
	
		
			
				|  |  |  |  |             sound = getHurtSound(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if (flag && sound != null) | 
		
	
		
			
				|  |  |  |  |                 this.playSound(sound, getSoundVolume(), getSoundPitch()); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 if (flag && s != null) { | 
		
	
		
			
				|  |  |  |  |                     this.playSound(s, this.getSoundVolume(), this.getSoundPitch()); | 
		
	
		
			
				|  |  |  |  |         return true; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     @Dynamic | 
		
	
		
			
				|  |  |  |  |     private void check_cauldron() { | 
		
	
		
			
				|  |  |  |  |         try { | 
		
	
		
			
				|  |  |  |  |             Class<?> target_class = EntityLivingBase.class; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             while (target_class != null) { | 
		
	
		
			
				|  |  |  |  |                 Method[] methods = target_class.getDeclaredMethods(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 for (Method method : methods) { | 
		
	
		
			
				|  |  |  |  |                     if (method.getName().equals("damageEntity_CB")) { | 
		
	
		
			
				|  |  |  |  |                         cauldron_method = method; | 
		
	
		
			
				|  |  |  |  |                         return; | 
		
	
		
			
				|  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } catch (Exception e) { | 
		
	
		
			
				|  |  |  |  |             e.printStackTrace(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             return true; | 
		
	
		
			
				|  |  |  |  |     @Dynamic | 
		
	
		
			
				|  |  |  |  |     public boolean entitydamage_cauldron(DamageSource source, float damage) { | 
		
	
		
			
				|  |  |  |  |         boolean return_value = true; | 
		
	
		
			
				|  |  |  |  |         if (cauldron_method != null) { | 
		
	
		
			
				|  |  |  |  |             try { | 
		
	
		
			
				|  |  |  |  |                 Object result = cauldron_method.invoke(this, source, damage); | 
		
	
		
			
				|  |  |  |  |                 if (result instanceof Boolean) {  // Check if the result is a boolean
 | 
		
	
		
			
				|  |  |  |  |                     return_value = (Boolean) result; | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |             } catch (IllegalAccessException | InvocationTargetException e) { | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         return return_value; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | 
 |