use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class SpongeEntityArchetype method apply.
@Override
public Optional<org.spongepowered.api.entity.Entity> apply(final ServerLocation location) {
if (!PlatformHooks.INSTANCE.getGeneralHooks().onServerThread()) {
return Optional.empty();
}
final org.spongepowered.api.world.server.ServerWorld spongeWorld = location.world();
final ServerLevel level = (ServerLevel) spongeWorld;
final ResourceLocation key = net.minecraft.world.entity.EntityType.getKey((net.minecraft.world.entity.EntityType<?>) this.type);
if (key == null) {
return Optional.empty();
}
final CompoundTag compound = this.compound.copy();
compound.putString(Constants.Entity.ENTITY_TYPE_ID, key.toString());
final ListTag pos = new ListTag();
pos.add(DoubleTag.valueOf(location.x()));
pos.add(DoubleTag.valueOf(location.y()));
pos.add(DoubleTag.valueOf(location.z()));
compound.put(Constants.Entity.ENTITY_POSITION, pos);
compound.remove(Constants.Entity.ENTITY_UUID);
final boolean requiresInitialSpawn;
if (compound.contains(Constants.Sponge.EntityArchetype.REQUIRES_EXTRA_INITIAL_SPAWN)) {
requiresInitialSpawn = compound.getBoolean(Constants.Sponge.EntityArchetype.REQUIRES_EXTRA_INITIAL_SPAWN);
compound.remove(Constants.Sponge.EntityArchetype.REQUIRES_EXTRA_INITIAL_SPAWN);
} else {
requiresInitialSpawn = true;
}
@Nullable final Entity entity = net.minecraft.world.entity.EntityType.loadEntityRecursive(compound, level, e -> {
e.moveTo(location.x(), location.y(), location.z());
if (requiresInitialSpawn && e instanceof Mob) {
((Mob) e).finalizeSpawn(level, level.getCurrentDifficultyAt(e.blockPosition()), MobSpawnType.COMMAND, null, compound);
}
return e;
});
if (entity == null) {
return Optional.empty();
}
if (level.tryAddFreshEntityWithPassengers(entity)) {
return Optional.of((org.spongepowered.api.entity.Entity) entity);
}
return Optional.empty();
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class EntityTickPhaseState method postBlockTransactionApplication.
@Override
public void postBlockTransactionApplication(final EntityTickContext context, final BlockChange blockChange, final BlockTransactionReceipt transaction) {
if (blockChange == BlockChange.BREAK) {
final Entity tickingEntity = context.getSource(Entity.class).get();
final BlockPos blockPos = VecHelper.toBlockPos(transaction.originalBlock().position());
final List<HangingEntity> hangingEntities = ((ServerLevel) tickingEntity.world()).getEntitiesOfClass(HangingEntity.class, new AABB(blockPos, blockPos).inflate(1.1D, 1.1D, 1.1D), entityIn -> {
if (entityIn == null) {
return false;
}
final BlockPos entityPos = entityIn.getPos();
// Hanging Neighbor Entity
if (entityPos.equals(blockPos.offset(0, 1, 0))) {
return true;
}
// Check around source block
final Direction entityFacing = entityIn.getDirection();
if (entityFacing == Direction.NORTH) {
return entityPos.equals(blockPos.offset(Constants.Entity.HANGING_OFFSET_NORTH));
} else if (entityFacing == Direction.SOUTH) {
return entityIn.getPos().equals(blockPos.offset(Constants.Entity.HANGING_OFFSET_SOUTH));
} else if (entityFacing == Direction.WEST) {
return entityIn.getPos().equals(blockPos.offset(Constants.Entity.HANGING_OFFSET_WEST));
} else if (entityFacing == Direction.EAST) {
return entityIn.getPos().equals(blockPos.offset(Constants.Entity.HANGING_OFFSET_EAST));
}
return false;
});
for (final HangingEntity entityHanging : hangingEntities) {
if (entityHanging instanceof ItemFrame) {
final ItemFrame itemFrame = (ItemFrame) entityHanging;
if (!itemFrame.removed) {
((ItemFrameAccessor) itemFrame).invoker$dropItem((net.minecraft.world.entity.Entity) tickingEntity, true);
}
itemFrame.remove();
}
}
}
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class ServerPlayerMixin method impl$onReturnSleep.
@Inject(method = "startSleepInBed", at = @At(value = "RETURN"), cancellable = true)
private void impl$onReturnSleep(final BlockPos param0, final CallbackInfoReturnable<Either<Player.BedSleepingProblem, Unit>> cir) {
final Either<Player.BedSleepingProblem, Unit> returnValue = cir.getReturnValue();
if (returnValue.left().isPresent()) {
switch(returnValue.left().get()) {
case NOT_POSSIBLE_HERE:
case TOO_FAR_AWAY:
case NOT_POSSIBLE_NOW:
case OBSTRUCTED:
case NOT_SAFE:
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.createSleepingEventFailed(currentCause, snapshot, (Living) this))) {
final Either<Player.BedSleepingProblem, Unit> var5 = super.shadow$startSleepInBed(param0).ifRight((param0x) -> {
this.shadow$awardStat(Stats.SLEEP_IN_BED);
CriteriaTriggers.SLEPT_IN_BED.trigger((net.minecraft.server.level.ServerPlayer) (Object) this);
});
((ServerLevel) this.level).updateSleepingPlayerList();
cir.setReturnValue(var5);
}
break;
case // ignore
OTHER_PROBLEM:
break;
}
}
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class TeleportCommandMixin method performTeleport.
/**
* @author Zidane
* @reason Have the teleport command respect our events
*/
@Overwrite
private static void performTeleport(CommandSourceStack source, Entity entityIn, ServerLevel worldIn, double x, double y, double z, Set<ClientboundPlayerPositionPacket.RelativeArgument> relativeList, float yaw, float pitch, @Nullable TeleportCommand.LookAt facing) {
double actualX = x;
double actualY = y;
double actualZ = z;
double actualYaw = yaw;
double actualPitch = pitch;
if (!(entityIn instanceof ServerPlayer)) {
actualYaw = Mth.wrapDegrees(yaw);
actualPitch = Mth.wrapDegrees(pitch);
actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F);
}
if (worldIn == entityIn.level) {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
if (ShouldFire.MOVE_ENTITY_EVENT) {
final MoveEntityEvent posEvent = SpongeEventFactory.createMoveEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, VecHelper.toVector3d(entityIn.position()), new Vector3d(x, y, z), new Vector3d(x, y, z));
if (SpongeCommon.post(posEvent)) {
return;
}
actualX = posEvent.destinationPosition().x();
actualY = posEvent.destinationPosition().y();
actualZ = posEvent.destinationPosition().z();
}
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(actualPitch, actualYaw, 0), new Vector3d(pitch, yaw, 0));
SpongeCommon.post(rotateEvent);
actualYaw = rotateEvent.isCancelled() ? entityIn.yRot : rotateEvent.toRotation().y();
actualPitch = rotateEvent.isCancelled() ? entityIn.xRot : rotateEvent.toRotation().x();
}
if (entityIn instanceof ServerPlayer) {
ChunkPos chunkpos = new ChunkPos(new BlockPos(actualX, actualY, actualZ));
worldIn.getChunkSource().addRegionTicket(TicketType.POST_TELEPORT, chunkpos, 1, entityIn.getId());
entityIn.stopRiding();
if (((ServerPlayer) entityIn).isSleeping()) {
((ServerPlayer) entityIn).stopSleepInBed(true, true);
}
((ServerPlayer) entityIn).connection.teleport(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch, relativeList);
} else {
entityIn.moveTo(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch);
}
entityIn.setYHeadRot((float) actualYaw);
}
} else {
if (entityIn instanceof ServerPlayer) {
// To ensure mod code is caught, handling the world change for players happens in teleport
// Teleport will create a frame but we want to ensure it'll be the command movement type
// TODO check if this is still correct
PhaseTracker.getCauseStackManager().addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
((ServerPlayer) entityIn).teleportTo(worldIn, x, y, z, yaw, pitch);
PhaseTracker.getCauseStackManager().removeContext(EventContextKeys.MOVEMENT_TYPE);
} else {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
final ServerLevel fromWorld = (ServerLevel) entityIn.getCommandSenderWorld();
final ChangeEntityWorldEvent.Pre preEvent = PlatformHooks.INSTANCE.getEventHooks().callChangeEntityWorldEventPre(entityIn, worldIn);
if (SpongeCommon.post(preEvent)) {
return;
}
final ChangeEntityWorldEvent.Reposition posEvent = SpongeEventFactory.createChangeEntityWorldEventReposition(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, (org.spongepowered.api.world.server.ServerWorld) entityIn.getCommandSenderWorld(), VecHelper.toVector3d(entityIn.position()), new Vector3d(x, y, z), preEvent.originalDestinationWorld(), new Vector3d(x, y, z), preEvent.destinationWorld());
if (SpongeCommon.post(posEvent)) {
return;
}
entityIn.unRide();
final Entity result = entityIn.getType().create(worldIn);
if (result == null) {
return;
}
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(entityIn.xRot, entityIn.yRot, 0), new Vector3d(actualPitch, actualYaw, 0));
if (!SpongeCommon.post(rotateEvent)) {
actualYaw = Mth.wrapDegrees(rotateEvent.toRotation().y());
actualPitch = Mth.wrapDegrees(rotateEvent.toRotation().x());
actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F);
} else {
actualYaw = entityIn.yRot;
actualPitch = entityIn.xRot;
}
}
result.restoreFrom(entityIn);
result.moveTo(posEvent.destinationPosition().x(), posEvent.destinationPosition().y(), posEvent.destinationPosition().z(), (float) actualYaw, (float) actualPitch);
result.setYHeadRot((float) actualYaw);
worldIn.addFromAnotherDimension(result);
entityIn.removed = true;
Sponge.eventManager().post(SpongeEventFactory.createChangeEntityWorldEventPost(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.entity.Entity) result, (ServerWorld) fromWorld, preEvent.originalDestinationWorld(), preEvent.destinationWorld()));
}
}
}
if (facing != null) {
facing.perform(source, entityIn);
}
if (!(entityIn instanceof LivingEntity) || !((LivingEntity) entityIn).isFallFlying()) {
entityIn.setDeltaMovement(entityIn.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
entityIn.setOnGround(true);
}
if (entityIn instanceof PathfinderMob) {
((PathfinderMob) entityIn).getNavigation().stop();
}
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class MinecraftServerMixin method saveAllChunks.
/**
* @author Zidane - November, 24th 2020 - Minecraft 1.15
* @reason To allow per-world auto-save tick intervals or disable auto-saving entirely
*/
@Overwrite
public boolean saveAllChunks(final boolean suppressLog, final boolean flush, final boolean isForced) {
boolean var0 = false;
for (final ServerLevel world : this.shadow$getAllLevels()) {
final SerializationBehavior serializationBehavior = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$serializationBehavior().orElse(SerializationBehavior.AUTOMATIC);
final InheritableConfigHandle<WorldConfig> adapter = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$configAdapter();
// Sponge start - use our own config
boolean log = adapter.get().world.logAutoSave;
// by a command, save our configs
if (!this.shadow$isRunning() || this.tickCount % 6000 == 0 || isForced) {
((PrimaryLevelDataBridge) world.getLevelData()).bridge$configAdapter().save();
}
final boolean canSaveAtAll = serializationBehavior != SerializationBehavior.NONE;
// This world is set to not save of any time, no reason to check the auto-save/etc, skip it
if (!canSaveAtAll) {
continue;
}
// Only run auto-save skipping if the server is still running and the save is not forced
if (this.bridge$performAutosaveChecks() && !isForced) {
final int autoSaveInterval = adapter.get().world.autoSaveInterval;
// Do not process properties or chunks if the world is not set to do so unless the server is shutting down
if (autoSaveInterval <= 0 || serializationBehavior != SerializationBehavior.AUTOMATIC) {
continue;
}
// Now check the interval vs the tick counter and skip it
if (this.tickCount % autoSaveInterval != 0) {
continue;
}
}
if (log) {
LOGGER.info("Saving chunks for level '{}'/{}", world, world.dimension().location());
}
world.save((ProgressListener) null, flush, world.noSave && !isForced);
var0 = true;
}
// Save the usercache.json file every 10 minutes or if forced to
if (isForced || this.tickCount % 6000 == 0) {
// We want to save the username cache json, as we normally bypass it.
((GameProfileCacheBridge) this.profileCache).bridge$setCanSave(true);
this.profileCache.save();
((GameProfileCacheBridge) this.profileCache).bridge$setCanSave(false);
}
return var0;
}
Aggregations