Search in sources :

Example 36 with WorldServer

use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.

the class TrackingUtil method randomTickBlock.

public static void randomTickBlock(PhaseTracker phaseTracker, IMixinWorldServer mixinWorld, Block block, BlockPos pos, IBlockState state, Random random) {
    final WorldServer minecraftWorld = mixinWorld.asMinecraftWorld();
    try (@SuppressWarnings("unused") StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(minecraftWorld);
        if (ShouldFire.TICK_BLOCK_EVENT) {
            final BlockSnapshot currentTickBlock = mixinWorld.createSpongeBlockSnapshot(state, state, pos, BlockChangeFlags.NONE);
            final TickBlockEvent event = SpongeEventFactory.createTickBlockEventRandom(Sponge.getCauseStackManager().getCurrentCause(), currentTickBlock);
            SpongeImpl.postEvent(event);
            if (event.isCancelled()) {
                return;
            }
        }
        final LocatableBlock locatable = LocatableBlock.builder().location(new Location<>(mixinWorld.asSpongeWorld(), pos.getX(), pos.getY(), pos.getZ())).state((BlockState) state).build();
        Sponge.getCauseStackManager().pushCause(locatable);
        IPhaseState<BlockTickContext> phase = ((IMixinBlock) block).requiresBlockCapture() ? TickPhase.Tick.RANDOM_BLOCK : TickPhase.Tick.NO_CAPTURE_BLOCK;
        final BlockTickContext phaseContext = phase.createPhaseContext().source(locatable);
        checkAndAssignBlockTickConfig(block, minecraftWorld, phaseContext);
        // We have to associate any notifiers in case of scheduled block updates from other sources
        final PhaseData current = phaseTracker.getCurrentPhaseData();
        final IPhaseState<?> currentState = current.state;
        ((IPhaseState) currentState).appendNotifierPreBlockTick(mixinWorld, pos, current.context, phaseContext);
        // Now actually switch to the new phase
        try (PhaseContext<?> context = phaseContext.buildAndSwitch()) {
            block.randomTick(minecraftWorld, pos, state, random);
        } catch (Exception | NoClassDefFoundError e) {
            phaseTracker.printExceptionFromPhase(e, phaseContext);
        }
    }
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) WorldServer(net.minecraft.world.WorldServer) TickBlockEvent(org.spongepowered.api.event.block.TickBlockEvent) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) BlockTickContext(org.spongepowered.common.event.tracking.phase.tick.BlockTickContext) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) LocatableBlock(org.spongepowered.api.world.LocatableBlock)

Example 37 with WorldServer

use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.

the class TrackingUtil method spawnItemDataForBlockDrops.

public static void spawnItemDataForBlockDrops(Collection<ItemDropData> itemStacks, BlockSnapshot oldBlockSnapshot, PhaseContext<?> phaseContext, IPhaseState<?> state) {
    final Vector3i position = oldBlockSnapshot.getPosition();
    final List<ItemStackSnapshot> itemSnapshots = itemStacks.stream().map(ItemDropData::getStack).map(ItemStackUtil::snapshotOf).collect(Collectors.toList());
    final ImmutableList<ItemStackSnapshot> originalSnapshots = ImmutableList.copyOf(itemSnapshots);
    Sponge.getCauseStackManager().pushCause(oldBlockSnapshot);
    final DropItemEvent.Pre dropItemEventPre = SpongeEventFactory.createDropItemEventPre(Sponge.getCauseStackManager().getCurrentCause(), originalSnapshots, itemSnapshots);
    Sponge.getCauseStackManager().popCause();
    SpongeImpl.postEvent(dropItemEventPre);
    if (dropItemEventPre.isCancelled()) {
        return;
    }
    final World world = oldBlockSnapshot.getLocation().get().getExtent();
    final WorldServer worldServer = (WorldServer) world;
    // Now we can spawn the entity items appropriately
    final List<Entity> itemDrops = itemStacks.stream().map(itemStack -> {
        final net.minecraft.item.ItemStack minecraftStack = itemStack.getStack();
        float f = 0.5F;
        double offsetX = worldServer.rand.nextFloat() * f + (1.0F - f) * 0.5D;
        double offsetY = worldServer.rand.nextFloat() * f + (1.0F - f) * 0.5D;
        double offsetZ = worldServer.rand.nextFloat() * f + (1.0F - f) * 0.5D;
        final double x = position.getX() + offsetX;
        final double y = position.getY() + offsetY;
        final double z = position.getZ() + offsetZ;
        EntityItem entityitem = new EntityItem(worldServer, x, y, z, minecraftStack);
        entityitem.setDefaultPickupDelay();
        return entityitem;
    }).map(EntityUtil::fromNative).collect(Collectors.toList());
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(oldBlockSnapshot);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.DROPPED_ITEM);
        if (phaseContext.getNotifier().isPresent()) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, phaseContext.getNotifier().get());
        }
        final User entityCreator = phaseContext.getNotifier().orElseGet(() -> phaseContext.getOwner().orElse(null));
        final DropItemEvent.Destruct destruct = SpongeEventFactory.createDropItemEventDestruct(Sponge.getCauseStackManager().getCurrentCause(), itemDrops);
        SpongeImpl.postEvent(destruct);
        if (!destruct.isCancelled()) {
            for (Entity entity : destruct.getEntities()) {
                if (entityCreator != null) {
                    EntityUtil.toMixin(entity).setCreator(entityCreator.getUniqueId());
                }
                EntityUtil.getMixinWorld(entity).forceSpawnEntity(entity);
            }
        }
    }
}
Also used : DropItemEvent(org.spongepowered.api.event.item.inventory.DropItemEvent) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) Entity(org.spongepowered.api.entity.Entity) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) WorldServer(net.minecraft.world.WorldServer) World(org.spongepowered.api.world.World) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Vector3i(com.flowpowered.math.vector.Vector3i) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) EntityItem(net.minecraft.entity.item.EntityItem)

Example 38 with WorldServer

use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.

the class TrackingUtil method performBlockAdditions.

@SuppressWarnings("rawtypes")
public static boolean performBlockAdditions(List<Transaction<BlockSnapshot>> transactions, IPhaseState<?> phaseState, PhaseContext<?> phaseContext, boolean noCancelledTransactions) {
    // We have to use a proxy so that our pending changes are notified such that any accessors from block
    // classes do not fail on getting the incorrect block state from the IBlockAccess
    // final SpongeProxyBlockAccess proxyBlockAccess = new SpongeProxyBlockAccess(transactions);
    final CapturedMultiMapSupplier<BlockPos, ItemDropData> capturedBlockDrops = phaseContext.getBlockDropSupplier();
    final CapturedMultiMapSupplier<BlockPos, EntityItem> capturedBlockItemEntityDrops = phaseContext.getBlockItemDropSupplier();
    final CapturedMultiMapSupplier<BlockPos, net.minecraft.entity.Entity> capturedBlockEntitySpawns = phaseContext.getBlockEntitySpawnSupplier();
    for (Transaction<BlockSnapshot> transaction : transactions) {
        if (!transaction.isValid()) {
            // Rememver that this value needs to be set to false to return because of the fact that
            // a transaction was marked as invalid or cancelled. This is used primarily for
            // things like portal creation, and if false, removes the portal from the cache
            noCancelledTransactions = false;
            // Don't use invalidated block transactions during notifications, these only need to be restored
            continue;
        }
        // Handle custom replacements
        if (transaction.getCustom().isPresent()) {
            transaction.getFinal().restore(true, BlockChangeFlags.NONE);
        }
        final SpongeBlockSnapshot oldBlockSnapshot = (SpongeBlockSnapshot) transaction.getOriginal();
        final SpongeBlockSnapshot newBlockSnapshot = (SpongeBlockSnapshot) transaction.getFinal();
        final Location<World> worldLocation = oldBlockSnapshot.getLocation().get();
        final IMixinWorldServer mixinWorldServer = (IMixinWorldServer) worldLocation.getExtent();
        // Handle item drops captured
        final BlockPos pos = ((IMixinLocation) (Object) oldBlockSnapshot.getLocation().get()).getBlockPos();
        // This is for pre-merged items
        capturedBlockDrops.acceptAndRemoveIfPresent(pos, items -> spawnItemDataForBlockDrops(items, oldBlockSnapshot, phaseContext, phaseState));
        // And this is for un-pre-merged items, these will be EntityItems, not ItemDropDatas.
        capturedBlockItemEntityDrops.acceptAndRemoveIfPresent(pos, items -> spawnItemEntitiesForBlockDrops(items, oldBlockSnapshot, phaseContext, phaseState));
        // This is for entities actually spawned
        capturedBlockEntitySpawns.acceptAndRemoveIfPresent(pos, items -> spawnEntitiesForBlock(items, oldBlockSnapshot, phaseContext, phaseState));
        final WorldServer worldServer = mixinWorldServer.asMinecraftWorld();
        SpongeHooks.logBlockAction(worldServer, oldBlockSnapshot.blockChange, transaction);
        final SpongeBlockChangeFlag changeFlag = oldBlockSnapshot.getChangeFlag();
        final IBlockState originalState = (IBlockState) oldBlockSnapshot.getState();
        final IBlockState newState = (IBlockState) newBlockSnapshot.getState();
        // We call onBlockAdded here for blocks without a TileEntity.
        // MixinChunk#setBlockState will call onBlockAdded for blocks
        // with a TileEntity or when capturing is not being done.
        final PhaseTracker phaseTracker = PhaseTracker.getInstance();
        if (!SpongeImplHooks.hasBlockTileEntity(newState.getBlock(), newState) && changeFlag.performBlockPhysics() && originalState.getBlock() != newState.getBlock()) {
            newState.getBlock().onBlockAdded(worldServer, pos, newState);
            final PhaseData peek = phaseTracker.getCurrentPhaseData();
            if (peek.state == GeneralPhase.Post.UNWINDING) {
                ((IPhaseState) peek.state).unwind(peek.context);
            }
        }
        // proxyBlockAccess.proceed();
        ((IPhaseState) phaseState).handleBlockChangeWithUser(oldBlockSnapshot.blockChange, transaction, phaseContext);
        if (changeFlag.isNotifyClients()) {
            // Always try to notify clients of the change.
            worldServer.notifyBlockUpdate(pos, originalState, newState, changeFlag.getRawFlag());
        }
        if (changeFlag.updateNeighbors()) {
            // Notify neighbors only if the change flag allowed it.
            mixinWorldServer.spongeNotifyNeighborsPostBlockChange(pos, originalState, newState, changeFlag);
        } else if (changeFlag.notifyObservers()) {
            worldServer.updateObservingBlocksAt(pos, newState.getBlock());
        }
        final PhaseData peek = phaseTracker.getCurrentPhaseData();
        if (peek.state == GeneralPhase.Post.UNWINDING) {
            ((IPhaseState) peek.state).unwind(peek.context);
        }
    }
    return noCancelledTransactions;
}
Also used : IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) Entity(org.spongepowered.api.entity.Entity) SpongeBlockChangeFlag(org.spongepowered.common.world.SpongeBlockChangeFlag) IBlockState(net.minecraft.block.state.IBlockState) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) WorldServer(net.minecraft.world.WorldServer) World(org.spongepowered.api.world.World) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockPos(net.minecraft.util.math.BlockPos) ItemDropData(org.spongepowered.common.event.tracking.context.ItemDropData) EntityItem(net.minecraft.entity.item.EntityItem)

Example 39 with WorldServer

use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.

the class ChangingToDimensionState method spawnEntityOrCapture.

@Override
public boolean spawnEntityOrCapture(TeleportingContext context, Entity entity, int chunkX, int chunkZ) {
    final WorldServer worldServer = context.getTargetWorld();
    ((IMixinWorldServer) worldServer).forceSpawnEntity(entity);
    return true;
}
Also used : IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) WorldServer(net.minecraft.world.WorldServer) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer)

Example 40 with WorldServer

use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.

the class ChangingToDimensionState method returnTeleportResult.

@Nullable
@Override
public net.minecraft.entity.Entity returnTeleportResult(PhaseContext<?> context, MoveEntityEvent.Teleport.Portal event) {
    final net.minecraft.entity.Entity teleportingEntity = context.getSource(net.minecraft.entity.Entity.class).orElseThrow(TrackingUtil.throwWithContext("Expected to be teleporting an entity!", context));
    // The rest of this is to be handled in the phase.
    if (event.isCancelled()) {
        return null;
    }
    teleportingEntity.world.profiler.startSection("changeDimension");
    WorldServer toWorld = (WorldServer) event.getToTransform().getExtent();
    teleportingEntity.world.removeEntity(teleportingEntity);
    teleportingEntity.isDead = false;
    teleportingEntity.world.profiler.startSection("reposition");
    final Vector3d position = event.getToTransform().getPosition();
    teleportingEntity.setLocationAndAngles(position.getX(), position.getY(), position.getZ(), (float) event.getToTransform().getYaw(), (float) event.getToTransform().getPitch());
    toWorld.spawnEntity(teleportingEntity);
    teleportingEntity.world = toWorld;
    toWorld.updateEntityWithOptionalForce(teleportingEntity, false);
    teleportingEntity.world.profiler.endStartSection("reloading");
    teleportingEntity.world.profiler.endSection();
    teleportingEntity.world.profiler.endSection();
    return teleportingEntity;
}
Also used : Entity(org.spongepowered.api.entity.Entity) Vector3d(com.flowpowered.math.vector.Vector3d) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) WorldServer(net.minecraft.world.WorldServer) Nullable(javax.annotation.Nullable)

Aggregations

WorldServer (net.minecraft.world.WorldServer)322 BlockPos (net.minecraft.util.math.BlockPos)96 EntityPlayer (net.minecraft.entity.player.EntityPlayer)63 EntityPlayerMP (net.minecraft.entity.player.EntityPlayerMP)51 ItemStack (net.minecraft.item.ItemStack)48 IMixinWorldServer (org.spongepowered.common.interfaces.world.IMixinWorldServer)48 TileEntity (net.minecraft.tileentity.TileEntity)42 Entity (net.minecraft.entity.Entity)41 IBlockState (net.minecraft.block.state.IBlockState)39 MinecraftServer (net.minecraft.server.MinecraftServer)35 NBTTagCompound (net.minecraft.nbt.NBTTagCompound)31 World (net.minecraft.world.World)29 Block (net.minecraft.block.Block)26 EntityLivingBase (net.minecraft.entity.EntityLivingBase)23 ArrayList (java.util.ArrayList)20 SubscribeEvent (net.minecraftforge.fml.common.eventhandler.SubscribeEvent)18 Nullable (javax.annotation.Nullable)17 PotionEffect (net.minecraft.potion.PotionEffect)16 Chunk (net.minecraft.world.chunk.Chunk)16 World (org.spongepowered.api.world.World)13