make it compile
This commit is contained in:
@@ -2,11 +2,8 @@ package net.gensokyoreimagined.nitori.common.world;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.entity.EntityClassGroup;
|
||||
import net.gensokyoreimagined.nitori.common.entity.pushable.EntityPushablePredicate;
|
||||
import net.gensokyoreimagined.nitori.mixin.util.accessors.ClientEntityManagerAccessor;
|
||||
import net.gensokyoreimagined.nitori.mixin.util.accessors.EntityTrackingSectionAccessor;
|
||||
import net.gensokyoreimagined.nitori.mixin.util.accessors.ServerEntityManagerAccessor;
|
||||
import net.gensokyoreimagined.nitori.common.world.chunk.ClassGroupFilterableList;
|
||||
import net.gensokyoreimagined.nitori.mixin.util.accessors.ServerWorldAccessor;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.ClassInstanceMultiMap;
|
||||
import net.minecraft.util.AbortableIterationConsumer;
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.alloc.chunk_random;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.world.ChunkRandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(ServerLevel.class)
|
||||
public abstract class ServerWorldMixin {
|
||||
private final BlockPos.MutableBlockPos nitori$randomPosInChunkCachedPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
/**
|
||||
* @reason Avoid allocating BlockPos every invocation through using our allocation-free variant
|
||||
*/
|
||||
@Redirect(
|
||||
method = "tickChunk",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;getBlockRandomPos(IIII)Lnet/minecraft/core/BlockPos;"
|
||||
)
|
||||
)
|
||||
private BlockPos redirectTickGetRandomPosInChunk(ServerLevel serverWorld, int x, int y, int z, int mask) {
|
||||
((ChunkRandomSource) serverWorld).nitori$getRandomPosInChunk(x, y, z, mask, this.nitori$randomPosInChunkCachedPos);
|
||||
|
||||
return this.nitori$randomPosInChunkCachedPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Ensure an immutable block position is passed on block tick
|
||||
*/
|
||||
@Redirect(
|
||||
method = "tickChunk",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;randomTick(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/util/RandomSource;)V"
|
||||
)
|
||||
)
|
||||
private void redirectBlockStateTick(BlockState blockState, ServerLevel world, BlockPos pos, net.minecraft.util.RandomSource rand) {
|
||||
blockState.randomTick(world, pos.immutable(), rand);
|
||||
}
|
||||
//import net.gensokyoreimagined.nitori.common.world.ChunkRandomSource;
|
||||
//import net.minecraft.world.level.block.state.BlockState;
|
||||
//import net.minecraft.server.level.ServerLevel;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
//
|
||||
//@Mixin(ServerLevel.class)
|
||||
//public abstract class ServerWorldMixin {
|
||||
// private final BlockPos.MutableBlockPos nitori$randomPosInChunkCachedPos = new BlockPos.MutableBlockPos();
|
||||
//
|
||||
// /**
|
||||
// * @reason Avoid allocating BlockPos every invocation through using our allocation-free variant
|
||||
// */
|
||||
// @Redirect(
|
||||
// method = "tickChunk",
|
||||
// at = @At(
|
||||
// value = "INVOKE",
|
||||
// target = "Lnet/minecraft/server/level/ServerLevel;getBlockRandomPos(IIII)Lnet/minecraft/core/BlockPos;"
|
||||
// )
|
||||
// )
|
||||
// private BlockPos redirectTickGetRandomPosInChunk(ServerLevel serverWorld, int x, int y, int z, int mask) {
|
||||
// ((ChunkRandomSource) serverWorld).nitori$getRandomPosInChunk(x, y, z, mask, this.nitori$randomPosInChunkCachedPos);
|
||||
//
|
||||
// return this.nitori$randomPosInChunkCachedPos;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @reason Ensure an immutable block position is passed on block tick
|
||||
// */
|
||||
// @Redirect(
|
||||
// method = "tickChunk",
|
||||
// at = @At(
|
||||
// value = "INVOKE",
|
||||
// target = "Lnet/minecraft/world/level/block/state/BlockState;randomTick(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/util/RandomSource;)V"
|
||||
// )
|
||||
// )
|
||||
// private void redirectBlockStateTick(BlockState blockState, ServerLevel world, BlockPos pos, net.minecraft.util.RandomSource rand) {
|
||||
// blockState.randomTick(world, pos.immutable(), rand);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @reason Ensure an immutable block position is passed on fluid tick
|
||||
@@ -55,6 +55,6 @@ public abstract class ServerWorldMixin {
|
||||
// private void redirectFluidStateTick(FluidState fluidState, ServerLevel world, BlockPos pos, net.minecraft.util.RandomSource rand) {
|
||||
// fluidState.randomTick(world, pos.immutable(), rand);
|
||||
// }
|
||||
}
|
||||
//}
|
||||
|
||||
// couldn't figure it out....
|
||||
@@ -1,29 +1,29 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.logic.recipe_manager;
|
||||
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@Mixin(RecipeManager.class)
|
||||
public abstract class RecipeManagerMixin {
|
||||
|
||||
@Shadow protected abstract <C extends Container, T extends Recipe<C>> Collection<RecipeHolder<T>> byType(RecipeType<T> type);
|
||||
|
||||
/**
|
||||
* @author QPCrummer & Leaf Patch #0023
|
||||
* @reason Optimize RecipeManager List Creation
|
||||
*/
|
||||
@Overwrite
|
||||
public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getAllRecipesFor(RecipeType<T> type) {
|
||||
return new ArrayList<>(this.byType(type));
|
||||
}
|
||||
}
|
||||
//import net.minecraft.world.Container;
|
||||
//import net.minecraft.world.item.crafting.Recipe;
|
||||
//import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
//import net.minecraft.world.item.crafting.RecipeManager;
|
||||
//import net.minecraft.world.item.crafting.RecipeType;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Overwrite;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.Collection;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//@Mixin(RecipeManager.class)
|
||||
//public abstract class RecipeManagerMixin {
|
||||
//
|
||||
// @Shadow protected abstract <C extends Container, T extends Recipe<C>> Collection<RecipeHolder<T>> byType(RecipeType<T> type);
|
||||
//
|
||||
// /**
|
||||
// * @author QPCrummer & Leaf Patch #0023
|
||||
// * @reason Optimize RecipeManager List Creation
|
||||
// */
|
||||
// @Overwrite
|
||||
// public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getAllRecipesFor(RecipeType<T> type) {
|
||||
// return new ArrayList<>(this.byType(type));
|
||||
// }
|
||||
//}
|
||||
@@ -1,20 +1,20 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.math.random.creation;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(ServerPlayer.class)
|
||||
public abstract class ServerPlayerEntityRandomMixin {
|
||||
|
||||
@Shadow public abstract ServerLevel serverLevel();
|
||||
|
||||
@Redirect(method = "fudgeSpawnLocation", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/RandomSource;create()Lnet/minecraft/util/RandomSource;"))
|
||||
private RandomSource redirectCreatedRandom() {
|
||||
return serverLevel().random;
|
||||
}
|
||||
}
|
||||
//import net.minecraft.server.level.ServerPlayer;
|
||||
//import net.minecraft.server.level.ServerLevel;
|
||||
//import net.minecraft.util.RandomSource;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
//
|
||||
//@Mixin(ServerPlayer.class)
|
||||
//public abstract class ServerPlayerEntityRandomMixin {
|
||||
//
|
||||
// @Shadow public abstract ServerLevel serverLevel();
|
||||
//
|
||||
// @Redirect(method = "fudgeSpawnLocation", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/RandomSource;create()Lnet/minecraft/util/RandomSource;"))
|
||||
// private RandomSource redirectCreatedRandom() {
|
||||
// return serverLevel().random;
|
||||
// }
|
||||
//}
|
||||
@@ -1,13 +1,13 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.util.accessors;
|
||||
|
||||
import net.minecraft.world.level.entity.EntityAccess;
|
||||
import net.minecraft.world.level.entity.EntitySectionStorage;
|
||||
import net.minecraft.world.level.entity.TransientEntitySectionManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(TransientEntitySectionManager.class)
|
||||
public interface ClientEntityManagerAccessor<T extends EntityAccess> {
|
||||
@Accessor
|
||||
EntitySectionStorage<T> getSectionStorage();
|
||||
}
|
||||
//import net.minecraft.world.level.entity.EntityAccess;
|
||||
//import net.minecraft.world.level.entity.EntitySectionStorage;
|
||||
//import net.minecraft.world.level.entity.TransientEntitySectionManager;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
//
|
||||
//@Mixin(TransientEntitySectionManager.class)
|
||||
//public interface ClientEntityManagerAccessor<T extends EntityAccess> {
|
||||
// @Accessor
|
||||
// EntitySectionStorage<T> getSectionStorage();
|
||||
//}
|
||||
@@ -1,13 +1,13 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.util.accessors;
|
||||
|
||||
import net.minecraft.world.level.entity.EntityAccess;
|
||||
import net.minecraft.world.level.entity.EntitySectionStorage;
|
||||
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(PersistentEntitySectionManager.class)
|
||||
public interface ServerEntityManagerAccessor<T extends EntityAccess> {
|
||||
@Accessor
|
||||
EntitySectionStorage<T> getSectionStorage();
|
||||
}
|
||||
//import net.minecraft.world.level.entity.EntityAccess;
|
||||
//import net.minecraft.world.level.entity.EntitySectionStorage;
|
||||
//import net.minecraft.world.level.entity.PersistentEntitySectionManager;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
//
|
||||
//@Mixin(PersistentEntitySectionManager.class)
|
||||
//public interface ServerEntityManagerAccessor<T extends EntityAccess> {
|
||||
// @Accessor
|
||||
// EntitySectionStorage<T> getSectionStorage();
|
||||
//}
|
||||
@@ -1,158 +1,158 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.util.block_tracking;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.block.*;
|
||||
import net.gensokyoreimagined.nitori.common.entity.block_tracking.ChunkSectionChangeCallback;
|
||||
import net.gensokyoreimagined.nitori.common.entity.block_tracking.SectionedBlockChangeTracker;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
/**
|
||||
* Keep track of how many blocks that meet certain criteria are in this chunk section.
|
||||
* E.g. if no over-sized blocks are there, collision code can skip a few blocks.
|
||||
*
|
||||
* @author 2No2Name
|
||||
*/
|
||||
@Mixin(LevelChunkSection.class)
|
||||
public abstract class ChunkSectionMixin implements BlockCountingSection, BlockListeningSection {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
public PalettedContainer<BlockState> states;
|
||||
|
||||
@Unique
|
||||
private short[] nitori$countsByFlag = null;
|
||||
@Unique
|
||||
private ChunkSectionChangeCallback nitori$changeListener;
|
||||
@Unique
|
||||
private short nitori$listeningMask;
|
||||
|
||||
@Unique
|
||||
private static void nitori$addToFlagCount(short[] countsByFlag, BlockState state, short change) {
|
||||
int flags = ((BlockStateFlagHolder) state).lithium$getAllFlags();
|
||||
int i;
|
||||
while ((i = Integer.numberOfTrailingZeros(flags)) < 32 && i < countsByFlag.length) {
|
||||
//either count up by one (prevFlag not set) or down by one (prevFlag set)
|
||||
countsByFlag[i] += change;
|
||||
flags &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lithium$mayContainAny(TrackedBlockStatePredicate trackedBlockStatePredicate) {
|
||||
if (this.nitori$countsByFlag == null) {
|
||||
nitori$fastInitClientCounts();
|
||||
}
|
||||
return this.nitori$countsByFlag[trackedBlockStatePredicate.getIndex()] != (short) 0;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void nitori$fastInitClientCounts() {
|
||||
this.nitori$countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
||||
for (TrackedBlockStatePredicate trackedBlockStatePredicate : BlockStateFlags.TRACKED_FLAGS) {
|
||||
if (this.states.maybeHas(trackedBlockStatePredicate)) {
|
||||
//We haven't counted, so we just set the count so high that it never incorrectly reaches 0.
|
||||
//For most situations, this overestimation does not hurt client performance compared to correct counting,
|
||||
this.nitori$countsByFlag[trackedBlockStatePredicate.getIndex()] = 16 * 16 * 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "recalcBlockCounts()V", at = @At("HEAD"))
|
||||
private void createFlagCounters(CallbackInfo ci) {
|
||||
this.nitori$countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "read",
|
||||
at = @At(value = "HEAD")
|
||||
)
|
||||
private void resetData(FriendlyByteBuf buf, CallbackInfo ci) {
|
||||
this.nitori$countsByFlag = null;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "setBlockState(IIILnet/minecraft/world/level/block/state/BlockState;Z)Lnet/minecraft/world/level/block/state/BlockState;",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;getFluidState()Lnet/minecraft/world/level/material/FluidState;",
|
||||
ordinal = 0,
|
||||
shift = At.Shift.BEFORE
|
||||
),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void updateFlagCounters(int x, int y, int z, BlockState newState, boolean lock, CallbackInfoReturnable<BlockState> cir, BlockState oldState) {
|
||||
this.lithium$trackBlockStateChange(newState, oldState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$trackBlockStateChange(BlockState newState, BlockState oldState) {
|
||||
short[] countsByFlag = this.nitori$countsByFlag;
|
||||
if (countsByFlag == null) {
|
||||
return;
|
||||
}
|
||||
int prevFlags = ((BlockStateFlagHolder) oldState).lithium$getAllFlags();
|
||||
int flags = ((BlockStateFlagHolder) newState).lithium$getAllFlags();
|
||||
|
||||
int flagsXOR = prevFlags ^ flags;
|
||||
//we need to iterate over indices that changed or are in the listeningMask
|
||||
//Some Listening Flags are sensitive to both the previous and the new block. Others are only sensitive to
|
||||
//blocks that are different according to the predicate (XOR). For XOR, the block counting needs to be updated
|
||||
//as well.
|
||||
int iterateFlags = (~BlockStateFlags.LISTENING_MASK_OR & flagsXOR) |
|
||||
(BlockStateFlags.LISTENING_MASK_OR & this.nitori$listeningMask & (prevFlags | flags));
|
||||
int flagIndex;
|
||||
|
||||
while ((flagIndex = Integer.numberOfTrailingZeros(iterateFlags)) < 32 && flagIndex < countsByFlag.length) {
|
||||
int flagBit = 1 << flagIndex;
|
||||
//either count up by one (prevFlag not set) or down by one (prevFlag set)
|
||||
if ((flagsXOR & flagBit) != 0) {
|
||||
countsByFlag[flagIndex] += (short) (1 - (((prevFlags >>> flagIndex) & 1) << 1));
|
||||
}
|
||||
if ((this.nitori$listeningMask & flagBit) != 0) {
|
||||
this.nitori$listeningMask = this.nitori$changeListener.onBlockChange(flagIndex, this);
|
||||
}
|
||||
iterateFlags &= ~flagBit;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$addToCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker, long sectionPos, Level world) {
|
||||
if (this.nitori$changeListener == null) {
|
||||
if (sectionPos == Long.MIN_VALUE || world == null) {
|
||||
throw new IllegalArgumentException("Expected world and section pos during intialization!");
|
||||
}
|
||||
this.nitori$changeListener = ChunkSectionChangeCallback.create(sectionPos, world);
|
||||
}
|
||||
|
||||
this.nitori$listeningMask = this.nitori$changeListener.addTracker(tracker, blockGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$removeFromCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker) {
|
||||
if (this.nitori$changeListener != null) {
|
||||
this.nitori$listeningMask = this.nitori$changeListener.removeTracker(tracker, blockGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public void lithium$invalidateListeningSection(SectionPos sectionPos) {
|
||||
if (this.nitori$listeningMask != 0) {
|
||||
this.nitori$changeListener.onChunkSectionInvalidated(sectionPos);
|
||||
this.nitori$listeningMask = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//import net.gensokyoreimagined.nitori.common.block.*;
|
||||
//import net.gensokyoreimagined.nitori.common.entity.block_tracking.ChunkSectionChangeCallback;
|
||||
//import net.gensokyoreimagined.nitori.common.entity.block_tracking.SectionedBlockChangeTracker;
|
||||
//import net.minecraft.core.SectionPos;
|
||||
//import net.minecraft.network.FriendlyByteBuf;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import net.minecraft.world.level.block.state.BlockState;
|
||||
//import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
//import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
//import org.spongepowered.asm.mixin.Final;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//import org.spongepowered.asm.mixin.Shadow;
|
||||
//import org.spongepowered.asm.mixin.Unique;
|
||||
//import org.spongepowered.asm.mixin.injection.At;
|
||||
//import org.spongepowered.asm.mixin.injection.Inject;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
//import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
//
|
||||
///**
|
||||
// * Keep track of how many blocks that meet certain criteria are in this chunk section.
|
||||
// * E.g. if no over-sized blocks are there, collision code can skip a few blocks.
|
||||
// *
|
||||
// * @author 2No2Name
|
||||
// */
|
||||
//@Mixin(LevelChunkSection.class)
|
||||
//public abstract class ChunkSectionMixin implements BlockCountingSection, BlockListeningSection {
|
||||
//
|
||||
// @Shadow
|
||||
// @Final
|
||||
// public PalettedContainer<BlockState> states;
|
||||
//
|
||||
// @Unique
|
||||
// private short[] nitori$countsByFlag = null;
|
||||
// @Unique
|
||||
// private ChunkSectionChangeCallback nitori$changeListener;
|
||||
// @Unique
|
||||
// private short nitori$listeningMask;
|
||||
//
|
||||
// @Unique
|
||||
// private static void nitori$addToFlagCount(short[] countsByFlag, BlockState state, short change) {
|
||||
// int flags = ((BlockStateFlagHolder) state).lithium$getAllFlags();
|
||||
// int i;
|
||||
// while ((i = Integer.numberOfTrailingZeros(flags)) < 32 && i < countsByFlag.length) {
|
||||
// //either count up by one (prevFlag not set) or down by one (prevFlag set)
|
||||
// countsByFlag[i] += change;
|
||||
// flags &= ~(1 << i);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean lithium$mayContainAny(TrackedBlockStatePredicate trackedBlockStatePredicate) {
|
||||
// if (this.nitori$countsByFlag == null) {
|
||||
// nitori$fastInitClientCounts();
|
||||
// }
|
||||
// return this.nitori$countsByFlag[trackedBlockStatePredicate.getIndex()] != (short) 0;
|
||||
// }
|
||||
//
|
||||
// @Unique
|
||||
// private void nitori$fastInitClientCounts() {
|
||||
// this.nitori$countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
||||
// for (TrackedBlockStatePredicate trackedBlockStatePredicate : BlockStateFlags.TRACKED_FLAGS) {
|
||||
// if (this.states.maybeHas(trackedBlockStatePredicate)) {
|
||||
// //We haven't counted, so we just set the count so high that it never incorrectly reaches 0.
|
||||
// //For most situations, this overestimation does not hurt client performance compared to correct counting,
|
||||
// this.nitori$countsByFlag[trackedBlockStatePredicate.getIndex()] = 16 * 16 * 16;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Inject(method = "recalcBlockCounts()V", at = @At("HEAD"))
|
||||
// private void createFlagCounters(CallbackInfo ci) {
|
||||
// this.nitori$countsByFlag = new short[BlockStateFlags.NUM_TRACKED_FLAGS];
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "read",
|
||||
// at = @At(value = "HEAD")
|
||||
// )
|
||||
// private void resetData(FriendlyByteBuf buf, CallbackInfo ci) {
|
||||
// this.nitori$countsByFlag = null;
|
||||
// }
|
||||
//
|
||||
// @Inject(
|
||||
// method = "setBlockState(IIILnet/minecraft/world/level/block/state/BlockState;Z)Lnet/minecraft/world/level/block/state/BlockState;",
|
||||
// at = @At(
|
||||
// value = "INVOKE",
|
||||
// target = "Lnet/minecraft/world/level/block/state/BlockState;getFluidState()Lnet/minecraft/world/level/material/FluidState;",
|
||||
// ordinal = 0,
|
||||
// shift = At.Shift.BEFORE
|
||||
// ),
|
||||
// locals = LocalCapture.CAPTURE_FAILHARD
|
||||
// )
|
||||
// private void updateFlagCounters(int x, int y, int z, BlockState newState, boolean lock, CallbackInfoReturnable<BlockState> cir, BlockState oldState) {
|
||||
// this.lithium$trackBlockStateChange(newState, oldState);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$trackBlockStateChange(BlockState newState, BlockState oldState) {
|
||||
// short[] countsByFlag = this.nitori$countsByFlag;
|
||||
// if (countsByFlag == null) {
|
||||
// return;
|
||||
// }
|
||||
// int prevFlags = ((BlockStateFlagHolder) oldState).lithium$getAllFlags();
|
||||
// int flags = ((BlockStateFlagHolder) newState).lithium$getAllFlags();
|
||||
//
|
||||
// int flagsXOR = prevFlags ^ flags;
|
||||
// //we need to iterate over indices that changed or are in the listeningMask
|
||||
// //Some Listening Flags are sensitive to both the previous and the new block. Others are only sensitive to
|
||||
// //blocks that are different according to the predicate (XOR). For XOR, the block counting needs to be updated
|
||||
// //as well.
|
||||
// int iterateFlags = (~BlockStateFlags.LISTENING_MASK_OR & flagsXOR) |
|
||||
// (BlockStateFlags.LISTENING_MASK_OR & this.nitori$listeningMask & (prevFlags | flags));
|
||||
// int flagIndex;
|
||||
//
|
||||
// while ((flagIndex = Integer.numberOfTrailingZeros(iterateFlags)) < 32 && flagIndex < countsByFlag.length) {
|
||||
// int flagBit = 1 << flagIndex;
|
||||
// //either count up by one (prevFlag not set) or down by one (prevFlag set)
|
||||
// if ((flagsXOR & flagBit) != 0) {
|
||||
// countsByFlag[flagIndex] += (short) (1 - (((prevFlags >>> flagIndex) & 1) << 1));
|
||||
// }
|
||||
// if ((this.nitori$listeningMask & flagBit) != 0) {
|
||||
// this.nitori$listeningMask = this.nitori$changeListener.onBlockChange(flagIndex, this);
|
||||
// }
|
||||
// iterateFlags &= ~flagBit;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$addToCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker, long sectionPos, Level world) {
|
||||
// if (this.nitori$changeListener == null) {
|
||||
// if (sectionPos == Long.MIN_VALUE || world == null) {
|
||||
// throw new IllegalArgumentException("Expected world and section pos during intialization!");
|
||||
// }
|
||||
// this.nitori$changeListener = ChunkSectionChangeCallback.create(sectionPos, world);
|
||||
// }
|
||||
//
|
||||
// this.nitori$listeningMask = this.nitori$changeListener.addTracker(tracker, blockGroup);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$removeFromCallback(ListeningBlockStatePredicate blockGroup, SectionedBlockChangeTracker tracker) {
|
||||
// if (this.nitori$changeListener != null) {
|
||||
// this.nitori$listeningMask = this.nitori$changeListener.removeTracker(tracker, blockGroup);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// @Unique
|
||||
// public void lithium$invalidateListeningSection(SectionPos sectionPos) {
|
||||
// if (this.nitori$listeningMask != 0) {
|
||||
// this.nitori$changeListener.onChunkSectionInvalidated(sectionPos);
|
||||
// this.nitori$listeningMask = 0;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package net.gensokyoreimagined.nitori.mixin.util.block_tracking.block_listening;
|
||||
|
||||
import net.gensokyoreimagined.nitori.common.entity.block_tracking.SectionedBlockChangeTracker;
|
||||
import net.gensokyoreimagined.nitori.common.util.deduplication.LithiumInterner;
|
||||
import net.gensokyoreimagined.nitori.common.util.deduplication.LithiumInternerWrapper;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(Level.class)
|
||||
public class WorldMixin implements LithiumInternerWrapper<SectionedBlockChangeTracker> {
|
||||
private final LithiumInterner<SectionedBlockChangeTracker> blockChangeTrackers = new LithiumInterner<>();
|
||||
|
||||
@Override
|
||||
public SectionedBlockChangeTracker lithium$getCanonical(SectionedBlockChangeTracker value) {
|
||||
return this.blockChangeTrackers.getCanonical(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lithium$deleteCanonical(SectionedBlockChangeTracker value) {
|
||||
this.blockChangeTrackers.deleteCanonical(value);
|
||||
}
|
||||
}
|
||||
//import net.gensokyoreimagined.nitori.common.entity.block_tracking.SectionedBlockChangeTracker;
|
||||
//import net.gensokyoreimagined.nitori.common.util.deduplication.LithiumInterner;
|
||||
//import net.gensokyoreimagined.nitori.common.util.deduplication.LithiumInternerWrapper;
|
||||
//import net.minecraft.world.level.Level;
|
||||
//import org.spongepowered.asm.mixin.Mixin;
|
||||
//
|
||||
//@Mixin(Level.class)
|
||||
//public class WorldMixin implements LithiumInternerWrapper<SectionedBlockChangeTracker> {
|
||||
// private final LithiumInterner<SectionedBlockChangeTracker> blockChangeTrackers = new LithiumInterner<>();
|
||||
//
|
||||
// @Override
|
||||
// public SectionedBlockChangeTracker lithium$getCanonical(SectionedBlockChangeTracker value) {
|
||||
// return this.blockChangeTrackers.getCanonical(value);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void lithium$deleteCanonical(SectionedBlockChangeTracker value) {
|
||||
// this.blockChangeTrackers.deleteCanonical(value);
|
||||
// }
|
||||
//}
|
||||
@@ -61,7 +61,6 @@
|
||||
"logic.fast_bits_blockpos.OptimizedBlockPosBitsMixin",
|
||||
"logic.fast_rotations.EulerAngleMixin",
|
||||
"logic.reduce_ray_casting.BlockViewCastingMixin",
|
||||
"logic.recipe_manager.RecipeManagerMixin",
|
||||
"math.fast_blockops.BlockPosMixin",
|
||||
"math.fast_blockops.DirectionMixin",
|
||||
"math.fast_util.AxisCycleDirectionMixin$BackwardMixin",
|
||||
@@ -78,7 +77,6 @@
|
||||
"math.sine_lut.MixinMth",
|
||||
"math.vec.FastMathVec3DMixin",
|
||||
"math.random.RandomMixin",
|
||||
"math.random.creation.ServerPlayerEntityRandomMixin",
|
||||
"network.microopt.VarIntsMixin",
|
||||
"network.microopt.StringEncodingMixin",
|
||||
"network.block_breaking.CacheBlockBreakPacketMixin",
|
||||
@@ -93,11 +91,8 @@
|
||||
"shapes.precompute_shape_arrays.SimpleVoxelShapeMixin",
|
||||
"shapes.specialized_shapes.VoxelShapeMixin",
|
||||
"util.MixinLevelBlockEntityRetrieval",
|
||||
"util.accessors.ClientEntityManagerAccessor",
|
||||
"util.accessors.EntityTrackingSectionAccessor",
|
||||
"util.accessors.ServerEntityManagerAccessor",
|
||||
"util.block_tracking.AbstractBlockStateMixin",
|
||||
"util.block_tracking.block_listening.WorldMixin",
|
||||
"util.block_entity_retrieval.WorldMixin",
|
||||
"world.block_entity_ticking.sleeping.WrappedBlockEntityTickInvokerAccessor",
|
||||
"world.block_entity_ticking.sleeping.furnace.AbstractFurnaceBlockEntityMixin",
|
||||
|
||||
Reference in New Issue
Block a user