|
|
|
@ -1,15 +1,15 @@
|
|
|
|
package com.zivilon.cinder_loe.mixins;
|
|
|
|
package com.zivilon.cinder_loe.mixins;
|
|
|
|
|
|
|
|
|
|
|
|
import com.zivilon.cinder_loe.util.Pair;
|
|
|
|
import com.zivilon.cinder_loe.util.*;
|
|
|
|
import com.zivilon.cinder_loe.util.DamageEvent;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.spongepowered.asm.mixin.Mixin;
|
|
|
|
import org.spongepowered.asm.mixin.*;
|
|
|
|
import org.spongepowered.asm.mixin.Shadow;
|
|
|
|
import org.spongepowered.asm.mixin.injection.*;
|
|
|
|
import org.spongepowered.asm.mixin.Overwrite;
|
|
|
|
import org.spongepowered.asm.mixin.injection.callback.*;
|
|
|
|
|
|
|
|
|
|
|
|
import net.minecraft.potion.Potion;
|
|
|
|
import net.minecraft.potion.Potion;
|
|
|
|
import net.minecraft.entity.Entity;
|
|
|
|
import net.minecraft.entity.Entity;
|
|
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
|
|
|
|
|
|
import net.minecraft.entity.passive.EntityTameable;
|
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
|
|
import net.minecraft.item.ItemStack;
|
|
|
|
import net.minecraft.item.ItemStack;
|
|
|
|
import net.minecraft.util.DamageSource;
|
|
|
|
import net.minecraft.util.DamageSource;
|
|
|
|
@ -18,10 +18,14 @@ import net.minecraft.entity.effect.EntityLightningBolt;
|
|
|
|
|
|
|
|
|
|
|
|
import net.minecraftforge.common.ForgeHooks;
|
|
|
|
import net.minecraftforge.common.ForgeHooks;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.*;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
@Mixin(EntityLivingBase.class)
|
|
|
|
@Mixin(EntityLivingBase.class)
|
|
|
|
public abstract class MixinEntityLivingBase extends Entity {
|
|
|
|
public abstract class MixinEntityLivingBase extends Entity {
|
|
|
|
|
|
|
|
private static boolean checked_cauldron = false;
|
|
|
|
|
|
|
|
private static Method cauldron_method;
|
|
|
|
|
|
|
|
|
|
|
|
@Shadow
|
|
|
|
@Shadow
|
|
|
|
protected int entityAge;
|
|
|
|
protected int entityAge;
|
|
|
|
@Shadow
|
|
|
|
@Shadow
|
|
|
|
@ -50,13 +54,13 @@ public abstract class MixinEntityLivingBase extends Entity {
|
|
|
|
@Shadow
|
|
|
|
@Shadow
|
|
|
|
protected abstract String getHurtSound();
|
|
|
|
protected abstract String getHurtSound();
|
|
|
|
@Shadow
|
|
|
|
@Shadow
|
|
|
|
public abstract void onDeath(DamageSource p_70645_1_);
|
|
|
|
public abstract void onDeath(DamageSource source);
|
|
|
|
@Shadow
|
|
|
|
@Shadow
|
|
|
|
protected abstract String getDeathSound();
|
|
|
|
protected abstract String getDeathSound();
|
|
|
|
@Shadow
|
|
|
|
@Shadow
|
|
|
|
public abstract float getHealth();
|
|
|
|
public abstract float getHealth();
|
|
|
|
@Shadow
|
|
|
|
@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
|
|
|
|
@Shadow
|
|
|
|
public abstract void setRevengeTarget(EntityLivingBase p_70604_1_);
|
|
|
|
public abstract void setRevengeTarget(EntityLivingBase p_70604_1_);
|
|
|
|
@Shadow
|
|
|
|
@Shadow
|
|
|
|
@ -79,40 +83,53 @@ public abstract class MixinEntityLivingBase extends Entity {
|
|
|
|
@Overwrite
|
|
|
|
@Overwrite
|
|
|
|
public boolean attackEntityFrom(DamageSource source, float damage) {
|
|
|
|
public boolean attackEntityFrom(DamageSource source, float damage) {
|
|
|
|
if (ForgeHooks.onLivingAttack((EntityLivingBase)(Object)this, source, damage)) return false;
|
|
|
|
if (ForgeHooks.onLivingAttack((EntityLivingBase)(Object)this, source, damage)) return false;
|
|
|
|
if (this.isEntityInvulnerable()) {
|
|
|
|
if (this.isEntityInvulnerable()) return false;
|
|
|
|
return false;
|
|
|
|
if (this.worldObj.isRemote) return false;
|
|
|
|
} else if (this.worldObj.isRemote) {
|
|
|
|
this.entityAge = 0;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
this.entityAge = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.getHealth() <= 0.0F) {
|
|
|
|
if (this.getHealth() <= 0.0F) return false;
|
|
|
|
return false;
|
|
|
|
if (source.isFireDamage() && isPotionActive(Potion.fireResistance)) return false;
|
|
|
|
} else if (source.isFireDamage() && this.isPotionActive(Potion.fireResistance)) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DamageEvent event = new DamageEvent(source, damage, (EntityLivingBase)(Object)this, source.getEntity());
|
|
|
|
if (!(checked_cauldron)) {
|
|
|
|
Pair<DamageEvent, Boolean> result = DamageEvent.run_events(event);
|
|
|
|
check_cauldron();
|
|
|
|
if (result.value) return false;
|
|
|
|
checked_cauldron = true;
|
|
|
|
damage = result.key.damage;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
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);
|
|
|
|
this.getEquipmentInSlot(4).damageItem((int)(damage * 4.0F + this.rand.nextFloat() * damage * 2.0F), (EntityLivingBase)(Object)this);
|
|
|
|
damage *= 0.75F;
|
|
|
|
damage *= 0.75F;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.limbSwingAmount = 1.5F;
|
|
|
|
this.limbSwingAmount = 1.5F;
|
|
|
|
boolean flag = true;
|
|
|
|
boolean flag = true;
|
|
|
|
|
|
|
|
|
|
|
|
if ((float)this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F) {
|
|
|
|
|
|
|
|
if (damage <= this.lastDamage) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.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.lastDamage = damage;
|
|
|
|
flag = false;
|
|
|
|
this.prevHealth = previousHealth;
|
|
|
|
|
|
|
|
this.hurtResistantTime = this.maxHurtResistantTime;
|
|
|
|
|
|
|
|
this.hurtTime = this.maxHurtTime = 10;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
this.lastDamage = damage;
|
|
|
|
this.lastDamage = damage;
|
|
|
|
this.prevHealth = this.getHealth();
|
|
|
|
this.prevHealth = this.getHealth();
|
|
|
|
@ -120,69 +137,100 @@ public abstract class MixinEntityLivingBase extends Entity {
|
|
|
|
this.damageEntity(source, damage);
|
|
|
|
this.damageEntity(source, damage);
|
|
|
|
this.hurtTime = this.maxHurtTime = 10;
|
|
|
|
this.hurtTime = this.maxHurtTime = 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.attackedAtYaw = 0.0F;
|
|
|
|
this.attackedAtYaw = 0.0F;
|
|
|
|
Entity entity = source.getEntity();
|
|
|
|
Entity entity = source.getEntity();
|
|
|
|
|
|
|
|
|
|
|
|
if (entity != null) {
|
|
|
|
if (entity != null) {
|
|
|
|
if (entity instanceof EntityLivingBase) {
|
|
|
|
if (entity instanceof EntityLivingBase)
|
|
|
|
this.setRevengeTarget((EntityLivingBase)entity);
|
|
|
|
this.setRevengeTarget((EntityLivingBase)entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (entity instanceof EntityPlayer) {
|
|
|
|
if (entity instanceof EntityPlayer) {
|
|
|
|
this.recentlyHit = 100;
|
|
|
|
this.recentlyHit = 100;
|
|
|
|
this.attackingPlayer = (EntityPlayer)entity;
|
|
|
|
this.attackingPlayer = (EntityPlayer)entity;
|
|
|
|
} else if (entity instanceof net.minecraft.entity.passive.EntityTameable) {
|
|
|
|
} else if (entity instanceof EntityTameable) {
|
|
|
|
net.minecraft.entity.passive.EntityTameable entitywolf = (net.minecraft.entity.passive.EntityTameable)entity;
|
|
|
|
EntityTameable entitywolf = (EntityTameable)entity;
|
|
|
|
|
|
|
|
|
|
|
|
if (entitywolf.isTamed()) {
|
|
|
|
if (entitywolf.isTamed()) {
|
|
|
|
this.recentlyHit = 100;
|
|
|
|
this.recentlyHit = 100;
|
|
|
|
this.attackingPlayer = null;
|
|
|
|
this.attackingPlayer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (flag) {
|
|
|
|
if (flag) {
|
|
|
|
this.worldObj.setEntityState(this, (byte)2);
|
|
|
|
this.worldObj.setEntityState((Entity)this, (byte)2);
|
|
|
|
|
|
|
|
if (source != DamageSource.drown)
|
|
|
|
|
|
|
|
this.setBeenAttacked();
|
|
|
|
|
|
|
|
|
|
|
|
if (source != DamageSource.drown) {
|
|
|
|
if (entity != null) {
|
|
|
|
this.setBeenAttacked();
|
|
|
|
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) {
|
|
|
|
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;
|
|
|
|
d1 = (Math.random() - Math.random()) * 0.01D;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - this.rotationYaw;
|
|
|
|
this.attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - this.rotationYaw;
|
|
|
|
this.knockBack(entity, damage, d1, d0);
|
|
|
|
this.knockBack(entity, damage, d1, d0);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
|
|
|
|
this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String s;
|
|
|
|
String sound;
|
|
|
|
|
|
|
|
|
|
|
|
if (this.getHealth() <= 0.0F) {
|
|
|
|
if (getHealth() <= 0.0F) {
|
|
|
|
s = this.getDeathSound();
|
|
|
|
sound = getDeathSound();
|
|
|
|
|
|
|
|
|
|
|
|
if (flag && s != null) {
|
|
|
|
if (flag && sound != null)
|
|
|
|
this.playSound(s, this.getSoundVolume(), this.getSoundPitch());
|
|
|
|
this.playSound(sound, getSoundVolume(), getSoundPitch());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.onDeath(source);
|
|
|
|
onDeath(source);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
s = this.getHurtSound();
|
|
|
|
sound = getHurtSound();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (flag && sound != null)
|
|
|
|
|
|
|
|
this.playSound(sound, getSoundVolume(), getSoundPitch());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (flag && s != null) {
|
|
|
|
return true;
|
|
|
|
this.playSound(s, this.getSoundVolume(), this.getSoundPitch());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|