Search in sources :

Example 21 with IMixinChunk

use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.

the class TrackingUtil method trackBlockChange.

@SuppressWarnings("rawtypes")
static boolean trackBlockChange(PhaseTracker phaseTracker, IMixinWorldServer mixinWorld, Chunk chunk, IBlockState currentState, IBlockState newState, BlockPos pos, BlockChangeFlag flags, PhaseContext<?> phaseContext, IPhaseState<?> phaseState) {
    final SpongeBlockSnapshot originalBlockSnapshot;
    final WorldServer minecraftWorld = mixinWorld.asMinecraftWorld();
    if (((IPhaseState) phaseState).shouldCaptureBlockChangeOrSkip(phaseContext, pos)) {
        // final IBlockState actualState = currentState.getActualState(minecraftWorld, pos);
        originalBlockSnapshot = mixinWorld.createSpongeBlockSnapshot(currentState, currentState, pos, flags);
        final List<BlockSnapshot> capturedSnapshots = phaseContext.getCapturedBlocks();
        final Block newBlock = newState.getBlock();
        associateBlockChangeWithSnapshot(phaseState, newBlock, currentState, originalBlockSnapshot, capturedSnapshots);
        final IMixinChunk mixinChunk = (IMixinChunk) chunk;
        final IBlockState originalBlockState = mixinChunk.setBlockState(pos, newState, currentState, originalBlockSnapshot);
        if (originalBlockState == null) {
            capturedSnapshots.remove(originalBlockSnapshot);
            return false;
        }
        ((IPhaseState) phaseState).postTrackBlock(originalBlockSnapshot, phaseTracker, phaseContext);
    } else {
        originalBlockSnapshot = (SpongeBlockSnapshot) BlockSnapshot.NONE;
        final IMixinChunk mixinChunk = (IMixinChunk) chunk;
        final IBlockState originalBlockState = mixinChunk.setBlockState(pos, newState, currentState, originalBlockSnapshot);
        if (originalBlockState == null) {
            return false;
        }
    }
    if (newState.getLightOpacity() != currentState.getLightOpacity() || newState.getLightValue() != currentState.getLightValue()) {
        minecraftWorld.profiler.startSection("checkLight");
        minecraftWorld.checkLight(pos);
        minecraftWorld.profiler.endSection();
    }
    return true;
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) IBlockState(net.minecraft.block.state.IBlockState) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) EntityFallingBlock(net.minecraft.entity.item.EntityFallingBlock) Block(net.minecraft.block.Block) LocatableBlock(org.spongepowered.api.world.LocatableBlock) IMixinBlock(org.spongepowered.common.interfaces.block.IMixinBlock) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) WorldServer(net.minecraft.world.WorldServer)

Example 22 with IMixinChunk

use of org.spongepowered.common.interfaces.IMixinChunk 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)

Example 23 with IMixinChunk

use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.

the class SpongeCommonEventFactory method handleCollideImpactEvent.

public static boolean handleCollideImpactEvent(net.minecraft.entity.Entity projectile, @Nullable ProjectileSource projectileSource, RayTraceResult movingObjectPosition) {
    final PhaseTracker phaseTracker = PhaseTracker.getInstance();
    RayTraceResult.Type movingObjectType = movingObjectPosition.typeOfHit;
    try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(projectile);
        Sponge.getCauseStackManager().addContext(EventContextKeys.PROJECTILE_SOURCE, projectileSource == null ? ProjectileSource.UNKNOWN : projectileSource);
        final Optional<User> owner = phaseTracker.getCurrentPhaseData().context.getOwner();
        owner.ifPresent(user -> Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, user));
        Location<World> impactPoint = new Location<>((World) projectile.world, VecHelper.toVector3d(movingObjectPosition.hitVec));
        boolean cancelled = false;
        if (movingObjectType == RayTraceResult.Type.BLOCK) {
            final BlockPos blockPos = movingObjectPosition.getBlockPos();
            if (blockPos.getY() <= 0) {
                return false;
            }
            BlockSnapshot targetBlock = ((World) projectile.world).createSnapshot(VecHelper.toVector3i(movingObjectPosition.getBlockPos()));
            Direction side = Direction.NONE;
            if (movingObjectPosition.sideHit != null) {
                side = DirectionFacingProvider.getInstance().getKey(movingObjectPosition.sideHit).get();
            }
            CollideBlockEvent.Impact event = SpongeEventFactory.createCollideBlockEventImpact(Sponge.getCauseStackManager().getCurrentCause(), impactPoint, targetBlock.getState(), targetBlock.getLocation().get(), side);
            cancelled = SpongeImpl.postEvent(event);
            // Track impact block if event is not cancelled
            if (!cancelled && owner.isPresent()) {
                BlockPos targetPos = VecHelper.toBlockPos(impactPoint.getBlockPosition());
                IMixinChunk spongeChunk = (IMixinChunk) projectile.world.getChunkFromBlockCoords(targetPos);
                spongeChunk.addTrackedBlockPosition((Block) targetBlock.getState().getType(), targetPos, owner.get(), PlayerTracker.Type.NOTIFIER);
            }
        } else if (movingObjectPosition.entityHit != null) {
            // entity
            ArrayList<Entity> entityList = new ArrayList<>();
            entityList.add((Entity) movingObjectPosition.entityHit);
            CollideEntityEvent.Impact event = SpongeEventFactory.createCollideEntityEventImpact(Sponge.getCauseStackManager().getCurrentCause(), entityList, impactPoint);
            cancelled = SpongeImpl.postEvent(event);
        }
        if (cancelled) {
            // Entities such as EnderPearls call setDead during onImpact. However, if the event is cancelled
            // setDead will never be called resulting in a bad state such as falling through world.
            projectile.setDead();
        }
        return cancelled;
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) RayTraceResult(net.minecraft.util.math.RayTraceResult) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) ArrayList(java.util.ArrayList) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction) CollideBlockEvent(org.spongepowered.api.event.block.CollideBlockEvent) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.util.math.BlockPos) Location(org.spongepowered.api.world.Location)

