Search in sources :

Example 1 with BlockStateBridge

use of org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge in project SpongeCommon by SpongePowered.

the class UpdateOrCreateNewTileEntityPostPlacementEffect 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 LevelChunk chunk = pipeline.getAffectedChunk();
    @Nullable final BlockEntity maybeNewTileEntity = chunk.getBlockEntity(oldState.pos, LevelChunk.EntityCreationType.CHECK);
    if (((BlockStateBridge) newState).bridge$hasTileEntity()) {
        if (maybeNewTileEntity == null) {
            // tileentity1 = ((ITileEntityProvider)block).createNewTileEntity(this.world); // Vanilla
            // tileentity1 = state.createTileEntity(this.world); // Forge
            // We cast to our bridge for easy access
            serverWorld.setBlockEntity(oldState.pos, ((BlockStateBridge) newState).bridge$createNewTileEntity(serverWorld));
        } else {
            maybeNewTileEntity.clearCache();
        }
    }
    return EffectResult.NULL_PASS;
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) Nullable(org.checkerframework.checker.nullness.qual.Nullable) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity) BlockStateBridge(org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge)

Example 2 with BlockStateBridge

use of org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge in project SpongeCommon by SpongePowered.

the class ServerLevelMixin_Tracker method tracker$associatePhaseContextDataWithBlockEvent.

@Redirect(method = "blockEvent", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectLinkedOpenHashSet;add(Ljava/lang/Object;)Z", remap = false))
private boolean tracker$associatePhaseContextDataWithBlockEvent(final ObjectLinkedOpenHashSet<BlockEventData> list, final Object data, final BlockPos pos, final Block blockIn, final int eventID, final int eventParam) {
    final PhaseContext<@NonNull ?> currentContext = PhaseTracker.getInstance().getPhaseContext();
    final BlockEventData blockEventData = (BlockEventData) data;
    final TrackableBlockEventDataBridge blockEvent = (TrackableBlockEventDataBridge) blockEventData;
    // Short circuit phase states who do not track during block events
    if (currentContext.ignoresBlockEvent()) {
        return list.add(blockEventData);
    }
    final BlockState state = this.shadow$getBlockState(pos);
    if (((TrackableBridge) blockIn).bridge$allowsBlockEventCreation()) {
        blockEvent.bridge$setSourceUserUUID(currentContext.getActiveUserUUID());
        if (((BlockStateBridge) state).bridge$hasTileEntity()) {
            blockEvent.bridge$setTileEntity((BlockEntity) this.shadow$getBlockEntity(pos));
        }
        if (blockEvent.bridge$getTileEntity() == null) {
            final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((org.spongepowered.api.world.server.ServerWorld) this).position(pos.getX(), pos.getY(), pos.getZ()).state((org.spongepowered.api.block.BlockState) state).build();
            blockEvent.bridge$setTickingLocatable(locatable);
        }
    }
    // allow tracking to take place for other/future phases
    if (!((TrackableBridge) blockIn).bridge$allowsBlockEventCreation()) {
        return list.add((BlockEventData) data);
    }
    // In pursuant with our block updates management, we chose to
    // effectively allow the block event get added to the list, but
    // we log the transaction so that we can call the change block event
    // pre, and if needed, undo the add to the list.
    currentContext.appendNotifierToBlockEvent(this, pos, blockEvent);
    // This is very common with pistons as they add block events while blocks are being notified.
    if (ShouldFire.CHANGE_BLOCK_EVENT_PRE) {
        if (blockIn instanceof PistonBaseBlock) {
            // We only fire pre events for pistons
            if (SpongeCommonEventFactory.handlePistonEvent(this, pos, state, eventID)) {
                return false;
            }
        } else {
            if (SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) this, pos).isCancelled()) {
                return false;
            }
        }
    }
    currentContext.getTransactor().logBlockEvent(state, this, pos, blockEvent);
    return list.add(blockEventData);
}
Also used : SpongeLocatableBlockBuilder(org.spongepowered.common.world.server.SpongeLocatableBlockBuilder) TrackableBlockEventDataBridge(org.spongepowered.common.bridge.world.level.TrackableBlockEventDataBridge) TrackableBridge(org.spongepowered.common.bridge.TrackableBridge) PistonBaseBlock(net.minecraft.world.level.block.piston.PistonBaseBlock) BlockState(net.minecraft.world.level.block.state.BlockState) LocatableBlock(org.spongepowered.api.world.LocatableBlock) ServerLevelBridge(org.spongepowered.common.bridge.server.level.ServerLevelBridge) BlockEventData(net.minecraft.world.level.BlockEventData) BlockStateBridge(org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 3 with BlockStateBridge

use of org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge in project SpongeCommon by SpongePowered.

the class ServerLevelMixin_Tracker method bridge$createSnapshot.

@Override
public SpongeBlockSnapshot bridge$createSnapshot(final net.minecraft.world.level.block.state.BlockState state, final BlockPos pos, final BlockChangeFlag updateFlag) {
    final SpongeBlockSnapshot.BuilderImpl builder = SpongeBlockSnapshot.BuilderImpl.pooled();
    builder.reset();
    builder.blockState(state).world((ServerLevel) (Object) this).position(VecHelper.toVector3i(pos));
    final LevelChunk chunk = this.shadow$getChunkAt(pos);
    if (chunk == null) {
        return builder.flag(updateFlag).build();
    }
    final Optional<UUID> creator = ((LevelChunkBridge) chunk).bridge$getBlockCreatorUUID(pos);
    final Optional<UUID> notifier = ((LevelChunkBridge) chunk).bridge$getBlockNotifierUUID(pos);
    creator.ifPresent(builder::creator);
    notifier.ifPresent(builder::notifier);
    final boolean hasTileEntity = ((BlockStateBridge) state).bridge$hasTileEntity();
    final net.minecraft.world.level.block.entity.BlockEntity tileEntity = chunk.getBlockEntity(pos, LevelChunk.EntityCreationType.CHECK);
    if (hasTileEntity || tileEntity != null) {
        // We MUST only check to see if a TE exists to avoid creating a new one.
        if (tileEntity != null) {
            // TODO - custom data.
            final CompoundTag nbt = new CompoundTag();
            // Some mods like OpenComputers assert if attempting to save robot while moving
            try {
                tileEntity.save(nbt);
                builder.addUnsafeCompound(nbt);
            } catch (final Throwable t) {
            // ignore
            }
        }
    }
    builder.flag(updateFlag);
    return builder.build();
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) TrackedLevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge) UUID(java.util.UUID) CompoundTag(net.minecraft.nbt.CompoundTag) BlockStateBridge(org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge)

