Search in sources :

Example 6 with LocatableBlock

use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.

the class PlaceBlockPacketState method addNotifierToBlockEvent.

@Override
public void addNotifierToBlockEvent(BasicPacketContext context, IMixinWorldServer mixinWorldServer, BlockPos pos, IMixinBlockEventData blockEvent) {
    final Player player = Sponge.getCauseStackManager().getCurrentCause().first(Player.class).get();
    final Location<World> location = new Location<>(player.getWorld(), pos.getX(), pos.getY(), pos.getZ());
    final LocatableBlock locatableBlock = LocatableBlock.builder().location(location).state(location.getBlock()).build();
    blockEvent.setTickBlock(locatableBlock);
    blockEvent.setSourceUser(player);
}
Also used : Player(org.spongepowered.api.entity.living.player.Player) LocatableBlock(org.spongepowered.api.world.LocatableBlock) World(org.spongepowered.api.world.World) Location(org.spongepowered.api.world.Location) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation)

Example 7 with LocatableBlock

use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.

the class BlockTickPhaseState method spawnEntityOrCapture.

@Override
public boolean spawnEntityOrCapture(BlockTickContext context, Entity entity, int chunkX, int chunkZ) {
    final LocatableBlock locatableBlock = getLocatableBlockSourceFromContext(context);
    final Optional<User> owner = context.getOwner();
    final Optional<User> notifier = context.getNotifier();
    final User entityCreator = notifier.orElseGet(() -> owner.orElse(null));
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(locatableBlock);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.EXPERIENCE);
        if (notifier.isPresent()) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier.get());
        }
        if (owner.isPresent()) {
            Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner.get());
        }
        if (entity instanceof EntityXPOrb) {
            final ArrayList<Entity> entities = new ArrayList<>(1);
            entities.add(entity);
            final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
            SpongeImpl.postEvent(event);
            if (!event.isCancelled()) {
                for (Entity anEntity : event.getEntities()) {
                    if (entityCreator != null) {
                        EntityUtil.toMixin(anEntity).setCreator(entityCreator.getUniqueId());
                    }
                    EntityUtil.getMixinWorld(entity).forceSpawnEntity(anEntity);
                }
                return true;
            }
            return false;
        }
        final List<Entity> nonExpEntities = new ArrayList<>(1);
        nonExpEntities.add(entity);
        Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, InternalSpawnTypes.BLOCK_SPAWNING);
        final SpawnEntityEvent spawnEntityEvent = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), nonExpEntities);
        SpongeImpl.postEvent(spawnEntityEvent);
        if (!spawnEntityEvent.isCancelled()) {
            for (Entity anEntity : spawnEntityEvent.getEntities()) {
                if (entityCreator != null) {
                    EntityUtil.toMixin(anEntity).setCreator(entityCreator.getUniqueId());
                }
                EntityUtil.getMixinWorld(entity).forceSpawnEntity(anEntity);
            }
            return true;
        }
    }
    return false;
}
Also used : Entity(org.spongepowered.api.entity.Entity) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) CauseStackManager(org.spongepowered.api.event.CauseStackManager) ArrayList(java.util.ArrayList) LocatableBlock(org.spongepowered.api.world.LocatableBlock) SpawnEntityEvent(org.spongepowered.api.event.entity.SpawnEntityEvent) EntityXPOrb(net.minecraft.entity.item.EntityXPOrb)

Example 8 with LocatableBlock

use of org.spongepowered.api.world.LocatableBlock in project SpongeForge by SpongePowered.

the class SpongeForgeEventFactory method callNeighborNotifyEvent.

