Search in sources :

Example 1 with TickableBlockEntity

use of net.minecraft.world.level.block.entity.TickableBlockEntity in project SpongeCommon by SpongePowered.

the class TrackingUtil method tickTileEntity.

@SuppressWarnings({ "unused", "try" })
public static void tickTileEntity(final TrackedWorldBridge mixinWorldServer, final TickableBlockEntity tile) {
    checkArgument(tile instanceof BlockEntity, "ITickable %s is not a TileEntity!", tile);
    checkNotNull(tile, "Cannot capture on a null ticking tile entity!");
    final net.minecraft.world.level.block.entity.BlockEntity tileEntity = (net.minecraft.world.level.block.entity.BlockEntity) tile;
    final BlockEntityBridge mixinTileEntity = (BlockEntityBridge) tile;
    final BlockPos pos = tileEntity.getBlockPos();
    final LevelChunkBridge chunk = ((ActiveChunkReferantBridge) tile).bridge$getActiveChunk();
    if (!((TrackableBridge) tileEntity).bridge$shouldTick()) {
        return;
    }
    if (chunk == null) {
        ((ActiveChunkReferantBridge) tile).bridge$setActiveChunk((TrackedLevelChunkBridge) tileEntity.getLevel().getChunkAt(tileEntity.getBlockPos()));
    }
    final TileEntityTickContext context = TickPhase.Tick.TILE_ENTITY.createPhaseContext(PhaseTracker.SERVER).source(mixinTileEntity);
    try (final PhaseContext<?> phaseContext = context) {
        if (tile instanceof CreatorTrackedBridge) {
            // Add notifier and owner so we don't have to perform lookups during the phases and other processing
            ((CreatorTrackedBridge) tile).tracker$getNotifierUUID().ifPresent(phaseContext::notifier);
            // Allow the tile entity to validate the owner of itself. As long as the tile entity
            // chunk is already loaded and activated, and the tile entity has already loaded
            // the owner of itself.
            ((CreatorTrackedBridge) tile).tracker$getCreatorUUID().ifPresent(phaseContext::creator);
        }
        // Finally, switch the context now that we have the owner and notifier
        phaseContext.buildAndSwitch();
        try (final Timing timing = ((TimingBridge) tileEntity.getType()).bridge$timings().startTiming()) {
            tile.tick();
        }
        // otherwise the viewing players update this during their ticking
        if (tileEntity instanceof ViewableInventoryBridge) {
            final Set<ServerPlayer> players = ((ViewableInventoryBridge) tileEntity).viewableBridge$getViewers();
            if (players.size() > 0) {
                players.forEach(player -> player.containerMenu.broadcastChanges());
            }
        }
    } catch (final Exception e) {
        PhasePrinter.printExceptionFromPhase(PhaseTracker.getInstance().stack, e, context);
    }
    // We delay clearing active chunk if TE is invalidated during tick so we must remove it after
    if (tileEntity.isRemoved()) {
        ((ActiveChunkReferantBridge) tileEntity).bridge$setActiveChunk(null);
    }
}
Also used : CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) BlockEntityBridge(org.spongepowered.common.bridge.world.level.block.entity.BlockEntityBridge) ActiveChunkReferantBridge(org.spongepowered.common.bridge.world.level.chunk.ActiveChunkReferantBridge) ViewableInventoryBridge(org.spongepowered.common.bridge.world.inventory.ViewableInventoryBridge) ServerPlayer(net.minecraft.server.level.ServerPlayer) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) TrackedLevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge) Timing(co.aikar.timings.Timing) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext) TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) BlockEntity(org.spongepowered.api.block.entity.BlockEntity)

Example 2 with TickableBlockEntity

use of net.minecraft.world.level.block.entity.TickableBlockEntity in project SpongeCommon by SpongePowered.

the class AddTileEntityToTickableListEffect method processSideEffect.

@Override
public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag, final int limit) {
    final ServerLevel serverWorld = pipeline.getServerWorld();
    final BlockEntity tileEntity = oldState.tileEntity;
    if (tileEntity == null) {
        return EffectResult.NULL_RETURN;
    }
    if (tileEntity instanceof TickableBlockEntity) {
        serverWorld.tickableBlockEntities.add(tileEntity);
    }
    return EffectResult.NULL_PASS;
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity)

Aggregations

TickableBlockEntity (net.minecraft.world.level.block.entity.TickableBlockEntity)2 Timing (co.aikar.timings.Timing)1 BlockPos (net.minecraft.core.BlockPos)1 ServerLevel (net.minecraft.server.level.ServerLevel)1 ServerPlayer (net.minecraft.server.level.ServerPlayer)1 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)1 BlockEntity (org.spongepowered.api.block.entity.BlockEntity)1 CreatorTrackedBridge (org.spongepowered.common.bridge.CreatorTrackedBridge)1 ViewableInventoryBridge (org.spongepowered.common.bridge.world.inventory.ViewableInventoryBridge)1 BlockEntityBridge (org.spongepowered.common.bridge.world.level.block.entity.BlockEntityBridge)1 ActiveChunkReferantBridge (org.spongepowered.common.bridge.world.level.chunk.ActiveChunkReferantBridge)1 LevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)1 TrackedLevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge)1 TileEntityTickContext (org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext)1