Aggregations

BlockStateBridge (org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge)3 ServerLevel (net.minecraft.server.level.ServerLevel)2 LevelChunk (net.minecraft.world.level.chunk.LevelChunk)2 UUID (java.util.UUID)1 CompoundTag (net.minecraft.nbt.CompoundTag)1 BlockEventData (net.minecraft.world.level.BlockEventData)1 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)1 PistonBaseBlock (net.minecraft.world.level.block.piston.PistonBaseBlock)1 BlockState (net.minecraft.world.level.block.state.BlockState)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1 LocatableBlock (org.spongepowered.api.world.LocatableBlock)1 Redirect (org.spongepowered.asm.mixin.injection.Redirect)1 SpongeBlockSnapshot (org.spongepowered.common.block.SpongeBlockSnapshot)1 TrackableBridge (org.spongepowered.common.bridge.TrackableBridge)1 ServerLevelBridge (org.spongepowered.common.bridge.server.level.ServerLevelBridge)1 TrackableBlockEventDataBridge (org.spongepowered.common.bridge.world.level.TrackableBlockEventDataBridge)1 LevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge)1 TrackedLevelChunkBridge (org.spongepowered.common.bridge.world.level.chunk.TrackedLevelChunkBridge)1 SpongeLocatableBlockBuilder (org.spongepowered.common.world.server.SpongeLocatableBlockBuilder)1