Search in sources :

Example 6 with IMixinChunk

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

the class SpongeCommonEventFactory method handleCollideBlockEvent.

public static boolean handleCollideBlockEvent(Block block, net.minecraft.world.World world, BlockPos pos, IBlockState state, net.minecraft.entity.Entity entity, Direction direction) {
    if (pos.getY() <= 0) {
        return false;
    }
    final PhaseTracker phaseTracker = PhaseTracker.getInstance();
    try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
        Sponge.getCauseStackManager().pushCause(entity);
        if (!(entity instanceof EntityPlayer)) {
            IMixinEntity spongeEntity = (IMixinEntity) entity;
            Optional<User> user = spongeEntity.getCreatorUser();
            if (user.isPresent()) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, user.get());
            }
        }
        // TODO: Add target side support
        CollideBlockEvent event = SpongeEventFactory.createCollideBlockEvent(Sponge.getCauseStackManager().getCurrentCause(), (BlockState) state, new Location<>((World) world, VecHelper.toVector3d(pos)), direction);
        boolean cancelled = SpongeImpl.postEvent(event);
        if (!cancelled) {
            IMixinEntity spongeEntity = (IMixinEntity) entity;
            if (!pos.equals(spongeEntity.getLastCollidedBlockPos())) {
                final PhaseData peek = phaseTracker.getCurrentPhaseData();
                final Optional<User> notifier = peek.context.getNotifier();
                if (notifier.isPresent()) {
                    IMixinChunk spongeChunk = (IMixinChunk) world.getChunkFromBlockCoords(pos);
                    spongeChunk.addTrackedBlockPosition(block, pos, notifier.get(), PlayerTracker.Type.NOTIFIER);
                }
            }
        }
        return cancelled;
    }
}
Also used : PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) User(org.spongepowered.api.entity.living.player.User) PhaseData(org.spongepowered.common.event.tracking.PhaseData) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) EntityPlayer(net.minecraft.entity.player.EntityPlayer) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) World(org.spongepowered.api.world.World) CollideBlockEvent(org.spongepowered.api.event.block.CollideBlockEvent)

Example 7 with IMixinChunk

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

the class DamageEventHandler method generateCauseFor.

