use of org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource in project SpongeCommon by SpongePowered.
the class MixinEntityLivingBase method damageEntityHook.
@Override
public boolean damageEntityHook(DamageSource damageSource, float damage) {
if (!this.isEntityInvulnerable(damageSource)) {
final boolean human = (Object) this instanceof EntityPlayer;
// apply forge damage hook
damage = applyModDamage((EntityLivingBase) (Object) this, damageSource, damage);
// set after forge hook.
float originalDamage = damage;
if (damage <= 0) {
damage = 0;
}
List<DamageFunction> originalFunctions = new ArrayList<>();
Optional<DamageFunction> hardHatFunction = DamageEventHandler.createHardHatModifier((EntityLivingBase) (Object) this, damageSource);
Optional<List<DamageFunction>> armorFunction = provideArmorModifiers((EntityLivingBase) (Object) this, damageSource, damage);
Optional<DamageFunction> resistanceFunction = DamageEventHandler.createResistanceModifier((EntityLivingBase) (Object) this, damageSource);
Optional<List<DamageFunction>> armorEnchantments = DamageEventHandler.createEnchantmentModifiers((EntityLivingBase) (Object) this, damageSource);
Optional<DamageFunction> absorptionFunction = DamageEventHandler.createAbsorptionModifier((EntityLivingBase) (Object) this, damageSource);
Optional<DamageFunction> shieldFunction = DamageEventHandler.createShieldFunction((EntityLivingBase) (Object) this, damageSource, damage);
if (hardHatFunction.isPresent()) {
originalFunctions.add(hardHatFunction.get());
}
if (shieldFunction.isPresent()) {
originalFunctions.add(shieldFunction.get());
}
if (armorFunction.isPresent()) {
originalFunctions.addAll(armorFunction.get());
}
if (resistanceFunction.isPresent()) {
originalFunctions.add(resistanceFunction.get());
}
if (armorEnchantments.isPresent()) {
originalFunctions.addAll(armorEnchantments.get());
}
if (absorptionFunction.isPresent()) {
originalFunctions.add(absorptionFunction.get());
}
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
DamageEventHandler.generateCauseFor(damageSource);
DamageEntityEvent event = SpongeEventFactory.createDamageEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), originalFunctions, this, originalDamage);
if (damageSource != DamageSourceRegistryModule.IGNORED_DAMAGE_SOURCE) {
// Basically, don't throw an event if it's our own damage source
Sponge.getEventManager().post(event);
}
if (event.isCancelled()) {
return false;
}
damage = (float) event.getFinalDamage();
// Helmet
final ItemStack mainHandItem = this.getItemStackFromSlot(EntityEquipmentSlot.MAINHAND);
if ((damageSource instanceof FallingBlockDamageSource) && mainHandItem != null) {
mainHandItem.damageItem((int) (event.getBaseDamage() * 4.0F + this.rand.nextFloat() * event.getBaseDamage() * 2.0F), (EntityLivingBase) (Object) this);
}
// Shield
if (shieldFunction.isPresent()) {
// TODO gabizou: Should this be in the API?
this.damageShield((float) event.getBaseDamage());
if (!damageSource.isProjectile()) {
Entity entity = damageSource.getImmediateSource();
if (entity instanceof EntityLivingBase) {
this.blockUsingShield((EntityLivingBase) entity);
}
}
}
// Armor
if (!damageSource.isUnblockable()) {
for (DamageFunction modifier : event.getModifiers()) {
applyArmorDamage((EntityLivingBase) (Object) this, damageSource, event, modifier.getModifier());
}
}
double absorptionModifier = absorptionFunction.map(function -> event.getDamage(function.getModifier())).orElse(0d);
if (absorptionFunction.isPresent()) {
absorptionModifier = event.getDamage(absorptionFunction.get().getModifier());
}
this.setAbsorptionAmount(Math.max(this.getAbsorptionAmount() + (float) absorptionModifier, 0.0F));
if (damage != 0.0F) {
if (human) {
((EntityPlayer) (Object) this).addExhaustion(damageSource.getHungerDamage());
}
float f2 = this.getHealth();
this.setHealth(f2 - damage);
this.getCombatTracker().trackDamage(damageSource, f2, damage);
if (human) {
return true;
}
this.setAbsorptionAmount(this.getAbsorptionAmount() - damage);
}
return true;
}
}
return false;
}
use of org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource in project SpongeCommon by SpongePowered.
the class LivingEntityMixin method bridge$damageEntity.
@Override
public boolean bridge$damageEntity(final DamageSource damageSource, float damage) {
if (this.shadow$isInvulnerableTo(damageSource)) {
return false;
}
final boolean isHuman = (LivingEntity) (Object) this instanceof Player;
// Sponge Start - Call platform hook for adjusting damage
damage = this.bridge$applyModDamage((LivingEntity) (Object) this, damageSource, damage);
// Sponge End
final float originalDamage = damage;
if (damage <= 0) {
return false;
}
final List<DamageFunction> originalFunctions = new ArrayList<>();
final Optional<DamageFunction> hardHatFunction = DamageEventUtil.createHardHatModifier((LivingEntity) (Object) this, damageSource);
final Optional<DamageFunction> armorFunction = DamageEventUtil.createArmorModifiers((LivingEntity) (Object) this, damageSource);
final Optional<DamageFunction> resistanceFunction = DamageEventUtil.createResistanceModifier((LivingEntity) (Object) this, damageSource);
final Optional<List<DamageFunction>> armorEnchantments = DamageEventUtil.createEnchantmentModifiers((LivingEntity) (Object) this, damageSource);
final Optional<DamageFunction> absorptionFunction = DamageEventUtil.createAbsorptionModifier((LivingEntity) (Object) this);
final Optional<DamageFunction> shieldFunction = DamageEventUtil.createShieldFunction((LivingEntity) (Object) this, damageSource, damage);
hardHatFunction.ifPresent(originalFunctions::add);
shieldFunction.ifPresent(originalFunctions::add);
armorFunction.ifPresent(originalFunctions::add);
resistanceFunction.ifPresent(originalFunctions::add);
armorEnchantments.ifPresent(originalFunctions::addAll);
absorptionFunction.ifPresent(originalFunctions::add);
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
DamageEventUtil.generateCauseFor(damageSource, frame);
final DamageEntityEvent event = SpongeEventFactory.createDamageEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) this, originalFunctions, originalDamage);
if (damageSource != SpongeDamageSources.IGNORED) {
// Basically, don't throw an event if it's our own damage source
SpongeCommon.post(event);
}
if (event.isCancelled()) {
return false;
}
damage = (float) event.finalDamage();
// Sponge Start - Allow the platform to adjust damage before applying armor/etc
damage = this.bridge$applyModDamageBeforeFunctions((LivingEntity) (Object) this, damageSource, damage);
// Sponge End
// Helmet
final ItemStack helmet = this.shadow$getItemBySlot(EquipmentSlot.HEAD);
// without using our mixin redirects in EntityFallingBlockMixin.
if ((damageSource instanceof FallingBlockDamageSource) || damageSource == DamageSource.ANVIL || damageSource == DamageSource.FALLING_BLOCK && !helmet.isEmpty()) {
helmet.hurtAndBreak((int) (event.baseDamage() * 4.0F + this.random.nextFloat() * event.baseDamage() * 2.0F), (LivingEntity) (Object) this, (entity) -> entity.broadcastBreakEvent(EquipmentSlot.HEAD));
}
boolean hurtStack = false;
// Shield
if (shieldFunction.isPresent()) {
this.shadow$hurtCurrentlyUsedShield((float) event.baseDamage());
hurtStack = true;
if (!damageSource.isProjectile()) {
final Entity entity = damageSource.getDirectEntity();
if (entity instanceof LivingEntity) {
this.shadow$blockUsingShield((LivingEntity) entity);
}
}
}
// Armor
if (!damageSource.isBypassArmor() && armorFunction.isPresent()) {
this.shadow$hurtArmor(damageSource, (float) event.baseDamage());
hurtStack = true;
}
// Sponge start - log inventory change due to taking damage
if (hurtStack && isHuman) {
PhaseTracker.SERVER.getPhaseContext().getTransactor().logPlayerInventoryChange((Player) (Object) this, PlayerInventoryTransaction.EventCreator.STANDARD);
// capture
((Player) (Object) this).inventoryMenu.broadcastChanges();
}
// Resistance modifier post calculation
if (resistanceFunction.isPresent()) {
final float f2 = (float) event.damage(resistanceFunction.get().modifier()) - damage;
if (f2 > 0.0F && f2 < 3.4028235E37F) {
if (((LivingEntity) (Object) this) instanceof net.minecraft.server.level.ServerPlayer) {
((net.minecraft.server.level.ServerPlayer) ((LivingEntity) (Object) this)).awardStat(Stats.DAMAGE_RESISTED, Math.round(f2 * 10.0F));
} else if (damageSource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) {
((net.minecraft.server.level.ServerPlayer) damageSource.getEntity()).awardStat(Stats.DAMAGE_DEALT_RESISTED, Math.round(f2 * 10.0F));
}
}
}
double absorptionModifier = absorptionFunction.map(function -> event.damage(function.modifier())).orElse(0d);
if (absorptionFunction.isPresent()) {
absorptionModifier = event.damage(absorptionFunction.get().modifier());
}
final float f = (float) event.finalDamage() - (float) absorptionModifier;
this.shadow$setAbsorptionAmount(Math.max(this.shadow$getAbsorptionAmount() + (float) absorptionModifier, 0.0F));
if (f > 0.0F && f < 3.4028235E37F && ((LivingEntity) (Object) this) instanceof net.minecraft.server.level.ServerPlayer) {
((Player) (Object) this).awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(f * 10.0F));
}
if (damage != 0.0F) {
if (isHuman) {
((Player) (Object) this).causeFoodExhaustion(damageSource.getFoodExhaustion());
}
final float f2 = this.shadow$getHealth();
this.shadow$setHealth(f2 - damage);
this.shadow$getCombatTracker().recordDamage(damageSource, f2, damage);
if (isHuman) {
if (damage < 3.4028235E37F) {
((Player) (Object) this).awardStat(Stats.DAMAGE_TAKEN, Math.round(damage * 10.0F));
}
return true;
}
this.shadow$setAbsorptionAmount(this.shadow$getAbsorptionAmount() - damage);
}
return true;
}
}
use of org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource in project SpongeCommon by SpongePowered.
the class SpongeFallingBlockDamgeSourceBuilder method build.
@SuppressWarnings("ConstantConditions")
@Override
public FallingBlockDamageSource build() throws IllegalStateException {
checkState(this.reference.get() != null);
checkState(this.damageType != null);
final MinecraftFallingBlockDamageSource damageSource = new MinecraftFallingBlockDamageSource(this.damageType.name(), (FallingBlockEntity) this.reference.get());
final DamageSourceAccessor accessor = (DamageSourceAccessor) (Object) damageSource;
if (this.creative) {
accessor.invoker$bypassInvul();
}
if (this.scales) {
damageSource.setScalesWithDifficulty();
}
if (this.magical) {
damageSource.setMagic();
}
if (this.bypasses) {
accessor.invoker$bypassArmor();
}
if (this.absolute) {
accessor.invoker$bypassMagic();
}
if (this.explosion) {
damageSource.setExplosion();
}
if (this.exhaustion != null) {
accessor.accessor$exhaustion(this.exhaustion.floatValue());
}
return (FallingBlockDamageSource) (Object) damageSource;
}
Aggregations