Example 24 with IMixinChunk

use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.

the class MixinBlockDispenser method onDispenseHead.

@Inject(method = "dispense", at = @At(value = "HEAD"))
public void onDispenseHead(World worldIn, BlockPos pos, CallbackInfo ci) {
    final IBlockState state = worldIn.getBlockState(pos);
    final SpongeBlockSnapshot spongeBlockSnapshot = ((IMixinWorldServer) worldIn).createSpongeBlockSnapshot(state, state, pos, BlockChangeFlags.ALL);
    final IMixinChunk mixinChunk = (IMixinChunk) worldIn.getChunkFromBlockCoords(pos);
    this.context = BlockPhase.State.DISPENSE.createPhaseContext().source(spongeBlockSnapshot).owner(() -> mixinChunk.getBlockOwner(pos)).notifier(() -> mixinChunk.getBlockNotifier(pos)).buildAndSwitch();
}
Also used : SpongeBlockSnapshot(org.spongepowered.common.block.SpongeBlockSnapshot) IBlockState(net.minecraft.block.state.IBlockState) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) IMixinWorldServer(org.spongepowered.common.interfaces.world.IMixinWorldServer) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 25 with IMixinChunk

use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.

the class PlaceBlockPacketState method handleBlockChangeWithUser.

@Override
public void handleBlockChangeWithUser(@Nullable BlockChange blockChange, Transaction<BlockSnapshot> transaction, BasicPacketContext context) {
    Player player = Sponge.getCauseStackManager().getCurrentCause().first(Player.class).get();
    final Location<World> location = transaction.getFinal().getLocation().get();
    BlockPos pos = ((IMixinLocation) (Object) location).getBlockPos();
    IMixinChunk spongeChunk = (IMixinChunk) ((WorldServer) location.getExtent()).getChunkFromBlockCoords(pos);
    if (blockChange == BlockChange.PLACE) {
        spongeChunk.addTrackedBlockPosition((Block) transaction.getFinal().getState().getType(), pos, player, PlayerTracker.Type.OWNER);
    }
    spongeChunk.addTrackedBlockPosition((Block) transaction.getFinal().getState().getType(), pos, player, PlayerTracker.Type.NOTIFIER);
}
Also used : Player(org.spongepowered.api.entity.living.player.Player) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) BlockPos(net.minecraft.util.math.BlockPos) World(org.spongepowered.api.world.World)

Aggregations

IMixinChunk (org.spongepowered.common.interfaces.IMixinChunk)49 Chunk (net.minecraft.world.chunk.Chunk)21 BlockPos (net.minecraft.util.math.BlockPos)18 IMixinChunkProviderServer (org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer)12 User (org.spongepowered.api.entity.living.player.User)11 Inject (org.spongepowered.asm.mixin.injection.Inject)8 IBlockState (net.minecraft.block.state.IBlockState)7 World (org.spongepowered.api.world.World)7 IMixinEntity (org.spongepowered.common.interfaces.entity.IMixinEntity)7 LocatableBlock (org.spongepowered.api.world.LocatableBlock)6 Vector3i (com.flowpowered.math.vector.Vector3i)5 Block (net.minecraft.block.Block)5 StackFrame (org.spongepowered.api.event.CauseStackManager.StackFrame)5 Direction (org.spongepowered.api.util.Direction)5 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)5 Overwrite (org.spongepowered.asm.mixin.Overwrite)4 PhaseData (org.spongepowered.common.event.tracking.PhaseData)4 IMixinTileEntity (org.spongepowered.common.interfaces.block.tile.IMixinTileEntity)4 IMixinWorldServer (org.spongepowered.common.interfaces.world.IMixinWorldServer)4 Vector3d (com.flowpowered.math.vector.Vector3d)3