use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method callPlaySoundNoteBlockEvent.
public static PlaySoundEvent.NoteBlock callPlaySoundNoteBlockEvent(final Cause cause, final World world, final BlockPos pos, final SoundEvent soundEvent, final InstrumentType instrument, final NotePitch notePitch, final Float pitch) {
final ServerLocation location = ServerLocation.of((ServerWorld) world, pos.getX(), pos.getY(), pos.getZ());
final PlaySoundEvent.NoteBlock event = SpongeEventFactory.createPlaySoundEventNoteBlock(cause, instrument, location, notePitch, Sound.Source.RECORD, (SoundType) soundEvent, pitch, 3.0F);
SpongeCommon.post(event);
return event;
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method handleCollideBlockEvent.
public static boolean handleCollideBlockEvent(final Block block, final Level world, final BlockPos pos, final net.minecraft.world.level.block.state.BlockState state, final net.minecraft.world.entity.Entity entity, final Direction direction, final CollisionType type) {
if (world.isClientSide() || pos.getY() <= 0) {
return false;
}
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.pushCause(entity);
if (entity instanceof CreatorTrackedBridge) {
final CreatorTrackedBridge spongeEntity = (CreatorTrackedBridge) entity;
spongeEntity.tracker$getCreatorUUID().ifPresent(user -> frame.addContext(EventContextKeys.CREATOR, user));
}
// TODO: Add target side support
final ServerLocation loc = ServerLocation.of((ServerWorld) world, VecHelper.toVector3d(pos));
final CollideBlockEvent event;
switch(type) {
case MOVE:
event = SpongeEventFactory.createCollideBlockEventMove(frame.currentCause(), (BlockState) state, loc, direction);
break;
case FALL:
event = SpongeEventFactory.createCollideBlockEventFall(frame.currentCause(), (BlockState) state, loc, direction);
break;
case STEP_ON:
event = SpongeEventFactory.createCollideBlockEventStepOn(frame.currentCause(), (BlockState) state, loc, direction);
break;
case INSIDE:
event = SpongeEventFactory.createCollideBlockEventInside(frame.currentCause(), (BlockState) state, loc, direction);
break;
default:
throw new IllegalArgumentException("Unknown type " + type);
}
final boolean cancelled = SpongeCommon.post(event);
if (!cancelled) {
final EntityBridge spongeEntity = (EntityBridge) entity;
if (!pos.equals(spongeEntity.bridge$getLastCollidedBlockPos())) {
final PhaseContext<?> context = PhaseTracker.getInstance().getPhaseContext();
context.applyNotifierIfAvailable(notifier -> {
LevelChunkBridge spongeChunk = ((ActiveChunkReferantBridge) entity).bridge$getActiveChunk();
if (spongeChunk == null) {
spongeChunk = (LevelChunkBridge) world.getChunkAt(pos);
}
spongeChunk.bridge$addTrackedBlockPosition(block, pos, notifier, PlayerTracker.Type.NOTIFIER);
});
}
}
return cancelled;
}
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method callPlaySoundAtEntityEvent.
@SuppressWarnings("ConstantConditions")
public static PlaySoundEvent.AtEntity callPlaySoundAtEntityEvent(final Cause cause, final net.minecraft.world.entity.player.@Nullable Player entity, final LevelBridge worldMixin, final double x, final double y, final double z, final net.minecraft.sounds.SoundSource category, final SoundEvent name, final float pitch, final float volume) {
final ServerLocation location = ServerLocation.of((ServerWorld) worldMixin, x, y, z);
final PlaySoundEvent.AtEntity event = SpongeEventFactory.createPlaySoundEventAtEntity(cause, location, Optional.ofNullable((ServerPlayer) entity), SpongeAdventure.asAdventure(category), (SoundType) name, pitch, volume);
SpongeCommon.post(event);
return event;
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method handlePistonEvent.
/**
* This simulates the blocks a piston moves and calls the event for saner
* debugging.
*
* @return if the event was cancelled
*/
public static boolean handlePistonEvent(final TrackedWorldBridge world, final BlockPos pos, final net.minecraft.world.level.block.state.BlockState blockstate, final int eventId) {
final boolean extending = (eventId == 0);
final net.minecraft.core.Direction direction = blockstate.getValue(DirectionalBlock.FACING);
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((ServerWorld) world).state((BlockState) blockstate).position(pos.getX(), pos.getY(), pos.getZ()).build();
// Sets toss out duplicate values (even though there shouldn't be any)
final HashSet<ServerLocation> locations = new HashSet<>();
locations.add(ServerLocation.of((ServerWorld) world, pos.getX(), pos.getY(), pos.getZ()));
final PistonStructureResolver movedBlocks = new PistonStructureResolver((ServerLevel) world, pos, direction, extending);
// calculates blocks to be moved
movedBlocks.resolve();
Stream.concat(movedBlocks.getToPush().stream(), movedBlocks.getToDestroy().stream()).map(block -> ServerLocation.of((ServerWorld) world, block.getX(), block.getY(), block.getZ())).collect(// SUPER
Collectors.toCollection(() -> locations));
// If the piston is extending and there are no blocks to destroy, add the offset location for protection purposes
if (extending && movedBlocks.getToDestroy().isEmpty()) {
final List<BlockPos> movedPositions = movedBlocks.getToPush();
final BlockPos offsetPos;
// If there are no blocks to move, add the offset of piston
if (movedPositions.isEmpty()) {
offsetPos = pos.relative(direction);
} else {
// Add the offset of last block set to move
offsetPos = movedPositions.get(movedPositions.size() - 1).relative(direction);
}
locations.add(ServerLocation.of((ServerWorld) world, offsetPos.getX(), offsetPos.getY(), offsetPos.getZ()));
}
try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) {
if (extending) {
frame.addContext(EventContextKeys.PISTON_EXTEND, (ServerWorld) world);
} else {
frame.addContext(EventContextKeys.PISTON_RETRACT, (ServerWorld) world);
}
return SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, ImmutableList.copyOf(locations), locatable).isCancelled();
}
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class EnderMan_EndermanLeaveBlockGoalMixin method impl$onPlaceBlockCancel.
/**
* @reason Makes Endermen check for block changes before they can place their blocks.
* This allows plugins to cancel the event regardless without issue.
*/
@Redirect(method = "canPlaceBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;isCollisionShapeFullBlock(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z"))
private boolean impl$onPlaceBlockCancel(BlockState blockState, BlockGetter blockReaderIn, BlockPos blockPosIn) {
if (blockState.isCollisionShapeFullBlock(blockReaderIn, blockPosIn)) {
// Sponge start
if (ShouldFire.CHANGE_BLOCK_EVENT_PRE) {
final ServerLocation location = ServerLocation.of((ServerWorld) blockReaderIn, blockPosIn.getX(), blockPosIn.getY(), blockPosIn.getZ());
final List<ServerLocation> list = new ArrayList<>(1);
list.add(location);
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final ChangeBlockEvent.Pre event = SpongeEventFactory.createChangeBlockEventPre(cause, list, ((ServerWorld) this.enderman.level));
return !SpongeCommon.post(event);
}
// Sponge end
return true;
}
return false;
}
Aggregations