use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.
the class DamageEventUtil method generateCauseFor.
/**
* This applies various contexts based on the type of {@link DamageSource}, whether
* it's provided by sponge or vanilla. This is not stack neutral, which is why it requires
* a {@link CauseStackManager.StackFrame} reference to push onto the stack.
*/
public static void generateCauseFor(final DamageSource damageSource, final CauseStackManager.StackFrame frame) {
if (damageSource instanceof EntityDamageSource) {
final net.minecraft.world.entity.Entity source = damageSource.getEntity();
if (!(source instanceof Player) && source instanceof CreatorTrackedBridge) {
final CreatorTrackedBridge creatorBridge = (CreatorTrackedBridge) source;
creatorBridge.tracker$getCreatorUUID().ifPresent(creator -> frame.addContext(EventContextKeys.CREATOR, creator));
creatorBridge.tracker$getNotifierUUID().ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
}
} else if (damageSource instanceof BlockDamageSource) {
final ServerLocation location = ((BlockDamageSource) damageSource).location();
final BlockPos blockPos = VecHelper.toBlockPos(location);
final LevelChunkBridge chunkBridge = (LevelChunkBridge) ((net.minecraft.world.level.Level) location.world()).getChunkAt(blockPos);
chunkBridge.bridge$getBlockCreatorUUID(blockPos).ifPresent(creator -> frame.addContext(EventContextKeys.CREATOR, creator));
chunkBridge.bridge$getBlockNotifierUUID(blockPos).ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
}
frame.pushCause(damageSource);
}
use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.
the class ChunkMapMixin method impl$onLoad.
@Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/LevelChunk;setLoaded(Z)V"), slice = @Slice(from = @At(value = "INVOKE", remap = false, target = "Lit/unimi/dsi/fastutil/longs/LongSet;add(J)Z"), to = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addAllPendingBlockEntities(Ljava/util/Collection;)V")))
private void impl$onLoad(final LevelChunk levelChunk, final boolean loaded) {
levelChunk.setLoaded(true);
final Vector3i chunkPos = new Vector3i(levelChunk.getPos().x, 0, levelChunk.getPos().z);
if (ShouldFire.CHUNK_EVENT_LOAD) {
final ChunkEvent.Load loadEvent = SpongeEventFactory.createChunkEventLoad(PhaseTracker.getInstance().currentCause(), ((WorldChunk) levelChunk), chunkPos, (ResourceKey) (Object) this.level.dimension().location());
SpongeCommon.post(loadEvent);
}
for (final Direction dir : Constants.Chunk.CARDINAL_DIRECTIONS) {
final Vector3i neighborPos = chunkPos.add(dir.asBlockOffset());
ChunkAccess neighbor = this.level.getChunk(neighborPos.x(), neighborPos.z(), ChunkStatus.EMPTY, false);
if (neighbor instanceof ImposterProtoChunk) {
neighbor = ((ImposterProtoChunk) neighbor).getWrapped();
}
if (neighbor instanceof LevelChunk) {
final int index = DirectionUtil.directionToIndex(dir);
final int oppositeIndex = DirectionUtil.directionToIndex(dir.opposite());
((LevelChunkBridge) levelChunk).bridge$setNeighborChunk(index, (LevelChunk) neighbor);
((LevelChunkBridge) neighbor).bridge$setNeighborChunk(oppositeIndex, levelChunk);
}
}
}
use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.
the class ChunkSerializerMixin_Tracker method impl$writeSpongeLevelData.
@Inject(method = "write", at = @At(value = "RETURN"))
private static void impl$writeSpongeLevelData(final ServerLevel param0, final ChunkAccess param1, final CallbackInfoReturnable<CompoundTag> cir) {
if (!(param1 instanceof LevelChunk)) {
return;
}
final LevelChunkBridge chunk = (LevelChunkBridge) param1;
if (!chunk.bridge$getTrackedShortPlayerPositions().isEmpty() || !chunk.bridge$getTrackedIntPlayerPositions().isEmpty()) {
final CompoundTag level = (CompoundTag) cir.getReturnValue().get("Level");
final CompoundTag trackedNbt = new CompoundTag();
final ListTag positions = new ListTag();
trackedNbt.put(Constants.Sponge.SPONGE_BLOCK_POS_TABLE, positions);
level.put(Constants.Sponge.Data.V2.SPONGE_DATA, trackedNbt);
ChunkSerializerMixin_Tracker.impl$writeMap(positions, chunk.bridge$getTrackedShortPlayerPositions(), (nbt, pos) -> nbt.putShort("pos", pos));
ChunkSerializerMixin_Tracker.impl$writeMap(positions, chunk.bridge$getTrackedIntPlayerPositions(), (nbt, pos) -> nbt.putInt("ipos", pos));
}
}
use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.
the class ChunkSerializerMixin_Tracker method impl$readSpongeLevelData.
@Redirect(method = "read", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/ChunkAccess;setLightCorrect(Z)V"))
private static void impl$readSpongeLevelData(final ChunkAccess chunkAccess, final boolean var1, final ServerLevel param0, final StructureManager param1, final PoiManager param2, final ChunkPos param3, final CompoundTag param4) {
if (!(chunkAccess instanceof LevelChunk)) {
return;
}
final CompoundTag level = (CompoundTag) param4.get("Level");
final CompoundTag spongeData = level.getCompound(Constants.Sponge.Data.V2.SPONGE_DATA);
if (spongeData.isEmpty()) {
return;
}
final Map<Integer, PlayerTracker> trackedIntPlayerPositions = new HashMap<>();
final Map<Short, PlayerTracker> trackedShortPlayerPositions = new HashMap<>();
final ListTag list = spongeData.getList(Constants.Sponge.SPONGE_BLOCK_POS_TABLE, 10);
final LevelChunkBridge chunk = (LevelChunkBridge) chunkAccess;
for (Tag tag : list) {
final PlayerTracker tracker = new PlayerTracker();
final CompoundTag data = (CompoundTag) tag;
final boolean isShortPos = data.contains("pos");
if (data.contains("owner")) {
tracker.creatorindex = data.getInt("owner");
}
if (data.contains("notifier")) {
tracker.notifierIndex = data.getInt("notifier");
}
if (tracker.notifierIndex != -1 || tracker.creatorindex != -1) {
if (isShortPos) {
trackedShortPlayerPositions.put(data.getShort("pos"), tracker);
} else {
trackedIntPlayerPositions.put(data.getInt("ipos"), tracker);
}
}
}
chunk.bridge$setTrackedIntPlayerPositions(trackedIntPlayerPositions);
chunk.bridge$setTrackedShortPlayerPositions(trackedShortPlayerPositions);
}
use of org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge in project SpongeCommon by SpongePowered.
the class TrackingUtil method associateTrackerToTarget.
public static void associateTrackerToTarget(final BlockChange blockChange, final BlockTransactionReceipt receipt, final UUID uuid) {
final BlockSnapshot finalSnapshot = receipt.finalBlock();
final SpongeBlockSnapshot spongeSnapshot = (SpongeBlockSnapshot) finalSnapshot;
final BlockPos pos = spongeSnapshot.getBlockPos();
final Block block = ((net.minecraft.world.level.block.state.BlockState) spongeSnapshot.state()).getBlock();
spongeSnapshot.getServerWorld().map(world -> world.getChunkAt(pos)).map(chunk -> (LevelChunkBridge) chunk).ifPresent(spongeChunk -> {
final PlayerTracker.Type trackerType = blockChange == BlockChange.PLACE ? PlayerTracker.Type.CREATOR : PlayerTracker.Type.NOTIFIER;
spongeChunk.bridge$addTrackedBlockPosition(block, pos, uuid, trackerType);
});
}
Aggregations