public static NotifyNeighborBlockEvent callNeighborNotifyEvent(Event event) {
    NotifyNeighborBlockEvent spongeEvent = (NotifyNeighborBlockEvent) event;
    LocatableBlock locatableBlock = spongeEvent.getCause().first(LocatableBlock.class).orElse(null);
    TileEntity tileEntitySource = spongeEvent.getCause().first(TileEntity.class).orElse(null);
    Location<World> sourceLocation = null;
    IBlockState state = null;
    if (locatableBlock != null) {
        Location<World> location = locatableBlock.getLocation();
        sourceLocation = location;
        state = (IBlockState) locatableBlock.getBlockState();
    } else if (tileEntitySource != null) {
        sourceLocation = tileEntitySource.getLocation();
        state = (IBlockState) sourceLocation.getBlock();
    } else {
        // should never happen but just in case it does
        return spongeEvent;
    }
    EnumSet<EnumFacing> facings = EnumSet.noneOf(EnumFacing.class);
    for (Map.Entry<Direction, BlockState> mapEntry : spongeEvent.getNeighbors().entrySet()) {
        if (mapEntry.getKey() != Direction.NONE) {
            facings.add(DirectionFacingProvider.getInstance().get(mapEntry.getKey()).get());
        }
    }
    if (facings.isEmpty()) {
        return spongeEvent;
    }
    BlockPos pos = ((IMixinLocation) (Object) sourceLocation).getBlockPos();
    net.minecraft.world.World world = (net.minecraft.world.World) sourceLocation.getExtent();
    // TODO - the boolean forced redstone bit needs to be set properly
    final NeighborNotifyEvent forgeEvent = new NeighborNotifyEvent(world, pos, state, facings, false);
    ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
    if (forgeEvent.isCanceled()) {
        spongeEvent.setCancelled(true);
    }
    return spongeEvent;
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) EnumFacing(net.minecraft.util.EnumFacing) World(org.spongepowered.api.world.World) IMixinWorld(org.spongepowered.common.interfaces.world.IMixinWorld) Direction(org.spongepowered.api.util.Direction) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinEventBus(org.spongepowered.mod.interfaces.IMixinEventBus) NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) NeighborNotifyEvent(net.minecraftforge.event.world.BlockEvent.NeighborNotifyEvent) LocatableBlock(org.spongepowered.api.world.LocatableBlock) BlockPos(net.minecraft.util.math.BlockPos) Map(java.util.Map)

Example 9 with LocatableBlock

use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.

the class TrackingUtil method updateTickBlock.

public static void updateTickBlock(IMixinWorldServer mixinWorld, Block block, BlockPos pos, IBlockState state, Random random) {
    final WorldServer minecraftWorld = mixinWorld.asMinecraftWorld();
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(minecraftWorld);
        if (ShouldFire.TICK_BLOCK_EVENT) {
            BlockSnapshot snapshot = mixinWorld.createSpongeBlockSnapshot(state, state, pos, BlockChangeFlags.NONE);
            final TickBlockEvent event = SpongeEventFactory.createTickBlockEventScheduled(Sponge.getCauseStackManager().getCurrentCause(), snapshot);
            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.BLOCK : TickPhase.Tick.NO_CAPTURE_BLOCK;
        final BlockTickContext phaseContext = phase.createPhaseContext().source(locatable);
        checkAndAssignBlockTickConfig(block, minecraftWorld, phaseContext);
        final PhaseTracker phaseTracker = PhaseTracker.getInstance();
        // 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);
        try (PhaseContext<?> context = phaseContext.buildAndSwitch()) {
            block.updateTick(minecraftWorld, pos, state, random);
        } catch (Exception | NoClassDefFoundError e) {
            phaseTracker.printExceptionFromPhase(e, phaseContext);
        }
    }
}
Also used : StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) 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) CauseStackManager(org.spongepowered.api.event.CauseStackManager) LocatableBlock(org.spongepowered.api.world.LocatableBlock)

Example 10 with LocatableBlock

use of org.spongepowered.api.world.LocatableBlock in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method callNotifyNeighborEvent.

