use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.
the class IPhaseState method appendNotifierPreBlockTick.
default void appendNotifierPreBlockTick(IMixinWorldServer mixinWorld, BlockPos pos, C context, BlockTickContext phaseContext) {
final Chunk chunk = mixinWorld.asMinecraftWorld().getChunkFromBlockCoords(pos);
final IMixinChunk mixinChunk = (IMixinChunk) chunk;
if (chunk != null && !chunk.isEmpty()) {
mixinChunk.getBlockOwner(pos).ifPresent(phaseContext::owner);
mixinChunk.getBlockNotifier(pos).ifPresent(phaseContext::notifier);
}
}
use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.
the class TrackingUtil method getNotifierOrOwnerFromBlock.
public static User getNotifierOrOwnerFromBlock(WorldServer world, BlockPos blockPos) {
final IMixinChunk mixinChunk = (IMixinChunk) world.getChunkFromBlockCoords(blockPos);
User notifier = mixinChunk.getBlockNotifier(blockPos).orElse(null);
if (notifier != null) {
return notifier;
}
User owner = mixinChunk.getBlockOwner(blockPos).orElse(null);
return owner;
}
use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.
the class TrackingUtil method tickTileEntity.
@SuppressWarnings({ "unused", "try" })
public static void tickTileEntity(IMixinWorldServer mixinWorldServer, ITickable tile) {
checkArgument(tile instanceof TileEntity, "ITickable %s is not a TileEntity!", tile);
checkNotNull(tile, "Cannot capture on a null ticking tile entity!");
final net.minecraft.tileentity.TileEntity tileEntity = (net.minecraft.tileentity.TileEntity) tile;
final IMixinTileEntity mixinTileEntity = (IMixinTileEntity) tile;
final BlockPos pos = tileEntity.getPos();
final IMixinChunk chunk = ((IMixinTileEntity) tile).getActiveChunk();
if (!mixinTileEntity.shouldTick()) {
return;
}
final TileEntityTickContext context = TickPhase.Tick.TILE_ENTITY.createPhaseContext().source(tile);
try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
final PhaseContext<?> phaseContext = context) {
Sponge.getCauseStackManager().pushCause(tile);
// Add notifier and owner so we don't have to perform lookups during the phases and other processing
chunk.getBlockNotifier(pos).ifPresent(notifier -> {
Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier);
phaseContext.notifier(notifier);
});
User blockOwner = mixinTileEntity.getSpongeOwner();
if (!mixinTileEntity.hasSetOwner()) {
blockOwner = chunk.getBlockOwner(pos).orElse(null);
mixinTileEntity.setSpongeOwner(blockOwner);
}
if (blockOwner != null) {
Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, blockOwner);
phaseContext.owner(blockOwner);
}
phaseContext.owner = blockOwner;
// Add the block snapshot of the tile entity for caches to avoid creating multiple snapshots during processing
// This is a lazy evaluating snapshot to avoid the overhead of snapshot creation
// Finally, switch the context now that we have the owner and notifier
phaseContext.buildAndSwitch();
try (Timing timing = mixinTileEntity.getTimingsHandler().startTiming()) {
tile.update();
}
} catch (Exception e) {
PhaseTracker.getInstance().printExceptionFromPhase(e, context);
}
}
use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.
the class MixinAnvilChunkLoader method onReadChunkFromNBT.
@Inject(method = "readChunkFromNBT", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/NBTTagCompound;getIntArray(Ljava/lang/String;)[I", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD)
public void onReadChunkFromNBT(World worldIn, NBTTagCompound compound, CallbackInfoReturnable<net.minecraft.world.chunk.Chunk> ci, int chunkX, int chunkZ, net.minecraft.world.chunk.Chunk chunkIn) {
if (compound.hasKey(NbtDataUtil.SPONGE_DATA)) {
Map<Integer, PlayerTracker> trackedIntPlayerPositions = Maps.newHashMap();
Map<Short, PlayerTracker> trackedShortPlayerPositions = Maps.newHashMap();
NBTTagList positions = compound.getCompoundTag(NbtDataUtil.SPONGE_DATA).getTagList(NbtDataUtil.SPONGE_BLOCK_POS_TABLE, 10);
IMixinChunk chunk = (IMixinChunk) chunkIn;
for (int i = 0; i < positions.tagCount(); i++) {
NBTTagCompound valueNbt = positions.getCompoundTagAt(i);
boolean isShortPos = valueNbt.hasKey("pos");
PlayerTracker tracker = new PlayerTracker();
if (valueNbt.hasKey("owner")) {
tracker.ownerIndex = valueNbt.getInteger("owner");
} else if (valueNbt.hasKey("uuid")) {
// Migrate old data, remove in future
tracker.ownerIndex = valueNbt.getInteger("uuid");
}
if (valueNbt.hasKey("notifier")) {
tracker.notifierIndex = valueNbt.getInteger("notifier");
}
if (tracker.notifierIndex != -1 || tracker.ownerIndex != -1) {
if (isShortPos) {
trackedShortPlayerPositions.put(valueNbt.getShort("pos"), tracker);
} else {
trackedIntPlayerPositions.put(valueNbt.getInteger("ipos"), tracker);
}
}
}
chunk.setTrackedIntPlayerPositions(trackedIntPlayerPositions);
chunk.setTrackedShortPlayerPositions(trackedShortPlayerPositions);
}
}
use of org.spongepowered.common.interfaces.IMixinChunk in project SpongeCommon by SpongePowered.
the class MixinAnvilChunkLoader method onWriteChunkToNBT.
@Inject(method = "writeChunkToNBT", at = @At(value = "RETURN"))
public void onWriteChunkToNBT(net.minecraft.world.chunk.Chunk chunkIn, World worldIn, NBTTagCompound compound, CallbackInfo ci) {
IMixinChunk chunk = (IMixinChunk) chunkIn;
// Add tracked block positions
if (chunk.getTrackedShortPlayerPositions().size() > 0 || chunk.getTrackedIntPlayerPositions().size() > 0) {
NBTTagCompound trackedNbt = new NBTTagCompound();
NBTTagList positions = new NBTTagList();
trackedNbt.setTag(NbtDataUtil.SPONGE_BLOCK_POS_TABLE, positions);
compound.setTag(NbtDataUtil.SPONGE_DATA, trackedNbt);
for (Map.Entry<Short, PlayerTracker> mapEntry : chunk.getTrackedShortPlayerPositions().entrySet()) {
Short pos = mapEntry.getKey();
Integer ownerUniqueIdIndex = mapEntry.getValue().ownerIndex;
Integer notifierUniqueIdIndex = mapEntry.getValue().notifierIndex;
NBTTagCompound valueNbt = new NBTTagCompound();
valueNbt.setInteger("owner", ownerUniqueIdIndex);
valueNbt.setInteger("notifier", notifierUniqueIdIndex);
valueNbt.setShort("pos", pos);
positions.appendTag(valueNbt);
}
for (Map.Entry<Integer, PlayerTracker> mapEntry : chunk.getTrackedIntPlayerPositions().entrySet()) {
Integer pos = mapEntry.getKey();
Integer ownerUniqueIdIndex = mapEntry.getValue().ownerIndex;
Integer notifierUniqueIdIndex = mapEntry.getValue().notifierIndex;
NBTTagCompound valueNbt = new NBTTagCompound();
valueNbt.setInteger("owner", ownerUniqueIdIndex);
valueNbt.setInteger("notifier", notifierUniqueIdIndex);
valueNbt.setInteger("ipos", pos);
positions.appendTag(valueNbt);
}
}
}
Aggregations