public static void generateCauseFor(DamageSource damageSource) {
    if (damageSource instanceof EntityDamageSourceIndirect) {
        net.minecraft.entity.Entity source = damageSource.getTrueSource();
        if (!(source instanceof EntityPlayer) && source != null) {
            final IMixinEntity mixinEntity = EntityUtil.toMixin(source);
            mixinEntity.getNotifierUser().ifPresent(notifier -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier));
            mixinEntity.getCreatorUser().ifPresent(owner -> Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner));
        }
    } else if (damageSource instanceof EntityDamageSource) {
        net.minecraft.entity.Entity source = damageSource.getTrueSource();
        if (!(source instanceof EntityPlayer) && source != null) {
            final IMixinEntity mixinEntity = EntityUtil.toMixin(source);
            // TODO only have a UUID, want a user
            mixinEntity.getNotifierUser().ifPresent(notifier -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier));
            mixinEntity.getCreatorUser().ifPresent(creator -> Sponge.getCauseStackManager().addContext(EventContextKeys.CREATOR, creator));
        }
    } else if (damageSource instanceof BlockDamageSource) {
        Location<org.spongepowered.api.world.World> location = ((BlockDamageSource) damageSource).getLocation();
        BlockPos blockPos = ((IMixinLocation) (Object) location).getBlockPos();
        final IMixinChunk mixinChunk = (IMixinChunk) ((net.minecraft.world.World) location.getExtent()).getChunkFromBlockCoords(blockPos);
        mixinChunk.getBlockNotifier(blockPos).ifPresent(notifier -> Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier));
        mixinChunk.getBlockOwner(blockPos).ifPresent(owner -> Sponge.getCauseStackManager().addContext(EventContextKeys.CREATOR, owner));
    }
    Sponge.getCauseStackManager().pushCause(damageSource);
}
Also used : EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) Item(net.minecraft.item.Item) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) ItemStackUtil(org.spongepowered.common.item.inventory.util.ItemStackUtil) NBTTagList(net.minecraft.nbt.NBTTagList) ItemStack(org.spongepowered.api.item.inventory.ItemStack) Map(java.util.Map) EntityDamageSourceIndirect(net.minecraft.util.EntityDamageSourceIndirect) PotionEffect(org.spongepowered.api.effect.potion.PotionEffect) ItemArmor(net.minecraft.item.ItemArmor) LinkedHashMultimap(com.google.common.collect.LinkedHashMultimap) NbtDataUtil(org.spongepowered.common.data.util.NbtDataUtil) Location(org.spongepowered.api.world.Location) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) Predicate(java.util.function.Predicate) EquipmentType(org.spongepowered.api.item.inventory.equipment.EquipmentType) Collection(java.util.Collection) Sponge(org.spongepowered.api.Sponge) EnchantmentHelper(net.minecraft.enchantment.EnchantmentHelper) EntityUtil(org.spongepowered.common.entity.EntityUtil) Cause(org.spongepowered.api.event.cause.Cause) List(java.util.List) BlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.BlockDamageSource) EntityPlayer(net.minecraft.entity.player.EntityPlayer) World(org.spongepowered.api.world.World) Optional(java.util.Optional) MobEffects(net.minecraft.init.MobEffects) EventContext(org.spongepowered.api.event.cause.EventContext) IMixinChunkProviderServer(org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer) Iterables(com.google.common.collect.Iterables) Enchantment(net.minecraft.enchantment.Enchantment) AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) EntityEquipmentSlot(net.minecraft.inventory.EntityEquipmentSlot) DamageModifierTypes(org.spongepowered.api.event.cause.entity.damage.DamageModifierTypes) Multimap(com.google.common.collect.Multimap) DoubleUnaryOperator(java.util.function.DoubleUnaryOperator) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) Chunk(net.minecraft.world.chunk.Chunk) Entity(net.minecraft.entity.Entity) FallingBlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource) BlockPos(net.minecraft.util.math.BlockPos) DamageSource(net.minecraft.util.DamageSource) IBlockState(net.minecraft.block.state.IBlockState) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) EntityLivingBase(net.minecraft.entity.EntityLivingBase) MathHelper(net.minecraft.util.math.MathHelper) EntityDamageSource(net.minecraft.util.EntityDamageSource) EnumCreatureAttribute(net.minecraft.entity.EnumCreatureAttribute) EquipmentTypes(org.spongepowered.api.item.inventory.equipment.EquipmentTypes) Entity(net.minecraft.entity.Entity) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) Entity(net.minecraft.entity.Entity) EntityDamageSourceIndirect(net.minecraft.util.EntityDamageSourceIndirect) IMixinLocation(org.spongepowered.common.interfaces.world.IMixinLocation) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) World(org.spongepowered.api.world.World) EntityDamageSource(net.minecraft.util.EntityDamageSource) BlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.BlockDamageSource) FallingBlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource) EntityPlayer(net.minecraft.entity.player.EntityPlayer) BlockPos(net.minecraft.util.math.BlockPos)

Example 8 with IMixinChunk

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

the class MixinChunk_Async_Lighting method isAreaLoaded.

/**
 * Checks if surrounding chunks are loaded thread-safe.
 *
 * @return True if surrounded chunks are loaded, false if not
 */
private boolean isAreaLoaded() {
    if (!this.areNeighborsLoaded()) {
        return false;
    }
    // add diagonal chunks
    final Chunk southEastChunk = ((IMixinChunk) this.getNeighborChunk(0)).getNeighborChunk(2);
    if (southEastChunk == null) {
        return false;
    }
    final Chunk southWestChunk = ((IMixinChunk) this.getNeighborChunk(0)).getNeighborChunk(3);
    if (southWestChunk == null) {
        return false;
    }
    final Chunk northEastChunk = ((IMixinChunk) this.getNeighborChunk(1)).getNeighborChunk(2);
    if (northEastChunk == null) {
        return false;
    }
    final Chunk northWestChunk = ((IMixinChunk) this.getNeighborChunk(1)).getNeighborChunk(3);
    if (northWestChunk == null) {
        return false;
    }
    return true;
}
Also used : IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(net.minecraft.world.chunk.Chunk)

Example 9 with IMixinChunk

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

the class MixinWorldServer_Async_Lighting method checkLightAsync.

