Fixed blocking letting first hit through and bypassing armor
parent
38729a6fcf
commit
55903e3e51
@ -0,0 +1,188 @@
|
|||||||
|
package com.zivilon.cinder_loe.mixins;
|
||||||
|
|
||||||
|
import com.zivilon.cinder_loe.util.Pair;
|
||||||
|
import com.zivilon.cinder_loe.util.DamageEvent;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
|
||||||
|
import net.minecraft.potion.Potion;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
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.util.List;
|
||||||
|
|
||||||
|
@Mixin(EntityLivingBase.class)
|
||||||
|
public abstract class MixinEntityLivingBase extends Entity {
|
||||||
|
@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 p_70645_1_);
|
||||||
|
@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_);
|
||||||
|
@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;
|
||||||
|
} else if (this.worldObj.isRemote) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.entityAge = 0;
|
||||||
|
|
||||||
|
if (this.getHealth() <= 0.0F) {
|
||||||
|
return false;
|
||||||
|
} else if (source.isFireDamage() && this.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 ((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.damageEntity(source, damage - this.lastDamage);
|
||||||
|
this.lastDamage = damage;
|
||||||
|
flag = false;
|
||||||
|
} 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 net.minecraft.entity.passive.EntityTameable) {
|
||||||
|
net.minecraft.entity.passive.EntityTameable entitywolf = (net.minecraft.entity.passive.EntityTameable)entity;
|
||||||
|
|
||||||
|
if (entitywolf.isTamed()) {
|
||||||
|
this.recentlyHit = 100;
|
||||||
|
this.attackingPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
this.worldObj.setEntityState(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 s;
|
||||||
|
|
||||||
|
if (this.getHealth() <= 0.0F) {
|
||||||
|
s = this.getDeathSound();
|
||||||
|
|
||||||
|
if (flag && s != null) {
|
||||||
|
this.playSound(s, this.getSoundVolume(), this.getSoundPitch());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onDeath(source);
|
||||||
|
} else {
|
||||||
|
s = this.getHurtSound();
|
||||||
|
|
||||||
|
if (flag && s != null) {
|
||||||
|
this.playSound(s, this.getSoundVolume(), this.getSoundPitch());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package com.zivilon.cinder_loe.mixins;
|
||||||
|
|
||||||
|
import com.zivilon.cinder_loe.util.Pair;
|
||||||
|
import com.zivilon.cinder_loe.util.DamageEvent;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
|
||||||
|
import net.minecraft.potion.Potion;
|
||||||
|
import net.minecraft.entity.*;
|
||||||
|
import net.minecraft.entity.player.*;
|
||||||
|
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 net.minecraftforge.common.ISpecialArmor.ArmorProperties;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(EntityPlayer.class)
|
||||||
|
public abstract class MixinEntityPlayer extends EntityLivingBase {
|
||||||
|
|
||||||
|
public MixinEntityPlayer(World world, GameProfile p_i45324_2_) {
|
||||||
|
super(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract void addExhaustion(float p_71020_1_);
|
||||||
|
@Shadow
|
||||||
|
public InventoryPlayer inventory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Shinare
|
||||||
|
* @reason Removed vanilla blocking damage reduction
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
protected void damageEntity(DamageSource source, float damage) {
|
||||||
|
if (!this.isEntityInvulnerable())
|
||||||
|
{
|
||||||
|
damage = ForgeHooks.onLivingHurt(this, source, damage);
|
||||||
|
if (damage <= 0) return;
|
||||||
|
|
||||||
|
damage = ArmorProperties.ApplyArmor(this, inventory.armorInventory, source, damage);
|
||||||
|
if (damage <= 0) return;
|
||||||
|
damage = this.applyPotionDamageCalculations(source, damage);
|
||||||
|
float f1 = damage;
|
||||||
|
damage = Math.max(damage - this.getAbsorptionAmount(), 0.0F);
|
||||||
|
this.setAbsorptionAmount(this.getAbsorptionAmount() - (f1 - damage));
|
||||||
|
|
||||||
|
if (damage != 0.0F)
|
||||||
|
{
|
||||||
|
this.addExhaustion(source.getHungerDamage());
|
||||||
|
float f2 = this.getHealth();
|
||||||
|
this.setHealth(this.getHealth() - damage);
|
||||||
|
this.func_110142_aN().func_94547_a(source, f2, damage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,73 @@
|
|||||||
|
package com.zivilon.cinder_loe.util;
|
||||||
|
|
||||||
|
import net.minecraft.entity.*;
|
||||||
|
import net.minecraft.entity.player.*;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import lotr.common.item.*;
|
||||||
|
import net.minecraft.item.*;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class DamageEvent {
|
||||||
|
public DamageSource source;
|
||||||
|
public float damage;
|
||||||
|
public EntityLivingBase defender;
|
||||||
|
public Entity attacker;
|
||||||
|
|
||||||
|
public DamageEvent(DamageSource source, float damage, EntityLivingBase defender, Entity attacker) {
|
||||||
|
this.source = source;
|
||||||
|
this.damage = damage;
|
||||||
|
this.defender = defender;
|
||||||
|
this.attacker = attacker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pair<DamageEvent, Boolean> run_events(DamageEvent event) {
|
||||||
|
boolean cancel = false;
|
||||||
|
World world = event.defender.worldObj;
|
||||||
|
|
||||||
|
if (event.defender instanceof EntityPlayer && !event.source.isUnblockable()) {
|
||||||
|
EntityPlayerMP player = (EntityPlayerMP) event.defender;
|
||||||
|
ItemStack sword = player.getHeldItem();
|
||||||
|
if (!(event.attacker instanceof EntityLivingBase)) return new Pair<>(event, cancel);
|
||||||
|
EntityLivingBase attacker = (EntityLivingBase)event.attacker;
|
||||||
|
|
||||||
|
float playerYaw = player.getRotationYawHead();
|
||||||
|
float attackerYaw = attacker.getRotationYawHead();
|
||||||
|
|
||||||
|
// Normalize both angles to be within 0 - 360
|
||||||
|
playerYaw = (playerYaw + 360) % 360;
|
||||||
|
attackerYaw = (attackerYaw + 360) % 360;
|
||||||
|
|
||||||
|
// Calculate the angle difference
|
||||||
|
float angleDifference = Math.abs(playerYaw - attackerYaw);
|
||||||
|
|
||||||
|
if (angleDifference > 180) {
|
||||||
|
angleDifference = 360 - angleDifference;
|
||||||
|
}
|
||||||
|
ItemStack weapon = attacker.getHeldItem();
|
||||||
|
if (weapon != null) {
|
||||||
|
if (player.isBlocking() && angleDifference >= 135 && angleDifference <=225) {
|
||||||
|
|
||||||
|
if (weapon.getItem() instanceof ItemAxe || weapon.getItem() instanceof LOTRItemAxe || weapon.getItem() instanceof LOTRItemBattleaxe) {
|
||||||
|
sword.damageItem((int) (event.damage *1.5), player); // Axes deal 150% the Durability damage
|
||||||
|
player.clearItemInUse();
|
||||||
|
world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F);
|
||||||
|
event.damage *= 0.25f; // Only 25% Passes through
|
||||||
|
} else if (weapon.getItem() instanceof LOTRItemHammer) {
|
||||||
|
sword.damageItem((int) event.damage, player); // Hammers bypass the block better, but only deal 100% of the durability damage
|
||||||
|
player.clearItemInUse();
|
||||||
|
world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F);
|
||||||
|
event.damage *= 0.5f; // Only 50% Passes through
|
||||||
|
} else {
|
||||||
|
sword.damageItem((int) (event.damage/2), player); //Swords only deal 50% of durability damage
|
||||||
|
player.clearItemInUse();
|
||||||
|
world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F);
|
||||||
|
event.damage = 0.0f;
|
||||||
|
cancel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Pair<>(event, cancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package com.zivilon.cinder_loe.util;
|
||||||
|
|
||||||
|
public class Pair<K, V> {
|
||||||
|
public K key;
|
||||||
|
public V value;
|
||||||
|
|
||||||
|
public Pair(K key, V value) {
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public K getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
public V getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue