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();
}
}
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;
}
}
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);
}
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;
}
}
Aggregations