use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class VillagerMixin method impl$callPreSleepingEvent.
@Inject(method = "startSleeping", at = @At("HEAD"), cancellable = true)
private void impl$callPreSleepingEvent(BlockPos param0, CallbackInfo ci) {
final Cause currentCause = Sponge.server().causeStackManager().currentCause();
final BlockSnapshot snapshot = ((ServerWorld) this.level).createSnapshot(param0.getX(), param0.getY(), param0.getZ());
if (Sponge.eventManager().post(SpongeEventFactory.createSleepingEventPre(currentCause, snapshot, (Living) this))) {
ci.cancel();
}
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class AbstractFurnaceBlockEntityMixin method impl$resetCookTimeIfCancelled.
// Tick down
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;clamp(III)I"))
private int impl$resetCookTimeIfCancelled(final int newCookTime, final int zero, final int totalCookTime) {
final int clampedCookTime = Mth.clamp(newCookTime, zero, totalCookTime);
final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(this.items.get(1));
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final AbstractCookingRecipe recipe = this.impl$getCurrentRecipe();
final ItemStackSnapshot stack = ItemStackUtil.snapshotOf(this.items.get(0));
final CookingEvent.Tick event = SpongeEventFactory.createCookingEventTick(cause, (FurnaceBlockEntity) this, stack, Optional.of(fuel), Optional.of((CookingRecipe) recipe));
SpongeCommon.post(event);
if (event.isCancelled()) {
// dont tick down
return this.cookingProgress;
}
return clampedCookTime;
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class AbstractFurnaceBlockEntityMixin method impl$checkIfCanSmelt.
// Tick up and Start
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;canBurn(Lnet/minecraft/world/item/crafting/Recipe;)Z", ordinal = 1))
private boolean impl$checkIfCanSmelt(final AbstractFurnaceBlockEntity furnace, final Recipe<?> recipe) {
if (!this.shadow$canBurn(recipe)) {
return false;
}
final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(this.items.get(1));
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
if (this.cookingProgress == 0) {
// Start
final CookingEvent.Start event = SpongeEventFactory.createCookingEventStart(cause, (FurnaceBlockEntity) this, Optional.of(fuel), Optional.of((CookingRecipe) recipe));
SpongeCommon.post(event);
return !event.isCancelled();
} else {
// Tick up
final ItemStackSnapshot stack = ItemStackUtil.snapshotOf(this.items.get(0));
final CookingEvent.Tick event = SpongeEventFactory.createCookingEventTick(cause, (FurnaceBlockEntity) this, stack, Optional.of(fuel), Optional.of((CookingRecipe) recipe));
SpongeCommon.post(event);
return !event.isCancelled();
}
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class AbstractFurnaceBlockEntityMixin method impl$afterSmeltItem.
// Finish
@Inject(method = "burn", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;shrink(I)V"))
private void impl$afterSmeltItem(final Recipe<?> recipe, final CallbackInfo ci) {
final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(this.items.get(1));
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(recipe.getResultItem());
final CookingEvent.Finish event = SpongeEventFactory.createCookingEventFinish(cause, (FurnaceBlockEntity) this, Collections.singletonList(snapshot), Optional.of(fuel), Optional.ofNullable((CookingRecipe) recipe));
SpongeCommon.post(event);
}
use of org.spongepowered.api.event.Cause in project SpongeCommon by SpongePowered.
the class ExplosionMixin method explode.
/**
* @author gabizou
* @author zidane
* @reason Fire ExplosionEvent.Detonate
*/
@Overwrite
public void explode() {
// Sponge Start - Do not run calculation logic on client thread
if (this.level.isClientSide) {
return;
}
// Sponge Start - If the explosion should not break blocks, don't bother calculating it on server thread
if (this.impl$shouldBreakBlocks) {
final Set<BlockPos> set = Sets.newHashSet();
final int i = 16;
for (int j = 0; j < 16; ++j) {
for (int k = 0; k < 16; ++k) {
for (int l = 0; l < 16; ++l) {
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
final double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 = d0 / d3;
d1 = d1 / d3;
d2 = d2 / d3;
float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F);
double d4 = this.x;
double d6 = this.y;
double d8 = this.z;
for (final float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
final BlockPos blockpos = new BlockPos(d4, d6, d8);
final BlockState blockstate = this.level.getBlockState(blockpos);
final FluidState fluidstate = this.level.getFluidState(blockpos);
Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance((net.minecraft.world.level.Explosion) (Object) this, this.level, blockpos, blockstate, fluidstate);
if (optional.isPresent()) {
f -= (optional.get() + 0.3F) * 0.3F;
}
if (f > 0.0F && this.damageCalculator.shouldBlockExplode((net.minecraft.world.level.Explosion) (Object) this, this.level, blockpos, blockstate, f)) {
set.add(blockpos);
}
d4 += d0 * (double) 0.3F;
d6 += d1 * (double) 0.3F;
d8 += d2 * (double) 0.3F;
}
}
}
}
}
this.toBlow.addAll(set);
}
// Sponge End
final float f3 = this.radius * 2.0F;
final int k1 = Mth.floor(this.x - (double) f3 - 1.0D);
final int l1 = Mth.floor(this.x + (double) f3 + 1.0D);
final int i2 = Mth.floor(this.y - (double) f3 - 1.0D);
final int i1 = Mth.floor(this.y + (double) f3 + 1.0D);
final int j2 = Mth.floor(this.z - (double) f3 - 1.0D);
final int j1 = Mth.floor(this.z + (double) f3 + 1.0D);
// Sponge Start - Only query for entities if we're to damage them
final List<Entity> list = this.impl$shouldDamageEntities ? this.level.getEntities(this.source, new AABB((double) k1, (double) i2, (double) j2, (double) l1, (double) i1, (double) j1)) : Collections.emptyList();
if (ShouldFire.EXPLOSION_EVENT_DETONATE) {
final List<ServerLocation> blockPositions = new ArrayList<>(this.toBlow.size());
final List<org.spongepowered.api.entity.Entity> entities = new ArrayList<>(list.size());
for (final BlockPos pos : this.toBlow) {
blockPositions.add(ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) this.level, pos.getX(), pos.getY(), pos.getZ()));
}
for (final Entity entity : list) {
// Make sure to check the entity is immune first.
if (!entity.ignoreExplosion()) {
entities.add((org.spongepowered.api.entity.Entity) entity);
}
}
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final ExplosionEvent.Detonate detonate = SpongeEventFactory.createExplosionEventDetonate(cause, blockPositions, entities, (Explosion) this, (org.spongepowered.api.world.server.ServerWorld) this.level);
SpongeCommon.post(detonate);
// Clear the positions so that they can be pulled from the event
this.toBlow.clear();
if (detonate.isCancelled()) {
return;
}
if (this.impl$shouldBreakBlocks) {
for (final ServerLocation worldLocation : detonate.affectedLocations()) {
this.toBlow.add(VecHelper.toBlockPos(worldLocation));
}
}
// Clear the list of entities so they can be pulled from the event.
list.clear();
if (this.impl$shouldDamageEntities) {
for (final org.spongepowered.api.entity.Entity entity : detonate.entities()) {
try {
list.add((Entity) entity);
} catch (final Exception e) {
// Do nothing, a plugin tried to use the wrong entity somehow.
}
}
}
}
// Sponge End
final Vec3 vec3d = new Vec3(this.x, this.y, this.z);
for (int k2 = 0; k2 < list.size(); ++k2) {
final Entity entity = list.get(k2);
if (!entity.ignoreExplosion()) {
final double d12 = (double) (Mth.sqrt(entity.distanceToSqr(vec3d)) / f3);
if (d12 <= 1.0D) {
double d5 = entity.getX() - this.x;
double d7 = entity.getEyeY() - this.y;
double d9 = entity.getZ() - this.z;
final double d13 = (double) Mth.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
if (d13 != 0.0D) {
d5 = d5 / d13;
d7 = d7 / d13;
d9 = d9 / d13;
final double d14 = (double) net.minecraft.world.level.Explosion.getSeenPercent(vec3d, entity);
final double d10 = (1.0D - d12) * d14;
entity.hurt(this.shadow$getDamageSource(), (float) ((int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f3 + 1.0D)));
double d11 = d10;
if (entity instanceof LivingEntity) {
d11 = ProtectionEnchantment.getExplosionKnockbackAfterDampener((LivingEntity) entity, d10);
}
// Sponge Start - Honor our knockback value from event
entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11 * this.impl$knockback, d7 * d11 * this.impl$knockback, d9 * d11 * this.impl$knockback));
if (entity instanceof Player) {
final Player playerentity = (Player) entity;
if (!playerentity.isSpectator() && (!playerentity.isCreative() || !playerentity.abilities.flying)) {
this.hitPlayers.put(playerentity, new Vec3(d5 * d10 * this.impl$knockback, d7 * d10 * this.impl$knockback, d9 * d10 * this.impl$knockback));
}
}
// Sponge End
}
}
}
}
}
Aggregations