Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-12-18 20:40:08 +01:00
Put damage modifiers in Functions for event. Fixes BUKKIT-5681
Dieser Commit ist enthalten in:
Ursprung
dbb5e6e3cd
Commit
13482ac7f6
@ -9,6 +9,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import com.google.common.base.Function;
|
||||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
|
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
|
||||||
@ -956,49 +957,78 @@ public abstract class EntityLiving extends Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
protected boolean d(DamageSource damagesource, float f) { // void -> boolean
|
protected boolean d(final DamageSource damagesource, float f) { // void -> boolean, add final
|
||||||
if (!this.isInvulnerable()) {
|
if (!this.isInvulnerable()) {
|
||||||
boolean human = this instanceof EntityHuman;
|
final boolean human = this instanceof EntityHuman;
|
||||||
float originalDamage = f;
|
float originalDamage = f;
|
||||||
float preDamage = f;
|
Function<Double, Double> hardHat = new Function<Double, Double>() {
|
||||||
float hardHatModifier = 0;
|
@Override
|
||||||
if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) {
|
public Double apply(Double f) {
|
||||||
f *= 0.75F;
|
if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && EntityLiving.this.getEquipment(4) != null) {
|
||||||
hardHatModifier = preDamage - f;
|
return -(f - (f * 0.75F));
|
||||||
preDamage = f;
|
}
|
||||||
}
|
return -0.0;
|
||||||
float blockingModifier = 0;
|
|
||||||
if (human) {
|
|
||||||
if (!damagesource.ignoresArmor() && ((EntityHuman) this).isBlocking() && f > 0.0F) {
|
|
||||||
f = (1.0F + f) * 0.5F;
|
|
||||||
blockingModifier = preDamage - f;
|
|
||||||
preDamage = f;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
// Armor modifier
|
float hardHatModifier = hardHat.apply((double) f).floatValue();
|
||||||
f = this.applyArmorModifier(damagesource, f);
|
f += hardHatModifier;
|
||||||
float armorModifier = preDamage - f;
|
|
||||||
preDamage = f;
|
|
||||||
// Resistance Potion Effect
|
|
||||||
if (!damagesource.isStarvation() && this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) {
|
|
||||||
int i = (this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5;
|
|
||||||
int j = 25 - i;
|
|
||||||
float f1 = f * (float) j;
|
|
||||||
f = f1 / 25.0F;
|
|
||||||
}
|
|
||||||
float resistanceModifier = preDamage - f;
|
|
||||||
preDamage = f;
|
|
||||||
// Magic modifier
|
|
||||||
f = this.applyMagicModifier(damagesource, f);
|
|
||||||
float magicModifier = preDamage - f;
|
|
||||||
float f1 = f;
|
|
||||||
|
|
||||||
// Absorption modifier
|
Function<Double, Double> blocking = new Function<Double, Double>() {
|
||||||
f = Math.max(f - this.getAbsorptionHearts(), 0.0F);
|
@Override
|
||||||
float absorptionModifier = Math.max(f1 - f, 0.0F);
|
public Double apply(Double f) {
|
||||||
|
if (human) {
|
||||||
|
if (!damagesource.ignoresArmor() && ((EntityHuman) EntityLiving.this).isBlocking() && f > 0.0F) {
|
||||||
|
return -(f - ((1.0F + f) * 0.5F));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -0.0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
float blockingModifier = blocking.apply((double) f).floatValue();
|
||||||
|
f += blockingModifier;
|
||||||
|
|
||||||
EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, -hardHatModifier, -blockingModifier, -armorModifier, -resistanceModifier, -magicModifier, -absorptionModifier);
|
Function<Double, Double> armor = new Function<Double, Double>() {
|
||||||
|
@Override
|
||||||
|
public Double apply(Double f) {
|
||||||
|
return -(f - EntityLiving.this.applyArmorModifier(damagesource, f.floatValue()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
float armorModifier = armor.apply((double) f).floatValue();
|
||||||
|
f += armorModifier;
|
||||||
|
|
||||||
|
Function<Double, Double> resistance = new Function<Double, Double>() {
|
||||||
|
@Override
|
||||||
|
public Double apply(Double f) {
|
||||||
|
if (!damagesource.isStarvation() && EntityLiving.this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) {
|
||||||
|
int i = (EntityLiving.this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5;
|
||||||
|
int j = 25 - i;
|
||||||
|
float f1 = f.floatValue() * (float) j;
|
||||||
|
return -(f - (f1 / 25.0F));
|
||||||
|
}
|
||||||
|
return -0.0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
float resistanceModifier = resistance.apply((double) f).floatValue();
|
||||||
|
f += resistanceModifier;
|
||||||
|
|
||||||
|
Function<Double, Double> magic = new Function<Double, Double>() {
|
||||||
|
@Override
|
||||||
|
public Double apply(Double f) {
|
||||||
|
return -(f - EntityLiving.this.applyMagicModifier(damagesource, f.floatValue()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
float magicModifier = magic.apply((double) f).floatValue();
|
||||||
|
f += magicModifier;
|
||||||
|
|
||||||
|
Function<Double, Double> absorption = new Function<Double, Double>() {
|
||||||
|
@Override
|
||||||
|
public Double apply(Double f) {
|
||||||
|
return -(Math.max(f - Math.max(f - EntityLiving.this.getAbsorptionHearts(), 0.0F), 0.0F));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
float absorptionModifier = absorption.apply((double) f).floatValue();
|
||||||
|
|
||||||
|
EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,11 @@ package org.bukkit.craftbukkit.event;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Functions;
|
||||||
import net.minecraft.server.ChunkCoordinates;
|
import net.minecraft.server.ChunkCoordinates;
|
||||||
import net.minecraft.server.Container;
|
import net.minecraft.server.Container;
|
||||||
import net.minecraft.server.DamageSource;
|
import net.minecraft.server.DamageSource;
|
||||||
@ -23,7 +24,6 @@ import net.minecraft.server.EntityLiving;
|
|||||||
import net.minecraft.server.EntityPlayer;
|
import net.minecraft.server.EntityPlayer;
|
||||||
import net.minecraft.server.EntityPotion;
|
import net.minecraft.server.EntityPotion;
|
||||||
import net.minecraft.server.Explosion;
|
import net.minecraft.server.Explosion;
|
||||||
import net.minecraft.server.IInventory;
|
|
||||||
import net.minecraft.server.InventoryCrafting;
|
import net.minecraft.server.InventoryCrafting;
|
||||||
import net.minecraft.server.ItemStack;
|
import net.minecraft.server.ItemStack;
|
||||||
import net.minecraft.server.Items;
|
import net.minecraft.server.Items;
|
||||||
@ -403,23 +403,23 @@ public class CraftEventFactory {
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map<DamageModifier, Double> modifiers) {
|
private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions) {
|
||||||
if (source.isExplosion()) {
|
if (source.isExplosion()) {
|
||||||
DamageCause damageCause;
|
DamageCause damageCause;
|
||||||
Entity damager = entityDamage;
|
Entity damager = entityDamage;
|
||||||
entityDamage = null;
|
entityDamage = null;
|
||||||
EntityDamageEvent event;
|
EntityDamageEvent event;
|
||||||
if (damager == null) {
|
if (damager == null) {
|
||||||
event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers);
|
event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions);
|
||||||
} else if (entity instanceof EntityEnderDragon && ((EntityEnderDragon) entity).bC == damager) {
|
} else if (entity instanceof EntityEnderDragon && ((EntityEnderDragon) entity).bC == damager) {
|
||||||
event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers);
|
event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions);
|
||||||
} else {
|
} else {
|
||||||
if (damager instanceof org.bukkit.entity.TNTPrimed) {
|
if (damager instanceof org.bukkit.entity.TNTPrimed) {
|
||||||
damageCause = DamageCause.BLOCK_EXPLOSION;
|
damageCause = DamageCause.BLOCK_EXPLOSION;
|
||||||
} else {
|
} else {
|
||||||
damageCause = DamageCause.ENTITY_EXPLOSION;
|
damageCause = DamageCause.ENTITY_EXPLOSION;
|
||||||
}
|
}
|
||||||
event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers);
|
event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
callEvent(event);
|
callEvent(event);
|
||||||
@ -443,15 +443,15 @@ public class CraftEventFactory {
|
|||||||
cause = DamageCause.THORNS;
|
cause = DamageCause.THORNS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return callEntityDamageEvent(damager, entity, cause, modifiers);
|
return callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions);
|
||||||
} else if (source == DamageSource.OUT_OF_WORLD) {
|
} else if (source == DamageSource.OUT_OF_WORLD) {
|
||||||
EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers));
|
EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions));
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
event.getEntity().setLastDamageCause(event);
|
event.getEntity().setLastDamageCause(event);
|
||||||
}
|
}
|
||||||
return event;
|
return event;
|
||||||
} else if (source == DamageSource.LAVA) {
|
} else if (source == DamageSource.LAVA) {
|
||||||
EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers));
|
EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions));
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
event.getEntity().setLastDamageCause(event);
|
event.getEntity().setLastDamageCause(event);
|
||||||
}
|
}
|
||||||
@ -465,7 +465,7 @@ public class CraftEventFactory {
|
|||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Unhandled entity damage");
|
throw new RuntimeException("Unhandled entity damage");
|
||||||
}
|
}
|
||||||
EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers));
|
EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions));
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
event.getEntity().setLastDamageCause(event);
|
event.getEntity().setLastDamageCause(event);
|
||||||
}
|
}
|
||||||
@ -483,7 +483,7 @@ public class CraftEventFactory {
|
|||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Unhandled entity damage");
|
throw new RuntimeException("Unhandled entity damage");
|
||||||
}
|
}
|
||||||
EntityDamageEvent event = callEvent(new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers));
|
EntityDamageEvent event = callEvent(new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions));
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
event.getEntity().setLastDamageCause(event);
|
event.getEntity().setLastDamageCause(event);
|
||||||
}
|
}
|
||||||
@ -512,22 +512,22 @@ public class CraftEventFactory {
|
|||||||
} else if (source == DamageSource.FALL) {
|
} else if (source == DamageSource.FALL) {
|
||||||
cause = DamageCause.FALL;
|
cause = DamageCause.FALL;
|
||||||
} else if (source == DamageSource.GENERIC) {
|
} else if (source == DamageSource.GENERIC) {
|
||||||
return new EntityDamageEvent(entity.getBukkitEntity(), null, modifiers);
|
return new EntityDamageEvent(entity.getBukkitEntity(), null, modifiers, modifierFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
return callEntityDamageEvent(null, entity, cause, modifiers);
|
return callEntityDamageEvent(null, entity, cause, modifiers, modifierFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException("Unhandled entity damage");
|
throw new RuntimeException("Unhandled entity damage");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map<DamageModifier, Double> modifiers) {
|
private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> modifierFunctions) {
|
||||||
EntityDamageEvent event;
|
EntityDamageEvent event;
|
||||||
if (damager != null) {
|
if (damager != null) {
|
||||||
event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers);
|
event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions);
|
||||||
} else {
|
} else {
|
||||||
event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers);
|
event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
callEvent(event);
|
callEvent(event);
|
||||||
@ -539,20 +539,30 @@ public class CraftEventFactory {
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityDamageEvent handleLivingEntityDamageEvent(Entity damagee, DamageSource source, double rawDamage, double hardHatModifier, double blockingModifier, double armorModifier, double resistanceModifier, double magicModifier, double absorptionModifier) {
|
private static final Function<? super Double, Double> ZERO = Functions.constant(-0.0);
|
||||||
Map<DamageModifier, Double> modifiers = new HashMap<DamageModifier, Double>();
|
|
||||||
|
public static EntityDamageEvent handleLivingEntityDamageEvent(Entity damagee, DamageSource source, double rawDamage, double hardHatModifier, double blockingModifier, double armorModifier, double resistanceModifier, double magicModifier, double absorptionModifier, Function<Double, Double> hardHat, Function<Double, Double> blocking, Function<Double, Double> armor, Function<Double, Double> resistance, Function<Double, Double> magic, Function<Double, Double> absorption) {
|
||||||
|
Map<DamageModifier, Double> modifiers = new EnumMap<DamageModifier, Double>(DamageModifier.class);
|
||||||
|
Map<DamageModifier, Function<? super Double, Double>> modifierFunctions = new EnumMap<DamageModifier, Function<? super Double, Double>>(DamageModifier.class);
|
||||||
modifiers.put(DamageModifier.BASE, rawDamage);
|
modifiers.put(DamageModifier.BASE, rawDamage);
|
||||||
|
modifierFunctions.put(DamageModifier.BASE, ZERO);
|
||||||
if (source == DamageSource.FALLING_BLOCK || source == DamageSource.ANVIL) {
|
if (source == DamageSource.FALLING_BLOCK || source == DamageSource.ANVIL) {
|
||||||
modifiers.put(DamageModifier.HARD_HAT, hardHatModifier);
|
modifiers.put(DamageModifier.HARD_HAT, hardHatModifier);
|
||||||
|
modifierFunctions.put(DamageModifier.HARD_HAT, hardHat);
|
||||||
}
|
}
|
||||||
if (damagee instanceof EntityHuman) {
|
if (damagee instanceof EntityHuman) {
|
||||||
modifiers.put(DamageModifier.BLOCKING, blockingModifier);
|
modifiers.put(DamageModifier.BLOCKING, blockingModifier);
|
||||||
|
modifierFunctions.put(DamageModifier.BLOCKING, blocking);
|
||||||
}
|
}
|
||||||
modifiers.put(DamageModifier.ARMOR, armorModifier);
|
modifiers.put(DamageModifier.ARMOR, armorModifier);
|
||||||
|
modifierFunctions.put(DamageModifier.ARMOR, armor);
|
||||||
modifiers.put(DamageModifier.RESISTANCE, resistanceModifier);
|
modifiers.put(DamageModifier.RESISTANCE, resistanceModifier);
|
||||||
|
modifierFunctions.put(DamageModifier.RESISTANCE, resistance);
|
||||||
modifiers.put(DamageModifier.MAGIC, magicModifier);
|
modifiers.put(DamageModifier.MAGIC, magicModifier);
|
||||||
|
modifierFunctions.put(DamageModifier.MAGIC, magic);
|
||||||
modifiers.put(DamageModifier.ABSORPTION, absorptionModifier);
|
modifiers.put(DamageModifier.ABSORPTION, absorptionModifier);
|
||||||
return handleEntityDamageEvent(damagee, source, new EnumMap<DamageModifier, Double>(modifiers));
|
modifierFunctions.put(DamageModifier.ABSORPTION, absorption);
|
||||||
|
return handleEntityDamageEvent(damagee, source, modifiers, modifierFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-Living Entities such as EntityEnderCrystal, EntityItemFrame, and EntityFireball need to call this
|
// Non-Living Entities such as EntityEnderCrystal, EntityItemFrame, and EntityFireball need to call this
|
||||||
@ -560,7 +570,7 @@ public class CraftEventFactory {
|
|||||||
if (entity instanceof EntityEnderCrystal && !(source instanceof EntityDamageSource)) {
|
if (entity instanceof EntityEnderCrystal && !(source instanceof EntityDamageSource)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
EntityDamageEvent event = handleEntityDamageEvent(entity, source, new EnumMap<DamageModifier, Double>(ImmutableMap.of(DamageModifier.BASE, (double) damage)));
|
EntityDamageEvent event = handleEntityDamageEvent(entity, source, new EnumMap<DamageModifier, Double>(ImmutableMap.of(DamageModifier.BASE, (double) damage)), null);
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren