Search in sources :

Example 1 with EntityDamageSource

use of net.minecraft.world.damagesource.EntityDamageSource in project SpongeCommon by SpongePowered.

the class EntityMixin method impl$ThrowDamageEventWithLightingSource.

@Redirect(method = "thunderHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
private boolean impl$ThrowDamageEventWithLightingSource(final Entity entity, final DamageSource source, final float damage, final ServerLevel level, final LightningBolt lightningBolt) {
    if (!this.level.isClientSide) {
        return entity.hurt(source, damage);
    }
    try {
        final EntityDamageSource lightning = new EntityDamageSource("lightningBolt", lightningBolt);
        ((DamageSourceBridge) lightning).bridge$setLightningSource();
        return entity.hurt(DamageSource.LIGHTNING_BOLT, damage);
    } finally {
        ((DamageSourceBridge) source).bridge$setLightningSource();
    }
}
Also used : DamageSourceBridge(org.spongepowered.common.bridge.world.damagesource.DamageSourceBridge) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 2 with EntityDamageSource

use of net.minecraft.world.damagesource.EntityDamageSource in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callDestructEntityEventDeath.

public static DestructEntityEvent.Death callDestructEntityEventDeath(final LivingEntity entity, @Nullable final DamageSource source, final Audience originalChannel) {
    final Component originalMessage;
    Optional<UUID> sourceCreator = Optional.empty();
    final boolean messageCancelled = false;
    if (source instanceof EntityDamageSource) {
        final EntityDamageSource damageSource = (EntityDamageSource) source;
        if (damageSource.getDirectEntity() instanceof CreatorTrackedBridge) {
            final CreatorTrackedBridge creatorBridge = (CreatorTrackedBridge) damageSource.getDirectEntity();
            if (creatorBridge != null) {
                sourceCreator = creatorBridge.tracker$getCreatorUUID();
            }
        }
    }
    originalMessage = SpongeAdventure.asAdventure(entity.getCombatTracker().getDeathMessage());
    try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
        if (source != null) {
            frame.pushCause(source);
        }
        sourceCreator.ifPresent(user -> frame.addContext(EventContextKeys.CREATOR, user));
        final DestructEntityEvent.Death event = SpongeEventFactory.createDestructEntityEventDeath(frame.currentCause(), originalChannel, Optional.of(originalChannel), originalMessage, originalMessage, (Living) entity, entity.level.getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY), messageCancelled);
        SpongeCommon.post(event);
        return event;
    }
}
Also used : CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) DestructEntityEvent(org.spongepowered.api.event.entity.DestructEntityEvent) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Component(net.kyori.adventure.text.Component) UUID(java.util.UUID) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource)

Example 3 with EntityDamageSource

use of net.minecraft.world.damagesource.EntityDamageSource in project SpongeCommon by SpongePowered.

the class DamageEventUtil method generateCauseFor.

/**
 * This applies various contexts based on the type of {@link DamageSource}, whether
 * it's provided by sponge or vanilla. This is not stack neutral, which is why it requires
 * a {@link CauseStackManager.StackFrame} reference to push onto the stack.
 */
public static void generateCauseFor(final DamageSource damageSource, final CauseStackManager.StackFrame frame) {
    if (damageSource instanceof EntityDamageSource) {
        final net.minecraft.world.entity.Entity source = damageSource.getEntity();
        if (!(source instanceof Player) && source instanceof CreatorTrackedBridge) {
            final CreatorTrackedBridge creatorBridge = (CreatorTrackedBridge) source;
            creatorBridge.tracker$getCreatorUUID().ifPresent(creator -> frame.addContext(EventContextKeys.CREATOR, creator));
            creatorBridge.tracker$getNotifierUUID().ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
        }
    } else if (damageSource instanceof BlockDamageSource) {
        final ServerLocation location = ((BlockDamageSource) damageSource).location();
        final BlockPos blockPos = VecHelper.toBlockPos(location);
        final LevelChunkBridge chunkBridge = (LevelChunkBridge) ((net.minecraft.world.level.Level) location.world()).getChunkAt(blockPos);
        chunkBridge.bridge$getBlockCreatorUUID(blockPos).ifPresent(creator -> frame.addContext(EventContextKeys.CREATOR, creator));
        chunkBridge.bridge$getBlockNotifierUUID(blockPos).ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
    }
    frame.pushCause(damageSource);
}
Also used : ResourceLocation(net.minecraft.resources.ResourceLocation) LivingEntity(net.minecraft.world.entity.LivingEntity) AABB(net.minecraft.world.phys.AABB) LivingEntityAccessor(org.spongepowered.common.accessor.world.entity.LivingEntityAccessor) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) MobType(net.minecraft.world.entity.MobType) EventContext(org.spongepowered.api.event.EventContext) Registry(net.minecraft.core.Registry) ChunkSource(net.minecraft.world.level.chunk.ChunkSource) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) ItemStack(org.spongepowered.api.item.inventory.ItemStack) Map(java.util.Map) PotionEffect(org.spongepowered.api.effect.potion.PotionEffect) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Player(net.minecraft.world.entity.player.Player) List(java.util.List) BlockPos(net.minecraft.core.BlockPos) BlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.BlockDamageSource) Optional(java.util.Optional) ServerLocation(org.spongepowered.api.world.server.ServerLocation) Enchantment(net.minecraft.world.item.enchantment.Enchantment) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) EventContextKeys(org.spongepowered.api.event.EventContextKeys) ServerWorld(org.spongepowered.api.world.server.ServerWorld) BlockState(net.minecraft.world.level.block.state.BlockState) HashMap(java.util.HashMap) DamageModifierTypes(org.spongepowered.api.event.cause.entity.damage.DamageModifierTypes) MobEffects(net.minecraft.world.effect.MobEffects) DoubleUnaryOperator(java.util.function.DoubleUnaryOperator) ArrayList(java.util.ArrayList) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource) ItemStackUtil(org.spongepowered.common.item.util.ItemStackUtil) DamageSource(net.minecraft.world.damagesource.DamageSource) EnchantmentHelper(net.minecraft.world.item.enchantment.EnchantmentHelper) CombatRules(net.minecraft.world.damagesource.CombatRules) Server(org.spongepowered.api.Server) CauseStackManager(org.spongepowered.api.event.CauseStackManager) FallingBlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource) Cause(org.spongepowered.api.event.Cause) Entity(net.minecraft.world.entity.Entity) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) EquipmentSlot(net.minecraft.world.entity.EquipmentSlot) Attributes(net.minecraft.world.entity.ai.attributes.Attributes) Mth(net.minecraft.util.Mth) Collections(java.util.Collections) ListTag(net.minecraft.nbt.ListTag) Player(net.minecraft.world.entity.player.Player) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) ServerLocation(org.spongepowered.api.world.server.ServerLocation) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource) Entity(net.minecraft.world.entity.Entity) BlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.BlockDamageSource) FallingBlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)

Example 4 with EntityDamageSource

use of net.minecraft.world.damagesource.EntityDamageSource in project SpongeCommon by SpongePowered.

the class LivingEntityMixin_Attack_impl method hurt.

// @formatter:on
/**
 * @author bloodmc - November 22, 2015
 * @author gabizou - Updated April 11th, 2016 - Update for 1.9 changes
 * @author Aaron1011 - Updated Nov 11th, 2016 - Update for 1.11 changes
 * @author gabizou - Updated Nov 15th, 2020 - Update for 1.15 changes
 * @author gabizou - Updated Jan 26th, 2022 - Update for 1.16.5 changes
 * @reason Reroute damageEntity calls to our hook in order to prevent damage.
 */
@Overwrite
public boolean hurt(final DamageSource source, final float amount) {
    // Sponge start - Add certain hooks for necessities
    this.lastDamageSource = source;
    if (source == null) {
        new PrettyPrinter(60).centre().add("Null DamageSource").hr().addWrapped("Sponge has found a null damage source! This should NEVER happen " + "as the DamageSource is used for all sorts of calculations. Usually" + " this can be considered developer error. Please report the following" + " stacktrace to the most appropriate mod/plugin available.").add().add(new IllegalArgumentException("Null DamageSource")).log(SpongeCommon.logger(), Level.WARN);
        return false;
    }
    // Sponge - This hook is for forge use mainly
    if (!this.bridge$onLivingAttack((LivingEntity) (Object) this, source, amount)) {
        return false;
    }
    // Sponge end
    if (this.shadow$isInvulnerableTo(source)) {
        return false;
    } else if (this.level.isClientSide) {
        return false;
    // Sponge - Also ignore our customary damage source
    } else if (this.shadow$isDeadOrDying() && source != SpongeDamageSources.IGNORED) {
        return false;
    } else if (source.isFire() && this.shadow$hasEffect(MobEffects.FIRE_RESISTANCE)) {
        return false;
    } else {
        if (this.shadow$isSleeping() && !this.level.isClientSide) {
            this.shadow$stopSleeping();
        }
        this.noActionTime = 0;
        final float f = amount;
        // Sponge - ignore as this is handled in our damageEntityHook
        // if ((source == DamageSource.ANVIL || source == DamageSource.FALLING_BLOCK) && !this.getItemStackFromSlot(EntityEquipmentSlot.HEAD).isEmpty())
        // {
        // this.getItemStackFromSlot(EquipmentSlotType.HEAD).damageItem((int)(amount * 4.0F + this.rand.nextFloat() * amount * 2.0F), this, (p_213341_0_) -> {
        // p_213341_0_.sendBreakAnimation(EquipmentSlotType.HEAD);
        // });
        // amount *= 0.75F;
        // }
        // Sponge End
        // Sponge - set the 'shield blocking ran' flag to the proper value, since
        // we comment out the logic below
        float f1 = 0.0F;
        final boolean flag = amount > 0.0F && this.shadow$isDamageSourceBlocked(source);
        // but we need to account for the amount later.
        if (flag) {
            f1 = amount;
        }
        // boolean flag = false;
        // 
        // if (amount > 0.0F && this.shadow$canBlockDamageSource(source))
        // {
        // this.damageShield(amount);
        // amount = 0.0F;
        // 
        // if (!source.isProjectile())
        // {
        // Entity entity = source.getImmediateSource();
        // 
        // if (entity instanceof EntityLivingBase)
        // {
        // this.blockUsingShield((EntityLivingBase)entity);
        // }
        // }
        // 
        // flag = true;
        // }
        // Sponge end
        this.animationSpeed = 1.5F;
        boolean flag1 = true;
        if ((float) this.invulnerableTime > 10.0F) {
            if (amount <= this.lastHurt) {
                // Technically, this is wrong since 'amount' won't be 0 if a shield is used. However, we need bridge$damageEntityHook so that we process the shield, so we leave it as-is
                return false;
            }
            // damageEntity method, which would re-run our bridge$damageEntityHook.
            if (((EntityTypeBridge) this.shadow$getType()).bridge$overridesDamageEntity()) {
                this.shadow$actuallyHurt(source, amount - this.lastHurt);
            } else {
                if (!this.bridge$damageEntity(source, amount - this.lastHurt)) {
                    return false;
                }
            }
            // this.damageEntity(source, amount - this.lastHurt); // handled above
            // Sponge end
            this.lastHurt = amount;
            flag1 = false;
        } else {
            // Sponge start - reroute to our damage hook
            if (((EntityTypeBridge) this.shadow$getType()).bridge$overridesDamageEntity()) {
                this.shadow$actuallyHurt(source, amount);
            } else {
                if (!this.bridge$damageEntity(source, amount)) {
                    return false;
                }
            }
            this.lastHurt = amount;
            this.invulnerableTime = 20;
            // this.damageEntity(source, amount); // handled above
            // Sponge end
            this.hurtDuration = 10;
            this.hurtTime = this.hurtDuration;
        }
        this.hurtDir = 0.0F;
        final Entity entity = source.getEntity();
        if (entity != null) {
            if (entity instanceof LivingEntity) {
                this.shadow$setLastHurtByMob((LivingEntity) entity);
            }
            if (entity instanceof Player) {
                this.lastHurtByPlayerTime = 100;
                this.lastHurtByPlayer = (Player) entity;
            // Forge Start - use TameableEntity instead of WolfEntity
            // } else if (entity1 instanceof WolfEntity) {
            // WolfEntity wolfentity = (WolfEntity)entity1;
            } else if (entity instanceof TamableAnimal) {
                final TamableAnimal wolfentity = (TamableAnimal) entity;
                if (wolfentity.isTame()) {
                    this.lastHurtByPlayerTime = 100;
                    final LivingEntity livingentity = wolfentity.getOwner();
                    if (livingentity != null && livingentity.getType() == EntityType.PLAYER) {
                        this.lastHurtByPlayer = (Player) livingentity;
                    } else {
                        this.lastHurtByPlayer = null;
                    }
                }
            }
        }
        if (flag1) {
            if (flag) {
                this.level.broadcastEntityEvent((LivingEntity) (Object) this, (byte) 29);
            } else if (source instanceof EntityDamageSource && ((EntityDamageSource) source).isThorns()) {
                this.level.broadcastEntityEvent((LivingEntity) (Object) this, (byte) 33);
            } else {
                final byte b0;
                if (source == DamageSource.DROWN) {
                    b0 = 36;
                } else if (source.isFire()) {
                    b0 = 37;
                } else if (source == DamageSource.SWEET_BERRY_BUSH) {
                    b0 = 44;
                } else {
                    b0 = 2;
                }
                this.level.broadcastEntityEvent((LivingEntity) (Object) this, b0);
            }
            if (source != DamageSource.DROWN && !flag) {
                // Sponge - remove 'amount > 0.0F' - it's redundant in Vanilla, and breaks our handling of shields
                this.shadow$markHurt();
            }
            if (entity != null) {
                double d1 = entity.getX() - this.shadow$getX();
                double d0;
                for (d0 = entity.getZ() - this.shadow$getZ(); d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) {
                    d1 = (Math.random() - Math.random()) * 0.01D;
                }
                this.hurtDir = (float) (Mth.atan2(d0, d1) * 57.2957763671875D - (double) this.yRot);
                this.shadow$knockback(0.4F, d1, d0);
            } else {
                this.hurtDir = (float) (Math.random() * 2.0D * 180);
            }
        }
        if (this.shadow$isDeadOrDying()) {
            if (!this.shadow$checkTotemDeathProtection(source)) {
                final SoundEvent soundevent = this.shadow$getDeathSound();
                // Sponge - Check that we're not vanished
                if (this.bridge$vanishState().createsSounds() && flag1 && soundevent != null) {
                    this.shadow$playSound(soundevent, this.shadow$getSoundVolume(), this.shadow$getVoicePitch());
                }
                // Sponge tracker will redirect this call
                this.shadow$die(source);
            }
        } else if (flag1) {
            // Sponge - Check if we're vanished
            if (this.bridge$vanishState().createsSounds()) {
                this.shadow$playHurtSound(source);
            }
        }
        // Sponge - remove 'amount > 0.0F' since it's handled in the event
        final boolean flag2 = !flag;
        if (flag2) {
            this.lastDamageSource = source;
            this.lastDamageStamp = this.level.getGameTime();
        }
        if ((LivingEntity) (Object) this instanceof net.minecraft.server.level.ServerPlayer) {
            CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((net.minecraft.server.level.ServerPlayer) (Object) this, source, f, amount, flag);
            if (f1 > 0.0F && f1 < 3.4028235E37F) {
                ((net.minecraft.server.level.ServerPlayer) (Object) this).awardStat(Stats.DAMAGE_BLOCKED_BY_SHIELD, Math.round(f1 * 10.0F));
            }
        }
        if (entity instanceof net.minecraft.server.level.ServerPlayer) {
            CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((net.minecraft.server.level.ServerPlayer) entity, (Entity) (Object) this, source, f, amount, flag);
        }
        return flag2;
    }
}
Also used : LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) Player(net.minecraft.world.entity.player.Player) TamableAnimal(net.minecraft.world.entity.TamableAnimal) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource) LivingEntity(net.minecraft.world.entity.LivingEntity) SoundEvent(net.minecraft.sounds.SoundEvent) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Aggregations

EntityDamageSource (net.minecraft.world.damagesource.EntityDamageSource)4 Entity (net.minecraft.world.entity.Entity)2 LivingEntity (net.minecraft.world.entity.LivingEntity)2 Player (net.minecraft.world.entity.player.Player)2 CauseStackManager (org.spongepowered.api.event.CauseStackManager)2 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 UUID (java.util.UUID)1 DoubleUnaryOperator (java.util.function.DoubleUnaryOperator)1 Predicate (java.util.function.Predicate)1 Component (net.kyori.adventure.text.Component)1 BlockPos (net.minecraft.core.BlockPos)1 Registry (net.minecraft.core.Registry)1 ListTag (net.minecraft.nbt.ListTag)1 ResourceLocation (net.minecraft.resources.ResourceLocation)1