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;
}
}
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);
}
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;
}
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;
}
}
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;
}
Aggregations