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 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; 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; } }