You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			237 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Java
		
	
			
		
		
	
	
			237 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Java
		
	
| package com.zivilon.cinder_loe.mixins;
 | |
| 
 | |
| import com.zivilon.cinder_loe.util.*;
 | |
| 
 | |
| 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;
 | |
| import net.minecraft.world.World;
 | |
| 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
 | |
|     public int maxHurtTime;
 | |
|     @Shadow
 | |
|     public float attackedAtYaw;
 | |
|     @Shadow
 | |
|     protected EntityPlayer attackingPlayer;
 | |
|     @Shadow
 | |
|     protected int recentlyHit;
 | |
|     @Shadow
 | |
|     public int hurtTime;
 | |
|     @Shadow
 | |
|     public float prevHealth;
 | |
|     @Shadow
 | |
|     protected float lastDamage;
 | |
|     @Shadow
 | |
|     public int maxHurtResistantTime;
 | |
|     @Shadow
 | |
|     public float limbSwingAmount;
 | |
| 
 | |
|     @Shadow
 | |
|     protected abstract float getSoundPitch();
 | |
|     @Shadow
 | |
|     protected abstract float getSoundVolume();
 | |
|     @Shadow
 | |
|     protected abstract String getHurtSound();
 | |
|     @Shadow
 | |
|     public abstract void onDeath(DamageSource source);
 | |
|     @Shadow
 | |
|     protected abstract String getDeathSound();
 | |
|     @Shadow
 | |
|     public abstract float getHealth();
 | |
|     @Shadow
 | |
|     public abstract void knockBack(Entity entity, float strength, double direction_x, double direction_z);
 | |
|     @Shadow
 | |
|     public abstract void setRevengeTarget(EntityLivingBase p_70604_1_);
 | |
|     @Shadow
 | |
|     protected abstract void damageEntity(DamageSource p_70665_1_, float p_70665_2_);
 | |
|     @Shadow
 | |
|     public abstract ItemStack getEquipmentInSlot(int p_71124_1_);
 | |
|     @Shadow
 | |
|     public abstract boolean isPotionActive(int p_82165_1_);
 | |
|     @Shadow
 | |
|     public abstract boolean isPotionActive(Potion p_70644_1_);
 | |
| 
 | |
|     public MixinEntityLivingBase(World world) {
 | |
|         super(world);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|     * @author Shinare
 | |
|     * @reason Adding damage event method
 | |
|     */
 | |
|     @Overwrite
 | |
|     public boolean attackEntityFrom(DamageSource source, float damage) {
 | |
|         if (ForgeHooks.onLivingAttack((EntityLivingBase)(Object)this, source, damage)) return false;
 | |
|         if (this.isEntityInvulnerable()) return false;
 | |
|         if (this.worldObj.isRemote) return false;
 | |
|         this.entityAge = 0;
 | |
| 
 | |
|         if (this.getHealth() <= 0.0F) return false;
 | |
|         if (source.isFireDamage() && isPotionActive(Potion.fireResistance)) return false;
 | |
| 
 | |
|         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 (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;
 | |
|                 this.prevHealth = previousHealth;
 | |
|                 this.hurtResistantTime = this.maxHurtResistantTime;
 | |
|                 this.hurtTime = this.maxHurtTime = 10;
 | |
|             } else {
 | |
|                 this.lastDamage = damage;
 | |
|                 this.prevHealth = this.getHealth();
 | |
|                 this.hurtResistantTime = this.maxHurtResistantTime;
 | |
|                 this.damageEntity(source, damage);
 | |
|                 this.hurtTime = this.maxHurtTime = 10;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         this.attackedAtYaw = 0.0F;
 | |
|         Entity entity = source.getEntity();
 | |
| 
 | |
|         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 EntityTameable) {
 | |
|                 EntityTameable entitywolf = (EntityTameable)entity;
 | |
| 
 | |
|                 if (entitywolf.isTamed()) {
 | |
|                     this.recentlyHit = 100;
 | |
|                     this.attackingPlayer = null;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (flag) {
 | |
|             this.worldObj.setEntityState((Entity)this, (byte)2);
 | |
|             if (source != DamageSource.drown)
 | |
|                 this.setBeenAttacked();
 | |
| 
 | |
|             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;
 | |
| 
 | |
|                 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 sound;
 | |
| 
 | |
|         if (getHealth() <= 0.0F) {
 | |
|             sound = getDeathSound();
 | |
| 
 | |
|             if (flag && sound != null)
 | |
|                 this.playSound(sound, getSoundVolume(), getSoundPitch());
 | |
| 
 | |
|             onDeath(source);
 | |
|         } else {
 | |
|             sound = getHurtSound();
 | |
| 
 | |
|             if (flag && sound != null)
 | |
|                 this.playSound(sound, getSoundVolume(), 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;
 | |
|     }
 | |
| 
 | |
|     @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;
 | |
|     }
 | |
| }
 |