@SuppressWarnings("rawtypes")
public static NotifyNeighborBlockEvent callNotifyNeighborEvent(World world, BlockPos sourcePos, EnumSet notifiedSides) {
    final PhaseTracker phaseTracker = PhaseTracker.getInstance();
    final PhaseData peek = phaseTracker.getCurrentPhaseData();
    final PhaseContext<?> context = peek.context;
    // Don't fire notify events during world gen or while restoring
    if (peek.state.isWorldGeneration() || peek.state == State.RESTORING_BLOCKS) {
        return null;
    }
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        final BlockState blockstate = (BlockState) ((net.minecraft.world.World) world).getBlockState(sourcePos);
        final LocatableBlock locatable = LocatableBlock.builder().location(new Location<World>(world, sourcePos.getX(), sourcePos.getY(), sourcePos.getZ())).state(blockstate).build();
        if (context.getNotifier().isPresent()) {
            context.addNotifierAndOwnerToCauseStack();
        } else {
            final IMixinChunk mixinChunk = (IMixinChunk) ((WorldServer) world).getChunkFromBlockCoords(sourcePos);
            mixinChunk.getBlockNotifier(sourcePos).ifPresent(user -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, user));
            mixinChunk.getBlockOwner(sourcePos).ifPresent(owner -> Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner));
        }
        Sponge.getCauseStackManager().pushCause(locatable);
        final Map<Direction, BlockState> neighbors = new HashMap<>();
        for (Object obj : notifiedSides) {
            EnumFacing notifiedSide = (EnumFacing) obj;
            BlockPos offset = sourcePos.offset(notifiedSide);
            Direction direction = DirectionFacingProvider.getInstance().getKey(notifiedSide).get();
            Location<World> location = new Location<>(world, VecHelper.toVector3i(offset));
            if (location.getBlockY() >= 0 && location.getBlockY() <= 255) {
                neighbors.put(direction, location.getBlock());
            }
        }
        // ImmutableMap<Direction, BlockState> originalNeighbors =
        // ImmutableMap.copyOf(neighbors);
        NotifyNeighborBlockEvent event = SpongeEventFactory.createNotifyNeighborBlockEvent(Sponge.getCauseStackManager().getCurrentCause(), neighbors, neighbors);
        SpongeImpl.postEvent(event);
        return event;
    }
}
Also used : PhaseData(org.spongepowered.common.event.tracking.PhaseData) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) HashMap(java.util.HashMap) EnumFacing(net.minecraft.util.EnumFacing) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) BlockState(org.spongepowered.api.block.BlockState) IBlockState(net.minecraft.block.state.IBlockState) NotifyNeighborBlockEvent(org.spongepowered.api.event.block.NotifyNeighborBlockEvent) CauseStackManager(org.spongepowered.api.event.CauseStackManager) LocatableBlock(org.spongepowered.api.world.LocatableBlock) IInteractionObject(net.minecraft.world.IInteractionObject) BlockPos(net.minecraft.util.math.BlockPos) Location(org.spongepowered.api.world.Location)

Aggregations

LocatableBlock (org.spongepowered.api.world.LocatableBlock)18 IBlockState (net.minecraft.block.state.IBlockState)8 StackFrame (org.spongepowered.api.event.CauseStackManager.StackFrame)8 BlockState (org.spongepowered.api.block.BlockState)7 World (org.spongepowered.api.world.World)7 IMixinWorldServer (org.spongepowered.common.interfaces.world.IMixinWorldServer)7 CauseStackManager (org.spongepowered.api.event.CauseStackManager)6 Entity (org.spongepowered.api.entity.Entity)5 User (org.spongepowered.api.entity.living.player.User)5 Location (org.spongepowered.api.world.Location)5 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)5 ArrayList (java.util.ArrayList)4 BlockSnapshot (org.spongepowered.api.block.BlockSnapshot)4 TileEntity (org.spongepowered.api.block.tileentity.TileEntity)4 IMixinChunk (org.spongepowered.common.interfaces.IMixinChunk)4 List (java.util.List)3 Nullable (javax.annotation.Nullable)3 EntityItem (net.minecraft.entity.item.EntityItem)3 EnumFacing (net.minecraft.util.EnumFacing)3 BlockPos (net.minecraft.util.math.BlockPos)3