diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java index 93fe582..a566896 100644 --- a/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinEntityLivingBase.java @@ -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 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 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; } } diff --git a/src/main/java/com/zivilon/cinder_loe/util/Utilities.java b/src/main/java/com/zivilon/cinder_loe/util/Utilities.java index 832c5f4..b64a548 100644 --- a/src/main/java/com/zivilon/cinder_loe/util/Utilities.java +++ b/src/main/java/com/zivilon/cinder_loe/util/Utilities.java @@ -10,7 +10,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.lang.reflect.Field; +import java.lang.reflect.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.UUID; @@ -153,31 +153,6 @@ public class Utilities { return builder.toString(); } - public static void dumpClass(String className, String outputFilePath, Class contextClass) { - // Convert class name to a resource path - String resourcePath = className.replace('.', '/') + ".class"; - // Use the class loader of the context class to find the resource - try (InputStream classStream = contextClass.getClassLoader().getResourceAsStream(resourcePath)) { - if (classStream == null) { - System.err.println("Class " + className + " could not be found."); - return; - } - try (OutputStream outputStream = new FileOutputStream(outputFilePath)) { - // Copy the class stream to the output file - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = classStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, bytesRead); - } - System.out.println("Dumped " + className + " to " + outputFilePath); - } catch (IOException e) { - System.err.println("Failed to write class file: " + e.getMessage()); - } - } catch (IOException e) { - System.err.println("Failed to read class file: " + e.getMessage()); - } - } - public static void writeLog(String message) { try (BufferedWriter writer = new BufferedWriter(new FileWriter("custom_log.txt", true))) { LocalDateTime now = LocalDateTime.now();