@Override
public boolean checkLightAsync(EnumSkyBlock lightType, BlockPos pos, net.minecraft.world.chunk.Chunk currentChunk, List<Chunk> neighbors) {
    // Sponge - This check is not needed as neighbors are checked in updateLightAsync
    if (false && !this.isAreaLoaded(pos, 17, false)) {
        return false;
    } else {
        final IMixinChunk spongeChunk = (IMixinChunk) currentChunk;
        int i = 0;
        int j = 0;
        // this.theProfiler.startSection("getBrightness"); // Sponge - don't use profiler off of main thread
        // Sponge - use thread safe method
        int k = this.getLightForAsync(lightType, pos, currentChunk, neighbors);
        // Sponge - use thread safe method
        int l = this.getRawBlockLightAsync(lightType, pos, currentChunk, neighbors);
        int i1 = pos.getX();
        int j1 = pos.getY();
        int k1 = pos.getZ();
        if (l > k) {
            this.lightUpdateBlockList[j++] = 133152;
        } else if (l < k) {
            this.lightUpdateBlockList[j++] = 133152 | k << 18;
            while (i < j) {
                int l1 = this.lightUpdateBlockList[i++];
                int i2 = (l1 & 63) - 32 + i1;
                int j2 = (l1 >> 6 & 63) - 32 + j1;
                int k2 = (l1 >> 12 & 63) - 32 + k1;
                int l2 = l1 >> 18 & 15;
                BlockPos blockpos = new BlockPos(i2, j2, k2);
                // Sponge - use thread safe method
                int i3 = this.getLightForAsync(lightType, blockpos, currentChunk, neighbors);
                if (i3 == l2) {
                    // Sponge - use thread safe method
                    this.setLightForAsync(lightType, blockpos, 0, currentChunk, neighbors);
                    if (l2 > 0) {
                        int j3 = MathHelper.abs(i2 - i1);
                        int k3 = MathHelper.abs(j2 - j1);
                        int l3 = MathHelper.abs(k2 - k1);
                        if (j3 + k3 + l3 < 17) {
                            BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain();
                            for (EnumFacing enumfacing : EnumFacing.values()) {
                                int i4 = i2 + enumfacing.getFrontOffsetX();
                                int j4 = j2 + enumfacing.getFrontOffsetY();
                                int k4 = k2 + enumfacing.getFrontOffsetZ();
                                blockpos$pooledmutableblockpos.setPos(i4, j4, k4);
                                // Sponge start - get chunk safely
                                final Chunk pooledChunk = this.getLightChunk(blockpos$pooledmutableblockpos, currentChunk, neighbors);
                                if (pooledChunk == null) {
                                    continue;
                                }
                                int l4 = Math.max(1, pooledChunk.getBlockState(blockpos$pooledmutableblockpos).getLightOpacity());
                                i3 = this.getLightForAsync(lightType, blockpos$pooledmutableblockpos, currentChunk, neighbors);
                                if (i3 == l2 - l4 && j < this.lightUpdateBlockList.length) {
                                    this.lightUpdateBlockList[j++] = i4 - i1 + 32 | j4 - j1 + 32 << 6 | k4 - k1 + 32 << 12 | l2 - l4 << 18;
                                }
                            }
                            blockpos$pooledmutableblockpos.release();
                        }
                    }
                }
            }
            i = 0;
        }
        while (i < j) {
            int i5 = this.lightUpdateBlockList[i++];
            int j5 = (i5 & 63) - 32 + i1;
            int k5 = (i5 >> 6 & 63) - 32 + j1;
            int l5 = (i5 >> 12 & 63) - 32 + k1;
            BlockPos blockpos1 = new BlockPos(j5, k5, l5);
            // Sponge - use thread safe method
            int i6 = this.getLightForAsync(lightType, blockpos1, currentChunk, neighbors);
            // Sponge - use thread safe method
            int j6 = this.getRawBlockLightAsync(lightType, blockpos1, currentChunk, neighbors);
            if (j6 != i6) {
                // Sponge - use thread safe method
                this.setLightForAsync(lightType, blockpos1, j6, currentChunk, neighbors);
                if (j6 > i6) {
                    int k6 = Math.abs(j5 - i1);
                    int l6 = Math.abs(k5 - j1);
                    int i7 = Math.abs(l5 - k1);
                    boolean flag = j < this.lightUpdateBlockList.length - 6;
                    if (k6 + l6 + i7 < 17 && flag) {
                        // Sponge start - use thread safe method getLightForAsync
                        if (this.getLightForAsync(lightType, blockpos1.west(), currentChunk, neighbors) < j6) {
                            this.lightUpdateBlockList[j++] = j5 - 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
                        }
                        if (this.getLightForAsync(lightType, blockpos1.east(), currentChunk, neighbors) < j6) {
                            this.lightUpdateBlockList[j++] = j5 + 1 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
                        }
                        if (this.getLightForAsync(lightType, blockpos1.down(), currentChunk, neighbors) < j6) {
                            this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
                        }
                        if (this.getLightForAsync(lightType, blockpos1.up(), currentChunk, neighbors) < j6) {
                            this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 + 1 - j1 + 32 << 6) + (l5 - k1 + 32 << 12);
                        }
                        if (this.getLightForAsync(lightType, blockpos1.north(), currentChunk, neighbors) < j6) {
                            this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 - 1 - k1 + 32 << 12);
                        }
                        if (this.getLightForAsync(lightType, blockpos1.south(), currentChunk, neighbors) < j6) {
                            this.lightUpdateBlockList[j++] = j5 - i1 + 32 + (k5 - j1 + 32 << 6) + (l5 + 1 - k1 + 32 << 12);
                        }
                    // Sponge end
                    }
                }
            }
        }
        // Sponge start - Asynchronous light updates
        spongeChunk.getQueuedLightingUpdates(lightType).remove((Short) this.blockPosToShort(pos));
        spongeChunk.getPendingLightUpdates().decrementAndGet();
        for (net.minecraft.world.chunk.Chunk neighborChunk : neighbors) {
            final IMixinChunk neighbor = (IMixinChunk) neighborChunk;
            neighbor.getPendingLightUpdates().decrementAndGet();
        }
        // this.theProfiler.endSection(); // Sponge - don't use profiler off of main thread
        return true;
    }
}
Also used : IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) EnumFacing(net.minecraft.util.EnumFacing) BlockPos(net.minecraft.util.math.BlockPos) IMixinBlockPos(org.spongepowered.common.interfaces.util.math.IMixinBlockPos) Chunk(net.minecraft.world.chunk.Chunk) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(net.minecraft.world.chunk.Chunk)

