use of net.minecraft.world.level.Explosion in project SpongeCommon by SpongePowered.
the class DamageSourceMixin method onSetExplosionSource.
@Inject(method = "explosion(Lnet/minecraft/world/level/Explosion;)Lnet/minecraft/world/damagesource/DamageSource;", at = @At("HEAD"), cancellable = true)
private static void onSetExplosionSource(@Nullable final Explosion explosion, final CallbackInfoReturnable<net.minecraft.world.damagesource.DamageSource> cir) {
if (explosion != null) {
final Entity entity = ((ExplosionAccessor) explosion).accessor$source();
if (entity != null && !((LevelBridge) ((ExplosionAccessor) explosion).accessor$level()).bridge$isFake()) {
if (explosion.getSourceMob() == null && entity instanceof CreatorTrackedBridge) {
// check creator
final CreatorTrackedBridge creatorBridge = (CreatorTrackedBridge) entity;
creatorBridge.tracker$getCreatorUUID().flatMap(x -> Sponge.server().player(x)).ifPresent(player -> {
final IndirectEntityDamageSource damageSource = new IndirectEntityDamageSource("explosion.player", entity, (Entity) player);
damageSource.setScalesWithDifficulty().setExplosion();
cir.setReturnValue(damageSource);
});
}
}
}
}
use of net.minecraft.world.level.Explosion in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method tracker$triggerInternalExplosion.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Explosion tracker$triggerInternalExplosion(org.spongepowered.api.world.explosion.Explosion explosion, final Function<? super Explosion, ? extends PhaseContext<@NonNull ?>> contextCreator) {
// Sponge start
final Explosion originalExplosion = (Explosion) explosion;
if (ShouldFire.EXPLOSION_EVENT_PRE) {
// Set up the pre event
final ExplosionEvent.Pre event = SpongeEventFactory.createExplosionEventPre(PhaseTracker.SERVER.currentCause(), explosion, ((org.spongepowered.api.world.server.ServerWorld) this));
if (SpongeCommon.post(event)) {
return (Explosion) explosion;
}
explosion = event.explosion();
}
final Explosion mcExplosion;
try {
// Since we already have the API created implementation Explosion, let's use it.
mcExplosion = (Explosion) explosion;
} catch (final Exception e) {
new org.spongepowered.asm.util.PrettyPrinter(60).add("Explosion not compatible with this implementation").centre().hr().add("An explosion that was expected to be used for this implementation does not").add("originate from this implementation.").add(e).trace();
return originalExplosion;
}
try (final PhaseContext<@NonNull ?> ignored = contextCreator.apply(mcExplosion).source(((Optional) explosion.sourceExplosive()).orElse(this))) {
ignored.buildAndSwitch();
final boolean damagesTerrain = explosion.shouldBreakBlocks();
// Sponge End
mcExplosion.explode();
mcExplosion.finalizeExplosion(true);
if (!damagesTerrain) {
mcExplosion.clearToBlow();
}
// the players being moved.
for (final ServerPlayer playerEntity : this.players) {
final Vec3 knockback = mcExplosion.getHitPlayers().get(playerEntity);
if (knockback != null) {
// In Vanilla, doExplosionB always updates the 'motion[xyz]' fields for every entity in range.
// However, this field is completely ignored for players (since 'velocityChanged') is never set, and
// a completely different value is sent through 'SPacketExplosion'.
// To replicate this behavior, we manually send a velocity packet. It's critical that we don't simply
// add to the 'motion[xyz]' fields, as that will end up using the value set by 'doExplosionB', which must be
// ignored.
playerEntity.connection.send(new ClientboundSetEntityMotionPacket(playerEntity.getId(), new Vec3(knockback.x, knockback.y, knockback.z)));
}
}
// Sponge End
}
// Sponge End
return mcExplosion;
}
use of net.minecraft.world.level.Explosion in project SpongeCommon by SpongePowered.
the class ExplosionState method populateLootContext.
@Override
public void populateLootContext(final ExplosionContext phaseContext, final LootContext.Builder lootBuilder) {
final Explosion explosion = phaseContext.getExplosion();
lootBuilder.withOptionalParameter(LootContextParams.THIS_ENTITY, ((ExplosionAccessor) explosion).accessor$source());
if (((ExplosionAccessor) explosion).accessor$blockInteraction() == net.minecraft.world.level.Explosion.BlockInteraction.DESTROY) {
lootBuilder.withParameter(LootContextParams.EXPLOSION_RADIUS, ((ExplosionAccessor) explosion).accessor$radius());
}
}
Aggregations