Example 10 with IMixinChunk

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

the class EntityActivationRange method checkIfActive.

/**
 * Checks if the entity is active for this tick.
 *
 * @param entity The entity to check for activity
 * @return Whether the given entity should be active
 */
public static boolean checkIfActive(Entity entity) {
    // Never safe to skip fireworks or entities not yet added to chunk
    if (entity.world.isRemote || !entity.addedToChunk || entity instanceof EntityFireworkRocket) {
        return true;
    }
    final IMixinChunk activeChunk = ((IMixinEntity) entity).getActiveChunk();
    if (activeChunk == null) {
        // Should never happen but just in case for mods, always tick
        return true;
    }
    // If in forced chunk or is player
    if (activeChunk.isPersistedChunk() || (!SpongeImplHooks.isFakePlayer(entity) && entity instanceof EntityPlayerMP)) {
        return true;
    }
    long currentTick = SpongeImpl.getServer().getTickCounter();
    IModData_Activation spongeEntity = (IModData_Activation) entity;
    boolean isActive = spongeEntity.getActivatedTick() >= currentTick || spongeEntity.getDefaultActivationState();
    // Should this entity tick?
    if (!isActive) {
        if ((currentTick - spongeEntity.getActivatedTick() - 1) % 20 == 0) {
            // Check immunities every 20 ticks.
            if (checkEntityImmunities(entity)) {
                // Triggered some sort of immunity, give 20 full ticks before we check again.
                spongeEntity.setActivatedTick(currentTick + 20);
            }
            isActive = true;
        }
    // Add a little performance juice to active entities. Skip 1/4 if not immune.
    } else if (!spongeEntity.getDefaultActivationState() && entity.ticksExisted % 4 == 0 && !checkEntityImmunities(entity)) {
        isActive = false;
    }
    if (isActive && !activeChunk.areNeighborsLoaded()) {
        isActive = false;
    }
    return isActive;
}
Also used : IModData_Activation(org.spongepowered.common.mixin.plugin.entityactivation.interfaces.IModData_Activation) EntityFireworkRocket(net.minecraft.entity.item.EntityFireworkRocket) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP)

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