Update to 1.20.3
Change all interfaces used in mixins to have methods prefixed with "moonrise" or "starlight", to remove risk of conflicting with Vanilla or other mods methods Add new patch for optimising ticking block entity removal - Similar to Paper's patch for this but uses an in-place removal method Remove most of the fluid mixins: - May not be effective, but are a big maintenance problem
This commit is contained in:
@@ -38,7 +38,7 @@ processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version
|
||||
expand "version": project.version, "minecraft_version": minecraft_version, "loader_version": loader_version, "mod_version": mod_version
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ org.gradle.jvmargs=-Xmx2G
|
||||
org.gradle.daemon=false
|
||||
# Fabric Properties
|
||||
# check these on https://modmuss50.me/fabric.html
|
||||
minecraft_version=1.20.2
|
||||
yarn_mappings=1.20.2+build.4
|
||||
loader_version=0.14.23
|
||||
minecraft_version=1.20.3
|
||||
yarn_mappings=1.20.3+build.1
|
||||
loader_version=0.15.0
|
||||
# Mod Properties
|
||||
mod_version=1.0.0
|
||||
maven_group=ca.spottedleaf.moonrise
|
||||
|
||||
@@ -38,7 +38,7 @@ public abstract class SimpleBitStorageMixin implements BitStorage {
|
||||
final int dataIndex = index / this.valuesPerLong;
|
||||
final int localIndex = (index % this.valuesPerLong) * this.bitsPerValue;
|
||||
where valuesPerLong = 64 / this.bits
|
||||
The additional add that mojang uses is only for unsigned division, when in reality the above is signed division.
|
||||
The additional add that Mojang uses is only for unsigned division, when in reality the above is signed division.
|
||||
Thus, it is appropriate to use the signed division magic values which do not use an add.
|
||||
*/
|
||||
|
||||
@@ -70,7 +70,7 @@ public abstract class SimpleBitStorageMixin implements BitStorage {
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise method to use our magic value, which does not perform an add
|
||||
* @reason Do not validate input, and optimise method to use our magic value, which does not perform an add
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
@@ -100,7 +100,7 @@ public abstract class SimpleBitStorageMixin implements BitStorage {
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise method to use our magic value, which does not perform an add
|
||||
* @reason Do not validate input, and optimise method to use our magic value, which does not perform an add
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
@@ -127,7 +127,7 @@ public abstract class SimpleBitStorageMixin implements BitStorage {
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise method to use our magic value, which does not perform an add
|
||||
* @reason Do not validate input, and optimise method to use our magic value, which does not perform an add
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package ca.spottedleaf.moonrise.mixin.block_entity_remove;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.TickRateManager;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.entity.TickingBlockEntity;
|
||||
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.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Mixin(Level.class)
|
||||
public abstract class LevelMixin implements LevelAccessor, AutoCloseable {
|
||||
|
||||
@Shadow
|
||||
protected List<TickingBlockEntity> blockEntityTickers;
|
||||
|
||||
@Shadow
|
||||
private List<TickingBlockEntity> pendingBlockEntityTickers;
|
||||
|
||||
@Shadow
|
||||
public abstract TickRateManager tickRateManager();
|
||||
|
||||
@Shadow
|
||||
public abstract boolean shouldTickBlocksAt(BlockPos blockPos);
|
||||
|
||||
/**
|
||||
* @reason Make blockEntityTickers be of type {@link ObjectArrayList}, so that we can use {@link ObjectArrayList#elements()}
|
||||
* and {@link ObjectArrayList#size(int)} to manipulate the raw list for faster removals
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Inject(
|
||||
method = "<init>",
|
||||
at = @At(
|
||||
value = "RETURN"
|
||||
)
|
||||
)
|
||||
private void newFieldType(final CallbackInfo ci) {
|
||||
// ObjectArrayList exposes raw elements + size
|
||||
this.blockEntityTickers = ObjectArrayList.wrap(new TickingBlockEntity[0]);
|
||||
this.pendingBlockEntityTickers = ObjectArrayList.wrap(new TickingBlockEntity[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Run an in-place remove while ticking block entities, instead of using the iterator remove (which is O(n) _per_ remove)
|
||||
* This brings the remove calls to O(1) time
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Redirect(
|
||||
method = "tickBlockEntities",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Ljava/util/Iterator;hasNext()Z",
|
||||
ordinal = 0
|
||||
)
|
||||
)
|
||||
private boolean newBlockEntityTick(final Iterator<TickingBlockEntity> ignored) {
|
||||
final boolean doTick = this.tickRateManager().runsNormally();
|
||||
final ObjectArrayList<TickingBlockEntity> tickList = (ObjectArrayList<TickingBlockEntity>)this.blockEntityTickers;
|
||||
// can cast the array, as we used wrap() with the array type
|
||||
final TickingBlockEntity[] elements = tickList.elements();
|
||||
|
||||
boolean writeToBase = false;
|
||||
|
||||
int base = 0;
|
||||
int i = 0; // current ticking entity (exclusive)
|
||||
int len = tickList.size();
|
||||
|
||||
Objects.checkFromToIndex(0, len, elements.length);
|
||||
try {
|
||||
for (; i < len; ++i) {
|
||||
final TickingBlockEntity tileEntity = elements[i];
|
||||
if (tileEntity.isRemoved()) {
|
||||
writeToBase = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (doTick && this.shouldTickBlocksAt(tileEntity.getPos())) {
|
||||
tileEntity.tick();
|
||||
}
|
||||
|
||||
if (writeToBase) {
|
||||
// avoid polluting cache if we are not removing
|
||||
elements[base] = tileEntity;
|
||||
++base;
|
||||
} else {
|
||||
++base;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// always keep the list in a non-broken state when handling (synchronous) exceptions
|
||||
if (i != base) {
|
||||
// writeToBase = true here
|
||||
// len - i != 0 only occurs when an exception is handled: remove elements between base and i
|
||||
System.arraycopy(elements, i, elements, base, len - i);
|
||||
|
||||
// adjust size by removed elements
|
||||
tickList.size(len - (i - base));
|
||||
}
|
||||
}
|
||||
|
||||
// force skip vanilla tick loop by always returning false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public abstract class BooleanPropertyMixin extends Property<Boolean> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getIdFor(final Boolean value) {
|
||||
public final int moonrise$getIdFor(final Boolean value) {
|
||||
return value.booleanValue() ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public abstract class EnumPropertyMixin<T extends Enum<T> & StringRepresentable>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getIdFor(final T value) {
|
||||
public final int moonrise$getIdFor(final T value) {
|
||||
return this.idLookupTable[value.ordinal()];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public abstract class IntegerPropertyMixin extends Property<Integer> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getIdFor(final Integer value) {
|
||||
public final int moonrise$getIdFor(final Integer value) {
|
||||
final int val = value.intValue();
|
||||
final int ret = val - this.min;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public abstract class PropertyMixin<T extends Comparable<T>> implements Property
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getId() {
|
||||
public final int moonrise$getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@@ -50,5 +50,5 @@ public abstract class PropertyMixin<T extends Comparable<T>> implements Property
|
||||
|
||||
// this is re-declared here so that calls to Property#getIdFor are a virtual method invoke, rather than an interface invoke
|
||||
@Override
|
||||
public abstract int getIdFor(final T value);
|
||||
public abstract int moonrise$getIdFor(final T value);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package ca.spottedleaf.moonrise.mixin.chunk_getblock;
|
||||
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
|
||||
@@ -83,7 +83,7 @@ public abstract class LevelChunkMixin extends ChunkAccess implements GetBlockChu
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockState getBlockState(final BlockPos pos) {
|
||||
return this.getBlock(pos.getX(), pos.getY(), pos.getZ());
|
||||
return this.moonrise$getBlock(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
@Unique
|
||||
@@ -101,7 +101,7 @@ public abstract class LevelChunkMixin extends ChunkAccess implements GetBlockChu
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(final int x, final int y, final int z) {
|
||||
public BlockState moonrise$getBlock(final int x, final int y, final int z) {
|
||||
if (this.debug) {
|
||||
return this.getBlockDebug(x, y, z);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ public abstract class ArrayVoxelShapeMixin {
|
||||
private void initState(final DiscreteVoxelShape discreteVoxelShape,
|
||||
final DoubleList xList, final DoubleList yList, final DoubleList zList,
|
||||
final CallbackInfo ci) {
|
||||
((CollisionVoxelShape)this).initCache();
|
||||
((CollisionVoxelShape)this).moonrise$initCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public abstract class BitSetDiscreteVoxelShapeMixin extends DiscreteVoxelShape {
|
||||
chkForAll(shape, mergeAdjacent);
|
||||
}
|
||||
// called with the shape of a VoxelShape, so we can expect the cache to exist
|
||||
final CachedShapeData cache = ((CollisionDiscreteVoxelShape)shape).getOrCreateCachedShapeData();
|
||||
final CachedShapeData cache = ((CollisionDiscreteVoxelShape)shape).moonrise$getOrCreateCachedShapeData();
|
||||
|
||||
final int sizeX = cache.sizeX();
|
||||
final int sizeY = cache.sizeY();
|
||||
|
||||
@@ -15,6 +15,6 @@ public abstract class BlockMixin {
|
||||
*/
|
||||
@Overwrite
|
||||
public static boolean isShapeFullBlock(final VoxelShape shape) {
|
||||
return ((CollisionVoxelShape)shape).isFullBlock();
|
||||
return ((CollisionVoxelShape)shape).moonrise$isFullBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ public abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState>
|
||||
|
||||
@Unique
|
||||
private static void initCaches(final VoxelShape shape) {
|
||||
((CollisionVoxelShape)shape).isFullBlock();
|
||||
((CollisionVoxelShape)shape).occludesFullBlock();
|
||||
((CollisionVoxelShape)shape).moonrise$isFullBlock();
|
||||
((CollisionVoxelShape)shape).moonrise$occludesFullBlock();
|
||||
shape.toAabbs();
|
||||
if (!shape.isEmpty()) {
|
||||
shape.bounds();
|
||||
@@ -100,12 +100,12 @@ public abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState>
|
||||
final VoxelShape collisionShape = this.cache.collisionShape;
|
||||
try {
|
||||
this.constantCollisionShape = this.getCollisionShape(null, null, null);
|
||||
this.constantAABBCollision = this.constantCollisionShape == null ? null : ((CollisionVoxelShape)this.constantCollisionShape).getSingleAABBRepresentation();
|
||||
this.constantAABBCollision = this.constantCollisionShape == null ? null : ((CollisionVoxelShape)this.constantCollisionShape).moonrise$getSingleAABBRepresentation();
|
||||
} catch (final Throwable throwable) {
|
||||
this.constantCollisionShape = null;
|
||||
this.constantAABBCollision = null;
|
||||
}
|
||||
this.occludesFullBlock = ((CollisionVoxelShape)collisionShape).occludesFullBlock();
|
||||
this.occludesFullBlock = ((CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock();
|
||||
this.emptyCollisionShape = collisionShape.isEmpty();
|
||||
// init caches
|
||||
initCaches(collisionShape);
|
||||
@@ -130,37 +130,37 @@ public abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasCache() {
|
||||
public final boolean moonrise$hasCache() {
|
||||
return this.cache != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean occludesFullBlock() {
|
||||
public final boolean moonrise$occludesFullBlock() {
|
||||
return this.occludesFullBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean emptyCollisionShape() {
|
||||
public final boolean moonrise$emptyCollisionShape() {
|
||||
return this.emptyCollisionShape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int uniqueId1() {
|
||||
public final int moonrise$uniqueId1() {
|
||||
return this.id1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int uniqueId2() {
|
||||
public final int moonrise$uniqueId2() {
|
||||
return this.id2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final VoxelShape getConstantCollisionShape() {
|
||||
public final VoxelShape moonrise$getConstantCollisionShape() {
|
||||
return this.constantCollisionShape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AABB getConstantCollisionAABB() {
|
||||
public final AABB moonrise$getConstantCollisionAABB() {
|
||||
return this.constantAABBCollision;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,6 @@ public abstract class CubeVoxelShapeMixin {
|
||||
)
|
||||
)
|
||||
private void initState(final DiscreteVoxelShape discreteVoxelShape, final CallbackInfo ci) {
|
||||
((CollisionVoxelShape)this).initCache();
|
||||
((CollisionVoxelShape)this).moonrise$initCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public abstract class DirectionMixin implements CollisionDirection {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int uniqueId() {
|
||||
public final int moonrise$uniqueId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public abstract class DiscreteVoxelShapeMixin implements CollisionDiscreteVoxelS
|
||||
private CachedShapeData cachedShapeData;
|
||||
|
||||
@Override
|
||||
public final CachedShapeData getOrCreateCachedShapeData() {
|
||||
public final CachedShapeData moonrise$getOrCreateCachedShapeData() {
|
||||
if (this.cachedShapeData != null) {
|
||||
return this.cachedShapeData;
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ public interface EntityGetterMixin extends CollisionEntityGetter {
|
||||
box = box.inflate(-CollisionUtil.COLLISION_EPSILON, -CollisionUtil.COLLISION_EPSILON, -CollisionUtil.COLLISION_EPSILON);
|
||||
|
||||
final List<Entity> entities;
|
||||
if (entity != null && ((CollisionEntity)entity).isHardColliding()) {
|
||||
if (entity != null && ((CollisionEntity)entity).moonrise$isHardColliding()) {
|
||||
entities = this.getEntities(entity, box, null);
|
||||
} else {
|
||||
entities = this.getHardCollidingEntities(entity, box, null);
|
||||
entities = this.moonrise$getHardCollidingEntities(entity, box, null);
|
||||
}
|
||||
|
||||
final List<VoxelShape> ret = new ArrayList<>(Math.min(25, entities.size()));
|
||||
@@ -68,7 +68,7 @@ public interface EntityGetterMixin extends CollisionEntityGetter {
|
||||
}
|
||||
|
||||
@Override
|
||||
default List<Entity> getHardCollidingEntities(final Entity entity, final AABB box, final Predicate<? super Entity> predicate) {
|
||||
default List<Entity> moonrise$getHardCollidingEntities(final Entity entity, final AABB box, final Predicate<? super Entity> predicate) {
|
||||
return this.getEntities(entity, box, predicate);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public interface EntityGetterMixin extends CollisionEntityGetter {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AABB singleAABB = ((CollisionVoxelShape)voxel).getSingleAABBRepresentation();
|
||||
final AABB singleAABB = ((CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation();
|
||||
final List<Entity> entities = this.getEntities(
|
||||
entity,
|
||||
singleAABB == null ? voxel.bounds() : singleAABB.inflate(-CollisionUtil.COLLISION_EPSILON, -CollisionUtil.COLLISION_EPSILON, -CollisionUtil.COLLISION_EPSILON)
|
||||
|
||||
@@ -92,10 +92,10 @@ public abstract class EntityMixin implements CollisionEntity {
|
||||
protected abstract void onInsideBlock(BlockState blockState);
|
||||
|
||||
@Unique
|
||||
private final boolean isHardColliding = this.isHardCollidingUncached();
|
||||
private final boolean isHardColliding = this.moonrise$isHardCollidingUncached();
|
||||
|
||||
@Override
|
||||
public final boolean isHardColliding() {
|
||||
public final boolean moonrise$isHardColliding() {
|
||||
return this.isHardColliding;
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ public abstract class EntityMixin implements CollisionEntity {
|
||||
|
||||
final BlockState state = chunk.getBlockState(tempPos);
|
||||
|
||||
if (((CollisionBlockState)state).emptyCollisionShape() || !state.isSuffocating(this.level, tempPos)) {
|
||||
if (((CollisionBlockState)state).moonrise$emptyCollisionShape() || !state.isSuffocating(this.level, tempPos)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ public abstract class EntityMixin implements CollisionEntity {
|
||||
|
||||
final AABB toCollide = box.move(-(double)fx, -(double)fy, -(double)fz);
|
||||
|
||||
final AABB singleAABB = ((CollisionVoxelShape)collisionShape).getSingleAABBRepresentation();
|
||||
final AABB singleAABB = ((CollisionVoxelShape)collisionShape).moonrise$getSingleAABBRepresentation();
|
||||
if (singleAABB != null) {
|
||||
if (CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) {
|
||||
return true;
|
||||
|
||||
@@ -118,7 +118,7 @@ public abstract class LevelChunkSectionMixin implements CollisionLevelChunkSecti
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getSpecialCollidingBlocks() {
|
||||
public final int moonrise$getSpecialCollidingBlocks() {
|
||||
return this.specialCollidingBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkSource;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
@@ -67,17 +66,17 @@ public abstract class LevelMixin implements CollisionLevel, CollisionEntityGette
|
||||
private int maxSection;
|
||||
|
||||
@Override
|
||||
public final EntityLookup getCollisionLookup() {
|
||||
public final EntityLookup moonrise$getCollisionLookup() {
|
||||
return this.collisionLookup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getMinSectionMoonrise() {
|
||||
public final int moonrise$getMinSection() {
|
||||
return this.minSection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getMaxSectionMoonrise() {
|
||||
public final int moonrise$getMaxSection() {
|
||||
return this.maxSection;
|
||||
}
|
||||
|
||||
@@ -196,7 +195,7 @@ public abstract class LevelMixin implements CollisionLevel, CollisionEntityGette
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Override
|
||||
public final List<Entity> getHardCollidingEntities(final Entity entity, final AABB box, final Predicate<? super Entity> predicate) {
|
||||
public final List<Entity> moonrise$getHardCollidingEntities(final Entity entity, final AABB box, final Predicate<? super Entity> predicate) {
|
||||
this.getProfiler().incrementCounter("getEntities");
|
||||
final List<Entity> ret = new ArrayList<>();
|
||||
|
||||
@@ -298,7 +297,7 @@ public abstract class LevelMixin implements CollisionLevel, CollisionEntityGette
|
||||
int lastChunkY = Integer.MIN_VALUE;
|
||||
int lastChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
final int minSection = ((CollisionLevel)level).getMinSectionMoonrise();
|
||||
final int minSection = ((CollisionLevel)level).moonrise$getMinSection();
|
||||
|
||||
for (;;) {
|
||||
currPos.set(currX, currY, currZ);
|
||||
@@ -514,9 +513,7 @@ public abstract class LevelMixin implements CollisionLevel, CollisionEntityGette
|
||||
final int newChunkX = currX >> 4;
|
||||
final int newChunkZ = currZ >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
if (((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ)) != 0) {
|
||||
lastChunk = (LevelChunk)chunkSource.getChunk(newChunkX, newChunkZ, ChunkStatus.FULL, false);
|
||||
}
|
||||
|
||||
@@ -538,16 +535,22 @@ public abstract class LevelMixin implements CollisionLevel, CollisionEntityGette
|
||||
continue;
|
||||
}
|
||||
|
||||
final BlockState state = ((GetBlockChunk)lastChunk).getBlock(currX, currY, currZ);
|
||||
if (((CollisionBlockState)state).emptyCollisionShape()) {
|
||||
final BlockState state = ((GetBlockChunk)lastChunk).moonrise$getBlock(currX, currY, currZ);
|
||||
if (((CollisionBlockState)state).moonrise$emptyCollisionShape()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VoxelShape blockCollision = ((CollisionBlockState)state).moonrise$getConstantCollisionShape();
|
||||
|
||||
if ((edgeCount != 1 || state.hasLargeCollisionShape()) && (edgeCount != 2 || state.getBlock() == Blocks.MOVING_PISTON)) {
|
||||
if (collisionContext == null) {
|
||||
collisionContext = new CollisionUtil.LazyEntityCollisionContext(entity);
|
||||
}
|
||||
final VoxelShape blockCollision = state.getCollisionShape(lastChunk, pos, collisionContext);
|
||||
|
||||
if (blockCollision == null) {
|
||||
blockCollision = state.getCollisionShape((Level)(Object)this, pos, collisionContext);
|
||||
}
|
||||
|
||||
if (blockCollision.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -555,7 +558,7 @@ public abstract class LevelMixin implements CollisionLevel, CollisionEntityGette
|
||||
// avoid VoxelShape#move by shifting the entity collision shape instead
|
||||
final AABB shiftedAABB = aabb.move(-(double)currX, -(double)currY, -(double)currZ);
|
||||
|
||||
final AABB singleAABB = ((CollisionVoxelShape)blockCollision).getSingleAABBRepresentation();
|
||||
final AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation();
|
||||
if (singleAABB != null) {
|
||||
if (!CollisionUtil.voxelShapeIntersect(singleAABB, shiftedAABB)) {
|
||||
continue;
|
||||
|
||||
@@ -57,7 +57,7 @@ public abstract class LiquidBlockRendererMixin {
|
||||
);
|
||||
}
|
||||
|
||||
final VoxelShape stateShape = ((CollisionVoxelShape)state.getOcclusionShape(world, pos)).getFaceShapeClamped(direction.getOpposite());
|
||||
final VoxelShape stateShape = ((CollisionVoxelShape)state.getOcclusionShape(world, pos)).moonrise$getFaceShapeClamped(direction.getOpposite());
|
||||
|
||||
if (stateShape.isEmpty()) {
|
||||
// cannot occlude
|
||||
|
||||
@@ -33,7 +33,7 @@ public abstract class LivingEntityMixin extends Entity implements Attackable {
|
||||
public void pushEntities() {
|
||||
if (this.level().isClientSide()) {
|
||||
final List<Player> players = new ArrayList<>();
|
||||
((CollisionLevel)this.level()).getCollisionLookup().getEntities(Player.class, this, this.getBoundingBox(), players, EntitySelector.pushableBy(this));
|
||||
((CollisionLevel)this.level()).moonrise$getCollisionLookup().getEntities(Player.class, this, this.getBoundingBox(), players, EntitySelector.pushableBy(this));
|
||||
for (int i = 0, len = players.size(); i < len; ++i) {
|
||||
this.doPush(players.get(i));
|
||||
}
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
package ca.spottedleaf.moonrise.mixin.collisions;
|
||||
|
||||
import ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.CollisionUtil;
|
||||
import ca.spottedleaf.moonrise.patches.starlight.light.StarLightInterface;
|
||||
import ca.spottedleaf.moonrise.patches.starlight.light.StarLightLightingProvider;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -99,33 +90,4 @@ public abstract class ParticleMixin {
|
||||
|
||||
return CollisionUtil.performCollisions(movement, entityBoundingBox, voxels, boxes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise impl
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
public int getLightColor(final float f) {
|
||||
final int blockX = Mth.floor(this.x);
|
||||
final int blockY = Mth.floor(this.y);
|
||||
final int blockZ = Mth.floor(this.z);
|
||||
|
||||
final BlockPos pos = new BlockPos(blockX, blockY, blockZ);
|
||||
|
||||
final LevelChunk chunk = this.level.getChunkSource().getChunk(blockX >> 4, blockZ >> 4, ChunkStatus.FULL, false);
|
||||
final BlockState blockState = chunk == null ? null : ((GetBlockChunk)chunk).getBlock(blockX, blockY, blockZ);
|
||||
|
||||
if (blockState != null && !blockState.isAir()) {
|
||||
if (blockState.emissiveRendering(this.level, pos)) {
|
||||
return 15728880;
|
||||
}
|
||||
}
|
||||
|
||||
final StarLightInterface lightEngine = ((StarLightLightingProvider)this.level.getLightEngine()).getLightEngine();
|
||||
|
||||
final int skyLight = chunk == null ? 0 : lightEngine.getSkyLightValue(pos, chunk);
|
||||
final int blockLight = Math.max(chunk == null ? 0 : lightEngine.getBlockLightValue(pos, chunk), blockState == null ? 0 : blockState.getLightEmission());
|
||||
|
||||
return skyLight << 20 | blockLight << 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public abstract class PersistentEntitySectionManagerCallbackMixin<T extends Enti
|
||||
|
||||
final long currentChunk = this.currentSectionKey;
|
||||
|
||||
((CollisionLevel)entity.level()).getCollisionLookup().moveEntity(entity, currentChunk);
|
||||
((CollisionLevel)entity.level()).moonrise$getCollisionLookup().moveEntity(entity, currentChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,6 +54,6 @@ public abstract class PersistentEntitySectionManagerCallbackMixin<T extends Enti
|
||||
private void onRemoved(final CallbackInfo ci) {
|
||||
final Entity entity = (Entity)this.entity;
|
||||
|
||||
((CollisionLevel)entity.level()).getCollisionLookup().removeEntity(entity);
|
||||
((CollisionLevel)entity.level()).moonrise$getCollisionLookup().removeEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,6 @@ public abstract class PersistentEntitySectionManagerMixin<T extends EntityAccess
|
||||
private void addEntity(final T entityAccess, final boolean onDisk, final CallbackInfoReturnable<Boolean> cir) {
|
||||
final Entity entity = (Entity)entityAccess;
|
||||
|
||||
((CollisionLevel)entity.level()).getCollisionLookup().addEntity(entity);
|
||||
((CollisionLevel)entity.level()).moonrise$getCollisionLookup().addEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class ServerEntityMixin {
|
||||
)
|
||||
)
|
||||
private void forceHardCollideTeleport(final CallbackInfo ci) {
|
||||
if (((CollisionEntity)this.entity).isHardColliding()) {
|
||||
if (((CollisionEntity)this.entity).moonrise$isHardColliding()) {
|
||||
this.teleportDelay = 9999;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ public abstract class ShapesMixin {
|
||||
*/
|
||||
@Overwrite
|
||||
public static VoxelShape getFaceShape(final VoxelShape shape, final Direction direction) {
|
||||
return ((CollisionVoxelShape)shape).getFaceShapeClamped(direction);
|
||||
return ((CollisionVoxelShape)shape).moonrise$getFaceShapeClamped(direction);
|
||||
}
|
||||
|
||||
@Unique
|
||||
@@ -288,7 +288,7 @@ public abstract class ShapesMixin {
|
||||
@Overwrite
|
||||
public static boolean mergedFaceOccludes(final VoxelShape first, final VoxelShape second, final Direction direction) {
|
||||
// see if any of the shapes on their own occludes, only if cached
|
||||
if (((CollisionVoxelShape)first).occludesFullBlockIfCached() || ((CollisionVoxelShape)second).occludesFullBlockIfCached()) {
|
||||
if (((CollisionVoxelShape)first).moonrise$occludesFullBlockIfCached() || ((CollisionVoxelShape)second).moonrise$occludesFullBlockIfCached()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -298,11 +298,11 @@ public abstract class ShapesMixin {
|
||||
|
||||
// we optimise getOpposite, so we can use it
|
||||
// secondly, use our cache to retrieve sliced shape
|
||||
final VoxelShape newFirst = ((CollisionVoxelShape)first).getFaceShapeClamped(direction);
|
||||
final VoxelShape newSecond = ((CollisionVoxelShape)second).getFaceShapeClamped(direction.getOpposite());
|
||||
final VoxelShape newFirst = ((CollisionVoxelShape)first).moonrise$getFaceShapeClamped(direction);
|
||||
final VoxelShape newSecond = ((CollisionVoxelShape)second).moonrise$getFaceShapeClamped(direction.getOpposite());
|
||||
|
||||
// see if any of the shapes on their own occludes, only if cached
|
||||
if (((CollisionVoxelShape)newFirst).occludesFullBlockIfCached() || ((CollisionVoxelShape)newSecond).occludesFullBlockIfCached()) {
|
||||
if (((CollisionVoxelShape)newFirst).moonrise$occludesFullBlockIfCached() || ((CollisionVoxelShape)newSecond).moonrise$occludesFullBlockIfCached()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -314,14 +314,14 @@ public abstract class ShapesMixin {
|
||||
}
|
||||
|
||||
if (firstEmpty | secondEmpty) {
|
||||
return secondEmpty ? ((CollisionVoxelShape)newFirst).occludesFullBlock() : ((CollisionVoxelShape)newSecond).occludesFullBlock();
|
||||
return secondEmpty ? ((CollisionVoxelShape)newFirst).moonrise$occludesFullBlock() : ((CollisionVoxelShape)newSecond).moonrise$occludesFullBlock();
|
||||
}
|
||||
|
||||
if (newFirst == newSecond) {
|
||||
return ((CollisionVoxelShape)newFirst).occludesFullBlock();
|
||||
return ((CollisionVoxelShape)newFirst).moonrise$occludesFullBlock();
|
||||
}
|
||||
|
||||
return mergedMayOccludeBlock(newFirst, newSecond) && ((CollisionVoxelShape)((CollisionVoxelShape)newFirst).orUnoptimized(newSecond)).occludesFullBlock();
|
||||
return mergedMayOccludeBlock(newFirst, newSecond) && ((CollisionVoxelShape)((CollisionVoxelShape)newFirst).moonrise$orUnoptimized(newSecond)).moonrise$occludesFullBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -343,11 +343,11 @@ public abstract class ShapesMixin {
|
||||
|
||||
// we optimise getOpposite, so we can use it
|
||||
// secondly, use our cache to retrieve sliced shape
|
||||
final VoxelShape newFirst = ((CollisionVoxelShape)first).getFaceShapeClamped(direction);
|
||||
final VoxelShape newFirst = ((CollisionVoxelShape)first).moonrise$getFaceShapeClamped(direction);
|
||||
if (newFirst.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
final VoxelShape newSecond = ((CollisionVoxelShape)second).getFaceShapeClamped(direction.getOpposite());
|
||||
final VoxelShape newSecond = ((CollisionVoxelShape)second).moonrise$getFaceShapeClamped(direction.getOpposite());
|
||||
if (newSecond.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -361,7 +361,7 @@ public abstract class ShapesMixin {
|
||||
*/
|
||||
@Overwrite
|
||||
public static boolean faceShapeOccludes(final VoxelShape shape1, final VoxelShape shape2) {
|
||||
if (((CollisionVoxelShape)shape1).occludesFullBlockIfCached() || ((CollisionVoxelShape)shape2).occludesFullBlockIfCached()) {
|
||||
if (((CollisionVoxelShape)shape1).moonrise$occludesFullBlockIfCached() || ((CollisionVoxelShape)shape2).moonrise$occludesFullBlockIfCached()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -372,13 +372,13 @@ public abstract class ShapesMixin {
|
||||
}
|
||||
|
||||
if (s1Empty | s2Empty) {
|
||||
return s2Empty ? ((CollisionVoxelShape)shape1).occludesFullBlock() : ((CollisionVoxelShape)shape2).occludesFullBlock();
|
||||
return s2Empty ? ((CollisionVoxelShape)shape1).moonrise$occludesFullBlock() : ((CollisionVoxelShape)shape2).moonrise$occludesFullBlock();
|
||||
}
|
||||
|
||||
if (shape1 == shape2) {
|
||||
return ((CollisionVoxelShape)shape1).occludesFullBlock();
|
||||
return ((CollisionVoxelShape)shape1).moonrise$occludesFullBlock();
|
||||
}
|
||||
|
||||
return mergedMayOccludeBlock(shape1, shape2) && ((CollisionVoxelShape)((CollisionVoxelShape)shape1).orUnoptimized(shape2)).occludesFullBlock();
|
||||
return mergedMayOccludeBlock(shape1, shape2) && ((CollisionVoxelShape)((CollisionVoxelShape)shape1).moonrise$orUnoptimized(shape2)).moonrise$occludesFullBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,6 @@ public abstract class SliceShapeMixin {
|
||||
)
|
||||
)
|
||||
private void initState(final VoxelShape parent, final Direction.Axis forAxis, final int forIndex, final CallbackInfo ci) {
|
||||
((CollisionVoxelShape)this).initCache();
|
||||
((CollisionVoxelShape)this).moonrise$initCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public abstract class TransientEntitySectionManagerCallbackMixin<T extends Entit
|
||||
|
||||
final long currentChunk = this.currentSectionKey;
|
||||
|
||||
((CollisionLevel)entity.level()).getCollisionLookup().moveEntity(entity, currentChunk);
|
||||
((CollisionLevel)entity.level()).moonrise$getCollisionLookup().moveEntity(entity, currentChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,6 +54,6 @@ public abstract class TransientEntitySectionManagerCallbackMixin<T extends Entit
|
||||
private void onRemoved(final CallbackInfo ci) {
|
||||
final Entity entity = (Entity)this.entity;
|
||||
|
||||
((CollisionLevel)entity.level()).getCollisionLookup().removeEntity(entity);
|
||||
((CollisionLevel)entity.level()).moonrise$getCollisionLookup().removeEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,6 @@ public abstract class TransientEntitySectionManagerMixin<T extends EntityAccess>
|
||||
private void addEntity(final T entityAccess, final CallbackInfo ci) {
|
||||
final Entity entity = (Entity)entityAccess;
|
||||
|
||||
((CollisionLevel)entity.level()).getCollisionLookup().addEntity(entity);
|
||||
((CollisionLevel)entity.level()).moonrise$getCollisionLookup().addEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,37 +87,37 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
private MergedORCache[] mergedORCache;
|
||||
|
||||
@Override
|
||||
public final double offsetX() {
|
||||
public final double moonrise$offsetX() {
|
||||
return this.offsetX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double offsetY() {
|
||||
public final double moonrise$offsetY() {
|
||||
return this.offsetY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double offsetZ() {
|
||||
public final double moonrise$offsetZ() {
|
||||
return this.offsetZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AABB getSingleAABBRepresentation() {
|
||||
public final AABB moonrise$getSingleAABBRepresentation() {
|
||||
return this.singleAABBRepresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double[] rootCoordinatesX() {
|
||||
public final double[] moonrise$rootCoordinatesX() {
|
||||
return this.rootCoordinatesX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double[] rootCoordinatesY() {
|
||||
public final double[] moonrise$rootCoordinatesY() {
|
||||
return this.rootCoordinatesY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double[] rootCoordinatesZ() {
|
||||
public final double[] moonrise$rootCoordinatesZ() {
|
||||
return this.rootCoordinatesZ;
|
||||
}
|
||||
|
||||
@@ -136,8 +136,8 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void initCache() {
|
||||
this.cachedShapeData = ((CollisionDiscreteVoxelShape)this.shape).getOrCreateCachedShapeData();
|
||||
public final void moonrise$initCache() {
|
||||
this.cachedShapeData = ((CollisionDiscreteVoxelShape)this.shape).moonrise$getOrCreateCachedShapeData();
|
||||
this.isEmpty = this.cachedShapeData.isEmpty();
|
||||
|
||||
final DoubleList xList = this.getCoords(Direction.Axis.X);
|
||||
@@ -175,7 +175,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CachedShapeData getCachedVoxelData() {
|
||||
public final CachedShapeData moonrise$getCachedVoxelData() {
|
||||
return this.cachedShapeData;
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
private VoxelShape[] faceShapeClampedCache;
|
||||
|
||||
@Override
|
||||
public final VoxelShape getFaceShapeClamped(final Direction direction) {
|
||||
public final VoxelShape moonrise$getFaceShapeClamped(final Direction direction) {
|
||||
if (this.isEmpty) {
|
||||
return (VoxelShape)(Object)this;
|
||||
}
|
||||
@@ -233,12 +233,12 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
return other;
|
||||
}
|
||||
|
||||
final AABB otherAABB = ((CollisionVoxelShape)other).getSingleAABBRepresentation();
|
||||
final AABB otherAABB = ((CollisionVoxelShape)other).moonrise$getSingleAABBRepresentation();
|
||||
if (otherAABB == null) {
|
||||
return other;
|
||||
}
|
||||
|
||||
if (((CollisionVoxelShape)Shapes.block()).getSingleAABBRepresentation().equals(otherAABB)) {
|
||||
if (((CollisionVoxelShape)Shapes.block()).moonrise$getSingleAABBRepresentation().equals(otherAABB)) {
|
||||
return Shapes.block();
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.isFullBlock()) {
|
||||
if (this.moonrise$isFullBlock()) {
|
||||
this.occludesFullBlock = Boolean.TRUE;
|
||||
return true;
|
||||
}
|
||||
@@ -274,7 +274,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean occludesFullBlock() {
|
||||
public final boolean moonrise$occludesFullBlock() {
|
||||
final Boolean ret = this.occludesFullBlock;
|
||||
if (ret != null) {
|
||||
return ret.booleanValue();
|
||||
@@ -284,7 +284,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean occludesFullBlockIfCached() {
|
||||
public final boolean moonrise$occludesFullBlockIfCached() {
|
||||
final Boolean ret = this.occludesFullBlock;
|
||||
return ret != null ? ret.booleanValue() : false;
|
||||
}
|
||||
@@ -295,7 +295,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final VoxelShape orUnoptimized(final VoxelShape other) {
|
||||
public final VoxelShape moonrise$orUnoptimized(final VoxelShape other) {
|
||||
// don't cache simple cases
|
||||
if (((VoxelShape)(Object)this) == other) {
|
||||
return other;
|
||||
@@ -525,7 +525,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullBlock() {
|
||||
public boolean moonrise$isFullBlock() {
|
||||
final Boolean ret = this.isFullBlock;
|
||||
|
||||
if (ret != null) {
|
||||
@@ -697,7 +697,7 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
|
||||
if (this.singleAABBRepresentation != null) {
|
||||
// note: the isFullBlock() is fuzzy, and Shapes.create() is also fuzzy which would return block()
|
||||
return this.isFullBlock() ? Shapes.block() : (VoxelShape)(Object)this;
|
||||
return this.moonrise$isFullBlock() ? Shapes.block() : (VoxelShape)(Object)this;
|
||||
}
|
||||
|
||||
final List<AABB> aabbs = this.toAabbs();
|
||||
|
||||
@@ -30,8 +30,6 @@ public abstract class SynchedEntityDataMixin {
|
||||
protected abstract <T> void assignValue(SynchedEntityData.DataItem<T> dataItem, SynchedEntityData.DataValue<?> dataValue);
|
||||
|
||||
|
||||
|
||||
|
||||
@Unique
|
||||
private static final SynchedEntityData.DataItem<?>[] EMPTY = new SynchedEntityData.DataItem<?>[0];
|
||||
|
||||
|
||||
@@ -72,9 +72,6 @@ public abstract class ExplosionMixin {
|
||||
@Final
|
||||
private ObjectArrayList<BlockPos> toBlow;
|
||||
|
||||
@Shadow
|
||||
public abstract DamageSource getDamageSource();
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Map<Player, Vec3> hitPlayers;
|
||||
@@ -83,7 +80,7 @@ public abstract class ExplosionMixin {
|
||||
@Final
|
||||
private boolean fire;
|
||||
|
||||
|
||||
@Shadow @Final private DamageSource damageSource;
|
||||
|
||||
@Unique
|
||||
private static final double[] CACHED_RAYS;
|
||||
@@ -164,7 +161,7 @@ public abstract class ExplosionMixin {
|
||||
this.chunkCache[chunkCacheKey] = chunk = this.level.getChunk(x >> 4, z >> 4);
|
||||
}
|
||||
|
||||
BlockState blockState = ((GetBlockChunk)chunk).getBlock(x, y, z);
|
||||
BlockState blockState = ((GetBlockChunk)chunk).moonrise$getBlock(x, y, z);
|
||||
FluidState fluidState = blockState.getFluidState();
|
||||
|
||||
Optional<Float> resistance = !calculateResistance ? Optional.empty() : this.damageCalculator.getBlockExplosionResistance((Explosion)(Object)this, this.level, pos, blockState, fluidState);
|
||||
@@ -245,10 +242,10 @@ public abstract class ExplosionMixin {
|
||||
}
|
||||
|
||||
final BlockState blockState = cachedBlock.blockState;
|
||||
if (blockState != null && !((CollisionBlockState)blockState).emptyCollisionShape()) {
|
||||
if (blockState != null && !((CollisionBlockState)blockState).moonrise$emptyCollisionShape()) {
|
||||
VoxelShape collision = cachedBlock.cachedCollisionShape;
|
||||
if (collision == null) {
|
||||
collision = ((CollisionBlockState)blockState).getConstantCollisionShape();
|
||||
collision = ((CollisionBlockState)blockState).moonrise$getConstantCollisionShape();
|
||||
if (collision == null) {
|
||||
collision = blockState.getCollisionShape(this.level, currPos, context);
|
||||
if (!context.isDelegated()) {
|
||||
@@ -455,7 +452,7 @@ public abstract class ExplosionMixin {
|
||||
|
||||
for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
final Entity entity = entities.get(i);
|
||||
if (entity.isSpectator() || entity.ignoreExplosion()) {
|
||||
if (entity.isSpectator() || entity.ignoreExplosion((Explosion)(Object)this)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -475,10 +472,9 @@ public abstract class ExplosionMixin {
|
||||
distZ /= distMag;
|
||||
|
||||
// route to new visible fraction calculation, using the existing block cache
|
||||
final double visibleFraction = (double)this.getSeenFraction(center, entity, blockCache, blockPos);
|
||||
final double intensityFraction = (1.0 - normalizedDistanceToCenter) * visibleFraction;
|
||||
final double intensityFraction = (1.0 - normalizedDistanceToCenter) * (double)this.getSeenFraction(center, entity, blockCache, blockPos);
|
||||
|
||||
entity.hurt(this.getDamageSource(), (float)((int)((intensityFraction * intensityFraction + intensityFraction) / 2.0 * 7.0 * diameter + 1.0)));
|
||||
entity.hurt(this.damageSource, (float)((int)((intensityFraction * intensityFraction + intensityFraction) / 2.0 * 7.0 * diameter + 1.0)));
|
||||
|
||||
final double knockbackFraction;
|
||||
if (entity instanceof LivingEntity livingEntity) {
|
||||
|
||||
@@ -18,7 +18,7 @@ public abstract class ExplosionProfileMixin implements LevelAccessor, AutoClosea
|
||||
private int count;
|
||||
|
||||
@Redirect(
|
||||
method = "explode(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;Z)Lnet/minecraft/world/level/Explosion;",
|
||||
method = "explode(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;ZLnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/sounds/SoundEvent;)Lnet/minecraft/world/level/Explosion;",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Explosion;explode()V"
|
||||
@@ -32,6 +32,10 @@ public abstract class ExplosionProfileMixin implements LevelAccessor, AutoClosea
|
||||
this.time += (end - start);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Spottedleaf
|
||||
* @reason print profile info
|
||||
*/
|
||||
@Overwrite
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
|
||||
@@ -3,27 +3,15 @@ package ca.spottedleaf.moonrise.mixin.fluid;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.util.CollisionDirection;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.util.FluidOcclusionCacheKey;
|
||||
import ca.spottedleaf.moonrise.patches.fluids.FluidClassification;
|
||||
import ca.spottedleaf.moonrise.patches.fluids.FluidFluid;
|
||||
import ca.spottedleaf.moonrise.patches.fluids.FluidFluidState;
|
||||
import com.google.common.collect.Maps;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ByteOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@@ -31,17 +19,10 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(FlowingFluid.class)
|
||||
public abstract class FlowingFluidMixin extends Fluid {
|
||||
|
||||
@Shadow
|
||||
protected abstract int getDropOff(LevelReader levelReader);
|
||||
|
||||
@Shadow
|
||||
public abstract Fluid getSource();
|
||||
|
||||
@@ -53,27 +34,9 @@ public abstract class FlowingFluidMixin extends Fluid {
|
||||
@Final
|
||||
public static IntegerProperty LEVEL;
|
||||
|
||||
@Shadow
|
||||
protected abstract boolean canConvertToSource(Level level);
|
||||
|
||||
@Shadow
|
||||
public abstract Fluid getFlowing();
|
||||
|
||||
@Shadow
|
||||
protected abstract void spreadTo(LevelAccessor levelAccessor, BlockPos blockPos, BlockState blockState, Direction direction, FluidState fluidState);
|
||||
|
||||
@Shadow
|
||||
protected abstract boolean canHoldFluid(BlockGetter blockGetter, BlockPos blockPos, BlockState blockState, Fluid fluid);
|
||||
|
||||
@Shadow
|
||||
protected abstract int getSlopeFindDistance(LevelReader levelReader);
|
||||
|
||||
|
||||
@Shadow
|
||||
private static short getCacheKey(BlockPos blockPos, BlockPos blockPos2) {
|
||||
return (short)0;
|
||||
}
|
||||
|
||||
|
||||
@Unique
|
||||
private FluidState sourceFalling;
|
||||
@@ -170,21 +133,21 @@ public abstract class FlowingFluidMixin extends Fluid {
|
||||
private boolean canPassThroughWall(final Direction direction, final BlockGetter level,
|
||||
final BlockPos fromPos, final BlockState fromState,
|
||||
final BlockPos toPos, final BlockState toState) {
|
||||
if (((CollisionBlockState)fromState).emptyCollisionShape() & ((CollisionBlockState)toState).emptyCollisionShape()) {
|
||||
if (((CollisionBlockState)fromState).moonrise$emptyCollisionShape() & ((CollisionBlockState)toState).moonrise$emptyCollisionShape()) {
|
||||
// don't even try to cache simple cases
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((CollisionBlockState)fromState).occludesFullBlock() | ((CollisionBlockState)toState).occludesFullBlock()) {
|
||||
if (((CollisionBlockState)fromState).moonrise$occludesFullBlock() | ((CollisionBlockState)toState).moonrise$occludesFullBlock()) {
|
||||
// don't even try to cache simple cases
|
||||
return false;
|
||||
}
|
||||
|
||||
final FluidOcclusionCacheKey[] cache = ((CollisionBlockState)fromState).hasCache() & ((CollisionBlockState)toState).hasCache() ?
|
||||
final FluidOcclusionCacheKey[] cache = ((CollisionBlockState)fromState).moonrise$hasCache() & ((CollisionBlockState)toState).moonrise$hasCache() ?
|
||||
COLLISION_OCCLUSION_CACHE : null;
|
||||
|
||||
final int keyIndex
|
||||
= (((CollisionBlockState)fromState).uniqueId1() ^ ((CollisionBlockState)toState).uniqueId2() ^ ((CollisionDirection)(Object)direction).uniqueId())
|
||||
= (((CollisionBlockState)fromState).moonrise$uniqueId1() ^ ((CollisionBlockState)toState).moonrise$uniqueId2() ^ ((CollisionDirection)(Object)direction).moonrise$uniqueId())
|
||||
& (COLLISION_OCCLUSION_CACHE_SIZE - 1);
|
||||
|
||||
if (cache != null) {
|
||||
@@ -206,424 +169,4 @@ public abstract class FlowingFluidMixin extends Fluid {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static final Direction[] HORIZONTAL_ARRAY = Direction.Plane.HORIZONTAL.stream().toList().toArray(new Direction[0]);
|
||||
|
||||
@Unique
|
||||
private static final FluidState EMPTY_FLUID_STATE = Fluids.EMPTY.defaultFluidState();
|
||||
|
||||
/**
|
||||
* @reason Optimise method
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
public FluidState getNewLiquid(final Level level, final BlockPos fromPos, final BlockState fromState) {
|
||||
final FluidClassification thisClassification = ((FluidFluid)this).getClassification();
|
||||
|
||||
LevelChunk lastChunk = null;
|
||||
int lastChunkX = Integer.MIN_VALUE;
|
||||
int lastChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
int newAmount = 0;
|
||||
int nearbySources = 0;
|
||||
|
||||
final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (final Direction direction : HORIZONTAL_ARRAY) {
|
||||
tempPos.set(fromPos.getX() + direction.getStepX(), fromPos.getY(), fromPos.getZ() + direction.getStepZ());
|
||||
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
|
||||
final BlockState neighbourState = lastChunk.getBlockState(tempPos);
|
||||
final FluidState fluidState = neighbourState.getFluidState();
|
||||
|
||||
if ((((FluidFluidState)(Object)fluidState).getClassification() == thisClassification) && this.canPassThroughWall(direction, level, fromPos, fromState, tempPos, neighbourState)) {
|
||||
if (fluidState.isSource()) {
|
||||
++nearbySources;
|
||||
}
|
||||
|
||||
newAmount = Math.max(newAmount, fluidState.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
tempPos.set(fromPos.getX(), fromPos.getY() - 1, fromPos.getZ());
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
|
||||
if (nearbySources >= 2 && this.canConvertToSource(level)) {
|
||||
final BlockState belowState = lastChunk.getBlockState(tempPos);
|
||||
final FluidState belowFluid = belowState.getFluidState();
|
||||
|
||||
if (belowState.isSolid() || (belowFluid.isSource() && ((FluidFluidState)(Object)belowFluid).getClassification() == thisClassification)) {
|
||||
return this.getSource(false);
|
||||
}
|
||||
}
|
||||
|
||||
tempPos.setY(fromPos.getY() + 1);
|
||||
final BlockState aboveState = lastChunk.getBlockState(tempPos);
|
||||
final FluidState aboveFluid = aboveState.getFluidState();
|
||||
|
||||
// drop empty check, we cannot be empty
|
||||
if ((((FluidFluidState)(Object)aboveFluid).getClassification() == thisClassification) && this.canPassThroughWall(Direction.UP, level, fromPos, fromState, tempPos, aboveState)) {
|
||||
return this.getFlowing(8, true);
|
||||
} else {
|
||||
final int finalAmount = newAmount - this.getDropOff(level);
|
||||
return finalAmount <= 0 ? EMPTY_FLUID_STATE : this.getFlowing(finalAmount, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
public void spread(final Level level, final BlockPos fromPos, final FluidState fromFluid) {
|
||||
if (fromFluid.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final LevelChunk fromChunk = level.getChunk(fromPos.getX() >> 4, fromPos.getZ() >> 4);
|
||||
final BlockState fromState = fromChunk.getBlockState(fromPos);
|
||||
final BlockPos belowPos = fromPos.below();
|
||||
final BlockState belowState = fromChunk.getBlockState(belowPos);
|
||||
final FluidState belowFluid = belowState.getFluidState();
|
||||
final FluidState newFluid = this.getNewLiquid(level, belowPos, belowState);
|
||||
|
||||
if (this.canSpreadTo(level, fromPos, fromState, Direction.DOWN, belowPos, belowState, belowFluid, newFluid.getType())) {
|
||||
this.spreadTo(level, belowPos, belowState, Direction.DOWN, newFluid);
|
||||
if (this.sourceNeighborCount(level, fromPos) >= 3) {
|
||||
this.spreadToSides(level, fromPos, fromFluid, fromState);
|
||||
}
|
||||
} else if (fromFluid.isSource() || !this.isWaterHole(level, newFluid.getType(), fromPos, fromState, belowPos, belowState)) {
|
||||
this.spreadToSides(level, fromPos, fromFluid, fromState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
private int sourceNeighborCount(final LevelReader level, final BlockPos fromPos) {
|
||||
final FluidClassification thisClassification = ((FluidFluid)this).getClassification();
|
||||
|
||||
ChunkAccess lastChunk = null;
|
||||
int lastChunkX = Integer.MIN_VALUE;
|
||||
int lastChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (final Direction direction : HORIZONTAL_ARRAY) {
|
||||
tempPos.set(fromPos.getX() + direction.getStepX(), fromPos.getY(), fromPos.getZ() + direction.getStepZ());
|
||||
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
|
||||
FluidState fluidState = lastChunk.getBlockState(tempPos).getFluidState();
|
||||
if (fluidState.isSource() && (((FluidFluidState)(Object)fluidState).getClassification() == thisClassification)) {
|
||||
++ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static final byte UNCACHED_RESULT = (byte)-1;
|
||||
|
||||
/**
|
||||
* @reason Optimise
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
public Map<Direction, FluidState> getSpread(final Level level, final BlockPos fromPos, final BlockState fromState) {
|
||||
ChunkAccess lastChunk = null;
|
||||
int lastChunkX = Integer.MIN_VALUE;
|
||||
int lastChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
int minSlope = 1000;
|
||||
|
||||
final Map<Direction, FluidState> ret = Maps.newEnumMap(Direction.class);
|
||||
final Short2ObjectOpenHashMap<BlockState> blockLookupCache = new Short2ObjectOpenHashMap<>();
|
||||
final Short2ByteOpenHashMap waterHoleCache = new Short2ByteOpenHashMap();
|
||||
waterHoleCache.defaultReturnValue(UNCACHED_RESULT);
|
||||
|
||||
final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (final Direction direction : HORIZONTAL_ARRAY) {
|
||||
tempPos.set(fromPos.getX() + direction.getStepX(), fromPos.getY(), fromPos.getZ() + direction.getStepZ());
|
||||
final short cacheKey = getCacheKey(fromPos, tempPos);
|
||||
|
||||
BlockState neighbourState = blockLookupCache.get(cacheKey);
|
||||
if (neighbourState == null) {
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
neighbourState = lastChunk.getBlockState(tempPos);
|
||||
blockLookupCache.put(cacheKey, neighbourState);
|
||||
}
|
||||
|
||||
final FluidState neighbourFluid = neighbourState.getFluidState();
|
||||
final FluidState newNeighbourFluid = this.getNewLiquid(level, tempPos, neighbourState);
|
||||
|
||||
if (this.canPassThrough(level, newNeighbourFluid.getType(), fromPos, fromState, direction, tempPos, neighbourState, neighbourFluid)) {
|
||||
byte isWaterHole = waterHoleCache.get(cacheKey);
|
||||
if (isWaterHole == UNCACHED_RESULT) {
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
final BlockPos neighbourBelowPos = tempPos.below();
|
||||
BlockState belowState = lastChunk.getBlockState(neighbourBelowPos);
|
||||
|
||||
isWaterHole = this.isWaterHole(level, this.getFlowing(), tempPos, neighbourState, neighbourBelowPos, belowState) ? (byte)1 : (byte)0;
|
||||
waterHoleCache.put(cacheKey, isWaterHole);
|
||||
}
|
||||
|
||||
final int slopeDistance = isWaterHole == (byte)1 ? 0 : this.getSlopeDistanceOptimised(
|
||||
level, tempPos, 1, direction.getOpposite(), neighbourState, fromPos, blockLookupCache, waterHoleCache,
|
||||
lastChunk, lastChunkX, lastChunkZ);
|
||||
|
||||
if (slopeDistance < minSlope) {
|
||||
ret.clear();
|
||||
}
|
||||
|
||||
if (slopeDistance <= minSlope) {
|
||||
ret.put(direction, newNeighbourFluid);
|
||||
minSlope = slopeDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static final Direction[][] HORIZONTAL_EXCEPT;
|
||||
static {
|
||||
final Direction[][] except = new Direction[Direction.values().length][];
|
||||
for (final Direction direction : HORIZONTAL_ARRAY) {
|
||||
final List<Direction> directionsWithout = new ArrayList<>(Arrays.asList(HORIZONTAL_ARRAY));
|
||||
directionsWithout.remove(direction);
|
||||
except[direction.ordinal()] = directionsWithout.toArray(new Direction[0]);
|
||||
}
|
||||
for (int i = 0; i < except.length; ++i) {
|
||||
if (except[i] == null) {
|
||||
except[i] = HORIZONTAL_ARRAY;
|
||||
}
|
||||
}
|
||||
HORIZONTAL_EXCEPT = except;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private int getSlopeDistanceOptimised(final LevelReader level, final BlockPos fromPos, final int step, final Direction fromDirection,
|
||||
final BlockState fromState, final BlockPos originPos,
|
||||
final Short2ObjectOpenHashMap<BlockState> blockLookupCache,
|
||||
final Short2ByteOpenHashMap belowIsWaterHole,
|
||||
ChunkAccess lastChunk, int lastChunkX, int lastChunkZ) {
|
||||
final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos();
|
||||
final Fluid flowing = this.getFlowing();
|
||||
|
||||
int ret = 1000;
|
||||
|
||||
for (final Direction direction : HORIZONTAL_EXCEPT[fromDirection.ordinal()]) {
|
||||
tempPos.set(fromPos.getX() + direction.getStepX(), fromPos.getY(), fromPos.getZ() + direction.getStepZ());
|
||||
final short cacheKey = getCacheKey(originPos, tempPos);
|
||||
|
||||
BlockState neighbourState = blockLookupCache.get(cacheKey);
|
||||
if (neighbourState == null) {
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
neighbourState = lastChunk.getBlockState(tempPos);
|
||||
blockLookupCache.put(cacheKey, neighbourState);
|
||||
}
|
||||
|
||||
FluidState neighbourFluid = neighbourState.getFluidState();
|
||||
if (this.canPassThrough(level, flowing, fromPos, fromState, direction, tempPos, neighbourState, neighbourFluid)) {
|
||||
byte isWaterHole = belowIsWaterHole.get(cacheKey);
|
||||
if (isWaterHole == UNCACHED_RESULT) {
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
|
||||
final BlockPos belowPos = tempPos.below();
|
||||
final BlockState belowState = lastChunk.getBlockState(belowPos);
|
||||
isWaterHole = this.isWaterHole(level, flowing, tempPos, neighbourState, belowPos, belowState) ? (byte)1 : (byte)0;
|
||||
belowIsWaterHole.put(cacheKey, isWaterHole);
|
||||
}
|
||||
if (isWaterHole == (byte)1) {
|
||||
return step;
|
||||
}
|
||||
|
||||
if (step < this.getSlopeFindDistance(level)) {
|
||||
final int slopeNeighbour = this.getSlopeDistanceOptimised(
|
||||
level, tempPos, step + 1, direction.getOpposite(), neighbourState, originPos, blockLookupCache, belowIsWaterHole,
|
||||
lastChunk, lastChunkX, lastChunkZ
|
||||
);
|
||||
ret = Math.min(slopeNeighbour, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Avoid indirection for empty/air case
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
public boolean canSpreadTo(final BlockGetter level,
|
||||
final BlockPos fromPos, final BlockState fromState, final Direction direction,
|
||||
final BlockPos toPos, final BlockState toState, final FluidState toFluid, final Fluid toType) {
|
||||
return (toFluid.isEmpty() || toFluid.canBeReplacedWith(level, toPos, toType, direction)) &&
|
||||
this.canPassThroughWall(direction, level, fromPos, fromState, toPos, toState) &&
|
||||
(toState.isAir() || this.canHoldFluid(level, toPos, toState, toType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
private void spreadToSides(final Level level, final BlockPos fromPos, final FluidState fromFluid, final BlockState fromState) {
|
||||
final int amount;
|
||||
if (fromFluid.getValue(FALLING).booleanValue()) {
|
||||
amount = 7;
|
||||
} else {
|
||||
amount = fromFluid.getAmount() - this.getDropOff(level);
|
||||
}
|
||||
|
||||
if (amount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ChunkAccess lastChunk = null;
|
||||
int lastChunkX = Integer.MIN_VALUE;
|
||||
int lastChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
final Map<Direction, FluidState> spread = this.getSpread(level, fromPos, fromState);
|
||||
final BlockPos.MutableBlockPos tempPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (final Map.Entry<Direction, FluidState> entry : spread.entrySet()) {
|
||||
final Direction direction = entry.getKey();
|
||||
final FluidState newFluid = entry.getValue();
|
||||
|
||||
tempPos.set(fromPos.getX() + direction.getStepX(), fromPos.getY() + direction.getStepY(), fromPos.getZ() + direction.getStepZ());
|
||||
|
||||
final int newChunkX = tempPos.getX() >> 4;
|
||||
final int newChunkZ = tempPos.getZ() >> 4;
|
||||
|
||||
final int chunkDiff = ((newChunkX ^ lastChunkX) | (newChunkZ ^ lastChunkZ));
|
||||
|
||||
if (chunkDiff != 0) {
|
||||
lastChunk = level.getChunk(newChunkX, newChunkZ);
|
||||
|
||||
lastChunkX = newChunkX;
|
||||
lastChunkZ = newChunkZ;
|
||||
}
|
||||
|
||||
final BlockState currentState = lastChunk.getBlockState(tempPos);
|
||||
final FluidState currentFluid = currentState.getFluidState();
|
||||
if (this.canSpreadTo(level, fromPos, fromState, direction, tempPos, currentState, currentFluid, newFluid.getType())) {
|
||||
this.spreadTo(level, tempPos, currentState, direction, newFluid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
private boolean isWaterHole(final BlockGetter level, final Fluid type,
|
||||
final BlockPos fromPos, final BlockState fromState,
|
||||
final BlockPos toPos, final BlockState toState) {
|
||||
final FluidClassification classification = ((FluidFluid)this).getClassification();
|
||||
final FluidClassification otherClassification = ((FluidFluidState)(Object)toState.getFluidState()).getClassification();
|
||||
return this.canPassThroughWall(Direction.DOWN, level, fromPos, fromState, toPos, toState) &&
|
||||
(
|
||||
(otherClassification == classification)
|
||||
|| (toState.isAir() || this.canHoldFluid(level, toPos, toState, type))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Optimise
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Overwrite
|
||||
private boolean canPassThrough(final BlockGetter level, final Fluid type,
|
||||
final BlockPos fromPos, final BlockState fromState, final Direction direction,
|
||||
final BlockPos toPos, final BlockState toState, final FluidState toFluid) {
|
||||
final FluidClassification classification = ((FluidFluid)this).getClassification();
|
||||
final FluidClassification otherClassification = ((FluidFluidState)(Object)toFluid).getClassification();
|
||||
|
||||
return (!toFluid.isSource() || classification != otherClassification) &&
|
||||
this.canPassThroughWall(direction, level, fromPos, fromState, toPos, toState) &&
|
||||
(toState.isAir() || this.canHoldFluid(level, toPos, toState, type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package ca.spottedleaf.moonrise.mixin.fluid;
|
||||
|
||||
import ca.spottedleaf.moonrise.patches.fluids.FluidClassification;
|
||||
import ca.spottedleaf.moonrise.patches.fluids.FluidFluid;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.world.level.material.EmptyFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.LavaFluid;
|
||||
import net.minecraft.world.level.material.WaterFluid;
|
||||
import org.slf4j.Logger;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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;
|
||||
|
||||
@Mixin(Fluid.class)
|
||||
public abstract class FluidMixin implements FluidFluid {
|
||||
|
||||
@Unique
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
@Unique
|
||||
private FluidClassification classification;
|
||||
|
||||
/**
|
||||
* @reason Init caches
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Inject(
|
||||
method = "<init>",
|
||||
at = @At(
|
||||
value = "RETURN"
|
||||
)
|
||||
)
|
||||
private void init(final CallbackInfo ci) {
|
||||
if ((Object)this instanceof EmptyFluid) {
|
||||
this.classification = FluidClassification.EMPTY;
|
||||
} else if ((Object)this instanceof LavaFluid) {
|
||||
this.classification = FluidClassification.LAVA;
|
||||
} else if ((Object)this instanceof WaterFluid) {
|
||||
this.classification = FluidClassification.WATER;
|
||||
}
|
||||
|
||||
if (this.classification == null) {
|
||||
LOGGER.error("Unknown fluid classification " + this.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidClassification getClassification() {
|
||||
return this.classification;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,12 @@
|
||||
package ca.spottedleaf.moonrise.mixin.fluid;
|
||||
|
||||
import ca.spottedleaf.moonrise.patches.fluids.FluidClassification;
|
||||
import ca.spottedleaf.moonrise.patches.fluids.FluidFluidState;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateHolder;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.EmptyFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.LavaFluid;
|
||||
import net.minecraft.world.level.material.WaterFluid;
|
||||
import org.slf4j.Logger;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -23,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(FluidState.class)
|
||||
public abstract class FluidStateMixin extends StateHolder<Fluid, FluidState> implements FluidFluidState {
|
||||
public abstract class FluidStateMixin extends StateHolder<Fluid, FluidState> {
|
||||
|
||||
@Shadow
|
||||
public abstract Fluid getType();
|
||||
@@ -32,9 +25,6 @@ public abstract class FluidStateMixin extends StateHolder<Fluid, FluidState> imp
|
||||
super(object, immutableMap, mapCodec);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
@Unique
|
||||
private int amount;
|
||||
|
||||
@@ -53,9 +43,6 @@ public abstract class FluidStateMixin extends StateHolder<Fluid, FluidState> imp
|
||||
@Unique
|
||||
private BlockState legacyBlock;
|
||||
|
||||
@Unique
|
||||
private FluidClassification classification;
|
||||
|
||||
/**
|
||||
* @reason Initialise caches
|
||||
* @author Spottedleaf
|
||||
@@ -72,21 +59,8 @@ public abstract class FluidStateMixin extends StateHolder<Fluid, FluidState> imp
|
||||
this.isSource = this.getType().isSource((FluidState)(Object)this);
|
||||
this.ownHeight = this.getType().getOwnHeight((FluidState)(Object)this);
|
||||
this.isRandomlyTicking = this.getType().isRandomlyTicking();
|
||||
|
||||
if (this.getType() instanceof EmptyFluid) {
|
||||
this.classification = FluidClassification.EMPTY;
|
||||
} else if (this.getType() instanceof LavaFluid) {
|
||||
this.classification = FluidClassification.LAVA;
|
||||
} else if (this.getType() instanceof WaterFluid) {
|
||||
this.classification = FluidClassification.WATER;
|
||||
}
|
||||
|
||||
if (this.classification == null) {
|
||||
LOGGER.error("Unknown fluid classification " + this.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @reason Use cached result, avoiding indirection
|
||||
* @author Spottedleaf
|
||||
@@ -152,9 +126,4 @@ public abstract class FluidStateMixin extends StateHolder<Fluid, FluidState> imp
|
||||
public boolean isRandomlyTicking() {
|
||||
return this.isRandomlyTicking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final FluidClassification getClassification() {
|
||||
return this.classification;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,16 +50,6 @@ public abstract class HopperBlockEntityMixin extends RandomizableContainerBlockE
|
||||
@Shadow
|
||||
protected abstract void setCooldown(int i);
|
||||
|
||||
@Shadow
|
||||
private static Container getSourceContainer(Level level, Hopper hopper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public static boolean addItem(Container container, ItemEntity itemEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Shadow
|
||||
private static boolean tryTakeInItemFromSlot(Hopper hopper, Container container, int i, Direction direction) {
|
||||
return false;
|
||||
@@ -200,20 +190,19 @@ public abstract class HopperBlockEntityMixin extends RandomizableContainerBlockE
|
||||
|
||||
final LevelChunk chunk = level.getChunk(blockX >> 4, blockZ >> 4);
|
||||
|
||||
final BlockState state = ((GetBlockChunk)chunk).getBlock(blockX, blockY, blockZ);
|
||||
final BlockState state = ((GetBlockChunk)chunk).moonrise$getBlock(blockX, blockY, blockZ);
|
||||
final Block block = state.getBlock();
|
||||
|
||||
Container blockContainer = null;
|
||||
if (block instanceof WorldlyContainerHolder worldlyContainerHolder) {
|
||||
blockContainer = worldlyContainerHolder.getContainer(state, level, new BlockPos(blockX, blockY, blockZ));
|
||||
} else if (state.hasBlockEntity() && !level.isOutsideBuildHeight(blockY)) {
|
||||
} else if (state.hasBlockEntity()) { // note: AIR is never outside build height, so we do not need to check
|
||||
final BlockPos pos = new BlockPos(blockX, blockY, blockZ);
|
||||
final BlockEntity blockEntity = chunk.getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE);
|
||||
if (blockEntity instanceof Container) {
|
||||
if (block instanceof ChestBlock chestBlock && blockEntity instanceof ChestBlockEntity) {
|
||||
blockContainer = ChestBlock.getContainer(chestBlock, state, level, pos, true);
|
||||
} else if (blockEntity instanceof Container) {
|
||||
blockContainer = (Container)blockEntity;
|
||||
if (block instanceof ChestBlock chestBlock && blockContainer instanceof ChestBlockEntity) {
|
||||
blockContainer = ChestBlock.getContainer(chestBlock, state, level, pos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,23 +2,19 @@ package ca.spottedleaf.moonrise.mixin.hopper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.RandomizableContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(RandomizableContainerBlockEntity.class)
|
||||
public abstract class RandomizableContainerBlockEntityMixin extends BaseContainerBlockEntity {
|
||||
|
||||
@Shadow
|
||||
public abstract void unpackLootTable(@Nullable Player player);
|
||||
public abstract class RandomizableContainerBlockEntityMixin extends BaseContainerBlockEntity implements RandomizableContainer {
|
||||
|
||||
@Shadow
|
||||
protected abstract NonNullList<ItemStack> getItems();
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
package ca.spottedleaf.moonrise.mixin.keep_alive_client;
|
||||
|
||||
import net.minecraft.network.TickablePacketListener;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ServerGamePacketListener;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.server.network.ServerPlayerConnection;
|
||||
import net.minecraft.network.protocol.common.ServerCommonPacketListener;
|
||||
import net.minecraft.server.network.ServerCommonPacketListenerImpl;
|
||||
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(ServerGamePacketListenerImpl.class)
|
||||
public abstract class ServerGamePacketListenerImplMixin extends net.minecraft.server.network.ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener {
|
||||
@Mixin(ServerCommonPacketListenerImpl.class)
|
||||
public abstract class ServerGamePacketListenerImplMixin implements ServerCommonPacketListener {
|
||||
|
||||
public ServerGamePacketListenerImplMixin(net.minecraft.server.MinecraftServer minecraftServer, net.minecraft.network.Connection connection, net.minecraft.server.network.CommonListenerCookie commonListenerCookie) {
|
||||
super(minecraftServer, connection, commonListenerCookie);
|
||||
}
|
||||
@Shadow
|
||||
protected abstract boolean isSingleplayerOwner();
|
||||
|
||||
/**
|
||||
* @reason Testing the explosion patch resulted in me being kicked for keepalive timeout as netty was unable to
|
||||
@@ -22,15 +20,14 @@ public abstract class ServerGamePacketListenerImplMixin extends net.minecraft.se
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Redirect(
|
||||
method = "tick",
|
||||
method = "keepConnectionAlive",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;disconnect(Lnet/minecraft/network/chat/Component;)V"
|
||||
target = "Lnet/minecraft/server/network/ServerCommonPacketListenerImpl;disconnect(Lnet/minecraft/network/chat/Component;)V"
|
||||
)
|
||||
)
|
||||
private void refuseSPKick(final ServerGamePacketListenerImpl instance, final Component component) {
|
||||
if (Component.translatable("disconnect.timeout").equals(component) &&
|
||||
((ServerGamePacketListenerImplMixin)(Object)instance).isSingleplayerOwner()) {
|
||||
private void refuseSPKick(final ServerCommonPacketListenerImpl instance, final Component component) {
|
||||
if (Component.translatable("disconnect.timeout").equals(component) && this.isSingleplayerOwner()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.injection.Constant;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||
|
||||
@Mixin(ServerSelectionList.class)
|
||||
public class ServerSelectionListMixin {
|
||||
public abstract class ServerSelectionListMixin {
|
||||
|
||||
/**
|
||||
* @reason Massively increase the threadpool count so that slow servers do not stall the pinging of other servers
|
||||
@@ -15,7 +15,9 @@ public class ServerSelectionListMixin {
|
||||
*/
|
||||
@ModifyConstant(
|
||||
method = "<clinit>",
|
||||
constant = @Constant(intValue = 5, ordinal = 0)
|
||||
constant = @Constant(
|
||||
intValue = 5, ordinal = 0
|
||||
)
|
||||
)
|
||||
private static int noPingLimitExecutor(final int constant) {
|
||||
return 128;
|
||||
|
||||
@@ -53,12 +53,12 @@ public abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isConditionallyFullOpaque() {
|
||||
public final boolean starlight$isConditionallyFullOpaque() {
|
||||
return this.isConditionallyFullOpaque;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getOpacityIfCached() {
|
||||
public final int starlight$getOpacityIfCached() {
|
||||
return this.opacityIfCached;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,42 +40,42 @@ public abstract class ChunkAccessMixin implements StarlightChunk {
|
||||
private volatile boolean[] blockEmptinessMap;
|
||||
|
||||
@Override
|
||||
public SWMRNibbleArray[] getBlockNibbles() {
|
||||
public SWMRNibbleArray[] starlight$getBlockNibbles() {
|
||||
return this.blockNibbles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
public void starlight$setBlockNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
this.blockNibbles = nibbles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWMRNibbleArray[] getSkyNibbles() {
|
||||
public SWMRNibbleArray[] starlight$getSkyNibbles() {
|
||||
return this.skyNibbles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
public void starlight$setSkyNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
this.skyNibbles = nibbles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getSkyEmptinessMap() {
|
||||
public boolean[] starlight$getSkyEmptinessMap() {
|
||||
return this.skyEmptinessMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyEmptinessMap(final boolean[] emptinessMap) {
|
||||
public void starlight$setSkyEmptinessMap(final boolean[] emptinessMap) {
|
||||
this.skyEmptinessMap = emptinessMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getBlockEmptinessMap() {
|
||||
public boolean[] starlight$getBlockEmptinessMap() {
|
||||
return this.blockEmptinessMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockEmptinessMap(final boolean[] emptinessMap) {
|
||||
public void starlight$setBlockEmptinessMap(final boolean[] emptinessMap) {
|
||||
this.blockEmptinessMap = emptinessMap;
|
||||
}
|
||||
|
||||
@@ -94,8 +94,8 @@ public abstract class ChunkAccessMixin implements StarlightChunk {
|
||||
CallbackInfo ci) {
|
||||
this.skyLightSources = null;
|
||||
if (!((Object)this instanceof ImposterProtoChunk)) {
|
||||
this.setBlockNibbles(StarLightEngine.getFilledEmptyLight(levelHeightAccessor));
|
||||
this.setSkyNibbles(StarLightEngine.getFilledEmptyLight(levelHeightAccessor));
|
||||
this.starlight$setBlockNibbles(StarLightEngine.getFilledEmptyLight(levelHeightAccessor));
|
||||
this.starlight$setSkyNibbles(StarLightEngine.getFilledEmptyLight(levelHeightAccessor));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,34 +17,34 @@ public abstract class EmptyLevelChunkMixin extends LevelChunk implements Starlig
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWMRNibbleArray[] getBlockNibbles() {
|
||||
public SWMRNibbleArray[] starlight$getBlockNibbles() {
|
||||
return StarLightEngine.getFilledEmptyLight(this.getLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockNibbles(final SWMRNibbleArray[] nibbles) {}
|
||||
public void starlight$setBlockNibbles(final SWMRNibbleArray[] nibbles) {}
|
||||
|
||||
@Override
|
||||
public SWMRNibbleArray[] getSkyNibbles() {
|
||||
public SWMRNibbleArray[] starlight$getSkyNibbles() {
|
||||
return StarLightEngine.getFilledEmptyLight(this.getLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyNibbles(final SWMRNibbleArray[] nibbles) {}
|
||||
public void starlight$setSkyNibbles(final SWMRNibbleArray[] nibbles) {}
|
||||
|
||||
@Override
|
||||
public boolean[] getSkyEmptinessMap() {
|
||||
public boolean[] starlight$getSkyEmptinessMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyEmptinessMap(final boolean[] emptinessMap) {}
|
||||
public void starlight$setSkyEmptinessMap(final boolean[] emptinessMap) {}
|
||||
|
||||
@Override
|
||||
public boolean[] getBlockEmptinessMap() {
|
||||
public boolean[] starlight$getBlockEmptinessMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockEmptinessMap(final boolean[] emptinessMap) {}
|
||||
public void starlight$setBlockEmptinessMap(final boolean[] emptinessMap) {}
|
||||
}
|
||||
|
||||
@@ -23,42 +23,42 @@ public abstract class ImposterProtoChunkMixin extends ProtoChunk implements Star
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWMRNibbleArray[] getBlockNibbles() {
|
||||
return ((StarlightChunk)this.wrapped).getBlockNibbles();
|
||||
public SWMRNibbleArray[] starlight$getBlockNibbles() {
|
||||
return ((StarlightChunk)this.wrapped).starlight$getBlockNibbles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
((StarlightChunk)this.wrapped).setBlockNibbles(nibbles);
|
||||
public void starlight$setBlockNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
((StarlightChunk)this.wrapped).starlight$setBlockNibbles(nibbles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWMRNibbleArray[] getSkyNibbles() {
|
||||
return ((StarlightChunk)this.wrapped).getSkyNibbles();
|
||||
public SWMRNibbleArray[] starlight$getSkyNibbles() {
|
||||
return ((StarlightChunk)this.wrapped).starlight$getSkyNibbles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
((StarlightChunk)this.wrapped).setSkyNibbles(nibbles);
|
||||
public void starlight$setSkyNibbles(final SWMRNibbleArray[] nibbles) {
|
||||
((StarlightChunk)this.wrapped).starlight$setSkyNibbles(nibbles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getSkyEmptinessMap() {
|
||||
return ((StarlightChunk)this.wrapped).getSkyEmptinessMap();
|
||||
public boolean[] starlight$getSkyEmptinessMap() {
|
||||
return ((StarlightChunk)this.wrapped).starlight$getSkyEmptinessMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyEmptinessMap(final boolean[] emptinessMap) {
|
||||
((StarlightChunk)this.wrapped).setSkyEmptinessMap(emptinessMap);
|
||||
public void starlight$setSkyEmptinessMap(final boolean[] emptinessMap) {
|
||||
((StarlightChunk)this.wrapped).starlight$setSkyEmptinessMap(emptinessMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getBlockEmptinessMap() {
|
||||
return ((StarlightChunk)this.wrapped).getBlockEmptinessMap();
|
||||
public boolean[] starlight$getBlockEmptinessMap() {
|
||||
return ((StarlightChunk)this.wrapped).starlight$getBlockEmptinessMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockEmptinessMap(final boolean[] emptinessMap) {
|
||||
((StarlightChunk)this.wrapped).setBlockEmptinessMap(emptinessMap);
|
||||
public void starlight$setBlockEmptinessMap(final boolean[] emptinessMap) {
|
||||
((StarlightChunk)this.wrapped).starlight$setBlockEmptinessMap(emptinessMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ public abstract class LevelChunkMixin implements StarlightChunk {
|
||||
at = @At("TAIL")
|
||||
)
|
||||
public void onTransitionToFull(ServerLevel serverLevel, ProtoChunk protoChunk, LevelChunk.PostLoadProcessor postLoadProcessor, CallbackInfo ci) {
|
||||
this.setBlockNibbles(((StarlightChunk)protoChunk).getBlockNibbles());
|
||||
this.setSkyNibbles(((StarlightChunk)protoChunk).getSkyNibbles());
|
||||
this.setSkyEmptinessMap(((StarlightChunk)protoChunk).getSkyEmptinessMap());
|
||||
this.setBlockEmptinessMap(((StarlightChunk)protoChunk).getBlockEmptinessMap());
|
||||
this.starlight$setBlockNibbles(((StarlightChunk)protoChunk).starlight$getBlockNibbles());
|
||||
this.starlight$setSkyNibbles(((StarlightChunk)protoChunk).starlight$getSkyNibbles());
|
||||
this.starlight$setSkyEmptinessMap(((StarlightChunk)protoChunk).starlight$getSkyEmptinessMap());
|
||||
this.starlight$setBlockEmptinessMap(((StarlightChunk)protoChunk).starlight$getBlockEmptinessMap());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,7 +45,7 @@ public abstract class LevelLightEngineMixin implements LightEventListener, StarL
|
||||
protected StarLightInterface lightEngine;
|
||||
|
||||
@Override
|
||||
public final StarLightInterface getLightEngine() {
|
||||
public final StarLightInterface starlight$getLightEngine() {
|
||||
return this.lightEngine;
|
||||
}
|
||||
|
||||
@@ -191,13 +191,13 @@ public abstract class LevelLightEngineMixin implements LightEventListener, StarL
|
||||
protected final Long2ObjectOpenHashMap<SWMRNibbleArray[]> skyLightMap = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
@Override
|
||||
public void clientUpdateLight(final LightLayer lightType, final SectionPos pos,
|
||||
final DataLayer nibble, final boolean trustEdges) {
|
||||
public void starlight$clientUpdateLight(final LightLayer lightType, final SectionPos pos,
|
||||
final DataLayer nibble, final boolean trustEdges) {
|
||||
if (((Object)this).getClass() != LevelLightEngine.class) {
|
||||
throw new IllegalStateException("This hook is for the CLIENT ONLY");
|
||||
}
|
||||
// data storage changed with new light impl
|
||||
final ChunkAccess chunk = this.getLightEngine().getAnyChunkNow(pos.getX(), pos.getZ());
|
||||
final ChunkAccess chunk = this.starlight$getLightEngine().getAnyChunkNow(pos.getX(), pos.getZ());
|
||||
switch (lightType) {
|
||||
case BLOCK: {
|
||||
final SWMRNibbleArray[] blockNibbles = this.blockLightMap.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> {
|
||||
@@ -207,7 +207,7 @@ public abstract class LevelLightEngineMixin implements LightEventListener, StarL
|
||||
blockNibbles[pos.getY() - WorldUtil.getMinLightSection(this.lightEngine.getWorld())] = SWMRNibbleArray.fromVanilla(nibble);
|
||||
|
||||
if (chunk != null) {
|
||||
((StarlightChunk)chunk).setBlockNibbles(blockNibbles);
|
||||
((StarlightChunk)chunk).starlight$setBlockNibbles(blockNibbles);
|
||||
this.lightEngine.getLightAccess().onLightUpdate(LightLayer.BLOCK, pos);
|
||||
}
|
||||
break;
|
||||
@@ -220,7 +220,7 @@ public abstract class LevelLightEngineMixin implements LightEventListener, StarL
|
||||
skyNibbles[pos.getY() - WorldUtil.getMinLightSection(this.lightEngine.getWorld())] = SWMRNibbleArray.fromVanilla(nibble);
|
||||
|
||||
if (chunk != null) {
|
||||
((StarlightChunk)chunk).setSkyNibbles(skyNibbles);
|
||||
((StarlightChunk)chunk).starlight$setSkyNibbles(skyNibbles);
|
||||
this.lightEngine.getLightAccess().onLightUpdate(LightLayer.SKY, pos);
|
||||
}
|
||||
break;
|
||||
@@ -229,7 +229,7 @@ public abstract class LevelLightEngineMixin implements LightEventListener, StarL
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clientRemoveLightData(final ChunkPos chunkPos) {
|
||||
public void starlight$clientRemoveLightData(final ChunkPos chunkPos) {
|
||||
if (((Object)this).getClass() != LevelLightEngine.class) {
|
||||
throw new IllegalStateException("This hook is for the CLIENT ONLY");
|
||||
}
|
||||
@@ -238,7 +238,7 @@ public abstract class LevelLightEngineMixin implements LightEventListener, StarL
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clientChunkLoad(final ChunkPos pos, final LevelChunk chunk) {
|
||||
public void starlight$clientChunkLoad(final ChunkPos pos, final LevelChunk chunk) {
|
||||
if (((Object)this).getClass() != LevelLightEngine.class) {
|
||||
throw new IllegalStateException("This hook is for the CLIENT ONLY");
|
||||
}
|
||||
@@ -246,10 +246,10 @@ public abstract class LevelLightEngineMixin implements LightEventListener, StarL
|
||||
final SWMRNibbleArray[] blockNibbles = this.blockLightMap.get(key);
|
||||
final SWMRNibbleArray[] skyNibbles = this.skyLightMap.get(key);
|
||||
if (blockNibbles != null) {
|
||||
((StarlightChunk)chunk).setBlockNibbles(blockNibbles);
|
||||
((StarlightChunk)chunk).starlight$setBlockNibbles(blockNibbles);
|
||||
}
|
||||
if (skyNibbles != null) {
|
||||
((StarlightChunk)chunk).setSkyNibbles(skyNibbles);
|
||||
((StarlightChunk)chunk).starlight$setSkyNibbles(skyNibbles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ public abstract class ThreadedLevelLightEngineMixin extends LevelLightEngine imp
|
||||
@Unique
|
||||
private void queueTaskForSection(final int chunkX, final int chunkY, final int chunkZ,
|
||||
final Supplier<StarLightInterface.LightQueue.ChunkTasks> runnable) {
|
||||
final ServerLevel world = (ServerLevel)this.getLightEngine().getWorld();
|
||||
final ServerLevel world = (ServerLevel)this.starlight$getLightEngine().getWorld();
|
||||
|
||||
final ChunkAccess center = this.getLightEngine().getAnyChunkNow(chunkX, chunkZ);
|
||||
final ChunkAccess center = this.starlight$getLightEngine().getAnyChunkNow(chunkX, chunkZ);
|
||||
if (center == null || !center.getStatus().isOrAfter(ChunkStatus.LIGHT)) {
|
||||
// do not accept updates in unlit chunks, unless we might be generating a chunk. thanks to the amazing
|
||||
// chunk scheduling, we could be lighting and generating a chunk at the same time
|
||||
@@ -121,7 +121,7 @@ public abstract class ThreadedLevelLightEngineMixin extends LevelLightEngine imp
|
||||
public void checkBlock(final BlockPos pos) {
|
||||
final BlockPos posCopy = pos.immutable();
|
||||
this.queueTaskForSection(posCopy.getX() >> 4, posCopy.getY() >> 4, posCopy.getZ() >> 4, () -> {
|
||||
return this.getLightEngine().blockChange(posCopy);
|
||||
return this.starlight$getLightEngine().blockChange(posCopy);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ public abstract class ThreadedLevelLightEngineMixin extends LevelLightEngine imp
|
||||
@Overwrite
|
||||
public void updateSectionStatus(final SectionPos pos, final boolean notReady) {
|
||||
this.queueTaskForSection(pos.getX(), pos.getY(), pos.getZ(), () -> {
|
||||
return this.getLightEngine().sectionChange(pos, notReady);
|
||||
return this.starlight$getLightEngine().sectionChange(pos, notReady);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -203,20 +203,20 @@ public abstract class ThreadedLevelLightEngineMixin extends LevelLightEngine imp
|
||||
final Boolean[] emptySections = StarLightEngine.getEmptySectionsForChunk(chunk);
|
||||
if (!lit) {
|
||||
chunk.setLightCorrect(false);
|
||||
this.getLightEngine().lightChunk(chunk, emptySections);
|
||||
this.starlight$getLightEngine().lightChunk(chunk, emptySections);
|
||||
chunk.setLightCorrect(true);
|
||||
} else {
|
||||
this.getLightEngine().forceLoadInChunk(chunk, emptySections);
|
||||
this.starlight$getLightEngine().forceLoadInChunk(chunk, emptySections);
|
||||
// can't really force the chunk to be edged checked, as we need neighbouring chunks - but we don't have
|
||||
// them, so if it's not loaded then i guess we can't do edge checks. later loads of the chunk should
|
||||
// catch what we miss here.
|
||||
this.getLightEngine().checkChunkEdges(chunkPos.x, chunkPos.z);
|
||||
this.starlight$getLightEngine().checkChunkEdges(chunkPos.x, chunkPos.z);
|
||||
}
|
||||
|
||||
this.chunkMap.releaseLightTicket(chunkPos);
|
||||
return chunk;
|
||||
}, (runnable) -> {
|
||||
this.getLightEngine().scheduleChunkLight(chunkPos, runnable);
|
||||
this.starlight$getLightEngine().scheduleChunkLight(chunkPos, runnable);
|
||||
this.tryScheduleUpdate();
|
||||
}).whenComplete((final ChunkAccess c, final Throwable throwable) -> {
|
||||
if (throwable != null) {
|
||||
|
||||
@@ -74,7 +74,7 @@ public abstract class ClientPacketListenerMixin implements ClientGamePacketListe
|
||||
)
|
||||
private void loadLightDataHook(final LevelLightEngine lightEngine, final LightLayer lightType, final SectionPos pos,
|
||||
final @Nullable DataLayer nibble) {
|
||||
((StarLightLightingProvider)this.level.getChunkSource().getLightEngine()).clientUpdateLight(lightType, pos, nibble, true);
|
||||
((StarLightLightingProvider)this.level.getChunkSource().getLightEngine()).starlight$clientUpdateLight(lightType, pos, nibble, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ public abstract class ClientPacketListenerMixin implements ClientGamePacketListe
|
||||
)
|
||||
)
|
||||
private void unloadLightDataHook(final ClientPacketListener instance, final ClientboundForgetLevelChunkPacket clientboundForgetLevelChunkPacket) {
|
||||
((StarLightLightingProvider)this.level.getChunkSource().getLightEngine()).clientRemoveLightData(new ChunkPos(clientboundForgetLevelChunkPacket.pos().x, clientboundForgetLevelChunkPacket.pos().z));
|
||||
((StarLightLightingProvider)this.level.getChunkSource().getLightEngine()).starlight$clientRemoveLightData(new ChunkPos(clientboundForgetLevelChunkPacket.pos().x, clientboundForgetLevelChunkPacket.pos().z));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +128,7 @@ public abstract class ClientPacketListenerMixin implements ClientGamePacketListe
|
||||
}
|
||||
// load in light data from packet immediately
|
||||
this.applyLightData(chunkX, chunkZ, clientboundLevelChunkWithLightPacket.getLightData());
|
||||
((StarLightLightingProvider)this.level.getChunkSource().getLightEngine()).clientChunkLoad(new ChunkPos(chunkX, chunkZ), chunk);
|
||||
((StarLightLightingProvider)this.level.getChunkSource().getLightEngine()).starlight$clientChunkLoad(new ChunkPos(chunkX, chunkZ), chunk);
|
||||
|
||||
// we need this for the update chunk status call, so that it can tell starlight what sections are empty and such
|
||||
this.enableChunkLight(chunk, chunkX, chunkZ);
|
||||
|
||||
@@ -14,7 +14,6 @@ import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.storage.WritableLevelData;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(ClientLevel.class)
|
||||
@@ -28,12 +27,12 @@ public abstract class ClientLevelMixin extends Level implements StarlightWorld {
|
||||
public abstract ClientChunkCache getChunkSource();
|
||||
|
||||
@Override
|
||||
public final LevelChunk getChunkAtImmediately(final int chunkX, final int chunkZ) {
|
||||
public final LevelChunk starlight$getChunkAtImmediately(final int chunkX, final int chunkZ) {
|
||||
return this.getChunkSource().getChunk(chunkX, chunkZ, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ChunkAccess getAnyChunkImmediately(int chunkX, int chunkZ) {
|
||||
public final ChunkAccess starlight$getAnyChunkImmediately(final int chunkX, final int chunkZ) {
|
||||
return this.getChunkSource().getChunk(chunkX, chunkZ, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
public abstract class LevelMixin implements LevelAccessor, AutoCloseable, StarlightWorld {
|
||||
|
||||
@Override
|
||||
public LevelChunk getChunkAtImmediately(final int chunkX, final int chunkZ) {
|
||||
public LevelChunk starlight$getChunkAtImmediately(final int chunkX, final int chunkZ) {
|
||||
return this.getChunkSource().getChunk(chunkX, chunkZ, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkAccess getAnyChunkImmediately(final int chunkX, final int chunkZ) {
|
||||
public ChunkAccess starlight$getAnyChunkImmediately(final int chunkX, final int chunkZ) {
|
||||
return this.getChunkSource().getChunk(chunkX, chunkX, ChunkStatus.EMPTY, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public abstract class ServerWorldMixin extends Level implements WorldGenLevel, S
|
||||
}
|
||||
|
||||
@Override
|
||||
public final LevelChunk getChunkAtImmediately(final int chunkX, final int chunkZ) {
|
||||
public final LevelChunk starlight$getChunkAtImmediately(final int chunkX, final int chunkZ) {
|
||||
final ChunkMap storage = this.chunkSource.chunkMap;
|
||||
final ChunkHolder holder = storage.getVisibleChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ));
|
||||
|
||||
@@ -49,7 +49,7 @@ public abstract class ServerWorldMixin extends Level implements WorldGenLevel, S
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ChunkAccess getAnyChunkImmediately(final int chunkX, final int chunkZ) {
|
||||
public final ChunkAccess starlight$getAnyChunkImmediately(final int chunkX, final int chunkZ) {
|
||||
final ChunkMap storage = this.chunkSource.chunkMap;
|
||||
final ChunkHolder holder = storage.getVisibleChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ));
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ package ca.spottedleaf.moonrise.patches.blockstate_propertyaccess;
|
||||
|
||||
public interface PropertyAccess<T> {
|
||||
|
||||
public int getId();
|
||||
public int moonrise$getId();
|
||||
|
||||
public int getIdFor(final T value);
|
||||
public int moonrise$getIdFor(final T value);
|
||||
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public final class ZeroCollidingReferenceStateTable {
|
||||
continue;
|
||||
}
|
||||
|
||||
states[((PropertyAccess)property).getIdFor(entry.getKey())] = entry.getValue();
|
||||
states[((PropertyAccess)property).moonrise$getIdFor(entry.getKey())] = entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public final class ZeroCollidingReferenceStateTable {
|
||||
this.value_table[index] = new StateHolder[property.getPossibleValues().size()];
|
||||
}
|
||||
|
||||
this.value_table[index][((PropertyAccess)property).getIdFor(entry.getValue())] = this.this_state;
|
||||
this.value_table[index][((PropertyAccess)property).moonrise$getIdFor(entry.getValue())] = this.this_state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public final class ZeroCollidingReferenceStateTable {
|
||||
protected long[] create_table(final Collection<Property<?>> collection) {
|
||||
int max_id = -1;
|
||||
for (final Property<?> property : collection) {
|
||||
final int id = ((PropertyAccess)property).getId();
|
||||
final int id = ((PropertyAccess)property).moonrise$getId();
|
||||
if (id > max_id) {
|
||||
max_id = id;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ public final class ZeroCollidingReferenceStateTable {
|
||||
final long[] ret = new long[((max_id + 1) + 31) >>> 5]; // ceil((max_id + 1) / 32)
|
||||
|
||||
for (final Property<?> property : collection) {
|
||||
final int id = ((PropertyAccess)property).getId();
|
||||
final int id = ((PropertyAccess)property).moonrise$getId();
|
||||
|
||||
ret[id >>> 5] |= (1L << (id & 31));
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public final class ZeroCollidingReferenceStateTable {
|
||||
|
||||
final StateHolder<?, ?>[] values = table[index];
|
||||
|
||||
final int withId = ((PropertyAccess)property).getIdFor(with);
|
||||
final int withId = ((PropertyAccess)property).moonrise$getIdFor(with);
|
||||
if (withId < 0 || withId >= values.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public final class ZeroCollidingReferenceStateTable {
|
||||
}
|
||||
|
||||
protected static int lookup_vindex(final Property<?> property, final long[] index_table) {
|
||||
final int id = ((PropertyAccess)property).getId();
|
||||
final int id = ((PropertyAccess)property).moonrise$getId();
|
||||
final long bitset_mask = (1L << (id & 31));
|
||||
final long lower_mask = bitset_mask - 1;
|
||||
final int index = id >>> 5;
|
||||
|
||||
@@ -4,6 +4,6 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface GetBlockChunk {
|
||||
|
||||
public BlockState getBlock(final int x, final int y, final int z);
|
||||
public BlockState moonrise$getBlock(final int x, final int y, final int z);
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@ import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.CollisionGetter;
|
||||
import net.minecraft.world.level.EntityGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -187,15 +185,15 @@ public final class CollisionUtil {
|
||||
// note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true
|
||||
|
||||
// offsets that should be applied to coords
|
||||
final double off_x = ((CollisionVoxelShape)voxel).offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)voxel).offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)voxel).offsetZ();
|
||||
final double off_x = ((CollisionVoxelShape)voxel).moonrise$offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)voxel).moonrise$offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)voxel).moonrise$offsetZ();
|
||||
|
||||
final double[] coords_x = ((CollisionVoxelShape)voxel).rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)voxel).rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)voxel).rootCoordinatesZ();
|
||||
final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ();
|
||||
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).getCachedVoxelData();
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData();
|
||||
|
||||
// note: size = coords.length - 1
|
||||
final int size_x = cached_shape_data.sizeX();
|
||||
@@ -290,22 +288,22 @@ public final class CollisionUtil {
|
||||
|
||||
// assume !target.isEmpty() && abs(source_move) >= COLLISION_EPSILON
|
||||
public static double collideX(final VoxelShape target, final AABB source, final double source_move) {
|
||||
final AABB single_aabb = ((CollisionVoxelShape)target).getSingleAABBRepresentation();
|
||||
final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation();
|
||||
if (single_aabb != null) {
|
||||
return collideX(single_aabb, source, source_move);
|
||||
}
|
||||
// note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true
|
||||
|
||||
// offsets that should be applied to coords
|
||||
final double off_x = ((CollisionVoxelShape)target).offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)target).offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)target).offsetZ();
|
||||
final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ();
|
||||
|
||||
final double[] coords_x = ((CollisionVoxelShape)target).rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)target).rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)target).rootCoordinatesZ();
|
||||
final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ();
|
||||
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).getCachedVoxelData();
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData();
|
||||
|
||||
// note: size = coords.length - 1
|
||||
final int size_x = cached_shape_data.sizeX();
|
||||
@@ -448,22 +446,22 @@ public final class CollisionUtil {
|
||||
}
|
||||
|
||||
public static double collideY(final VoxelShape target, final AABB source, final double source_move) {
|
||||
final AABB single_aabb = ((CollisionVoxelShape)target).getSingleAABBRepresentation();
|
||||
final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation();
|
||||
if (single_aabb != null) {
|
||||
return collideY(single_aabb, source, source_move);
|
||||
}
|
||||
// note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true
|
||||
|
||||
// offsets that should be applied to coords
|
||||
final double off_x = ((CollisionVoxelShape)target).offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)target).offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)target).offsetZ();
|
||||
final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ();
|
||||
|
||||
final double[] coords_x = ((CollisionVoxelShape)target).rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)target).rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)target).rootCoordinatesZ();
|
||||
final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ();
|
||||
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).getCachedVoxelData();
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData();
|
||||
|
||||
// note: size = coords.length - 1
|
||||
final int size_x = cached_shape_data.sizeX();
|
||||
@@ -606,22 +604,22 @@ public final class CollisionUtil {
|
||||
}
|
||||
|
||||
public static double collideZ(final VoxelShape target, final AABB source, final double source_move) {
|
||||
final AABB single_aabb = ((CollisionVoxelShape)target).getSingleAABBRepresentation();
|
||||
final AABB single_aabb = ((CollisionVoxelShape)target).moonrise$getSingleAABBRepresentation();
|
||||
if (single_aabb != null) {
|
||||
return collideZ(single_aabb, source, source_move);
|
||||
}
|
||||
// note: this function assumes that for any i in coords that coord[i + 1] - coord[i] > COLLISION_EPSILON is true
|
||||
|
||||
// offsets that should be applied to coords
|
||||
final double off_x = ((CollisionVoxelShape)target).offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)target).offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)target).offsetZ();
|
||||
final double off_x = ((CollisionVoxelShape)target).moonrise$offsetX();
|
||||
final double off_y = ((CollisionVoxelShape)target).moonrise$offsetY();
|
||||
final double off_z = ((CollisionVoxelShape)target).moonrise$offsetZ();
|
||||
|
||||
final double[] coords_x = ((CollisionVoxelShape)target).rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)target).rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)target).rootCoordinatesZ();
|
||||
final double[] coords_x = ((CollisionVoxelShape)target).moonrise$rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)target).moonrise$rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)target).moonrise$rootCoordinatesZ();
|
||||
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).getCachedVoxelData();
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)target).moonrise$getCachedVoxelData();
|
||||
|
||||
// note: size = coords.length - 1
|
||||
final int size_x = cached_shape_data.sizeX();
|
||||
@@ -770,7 +768,7 @@ public final class CollisionUtil {
|
||||
|
||||
// does not use epsilon
|
||||
public static boolean strictlyContains(final VoxelShape voxel, double x, double y, double z) {
|
||||
final AABB single_aabb = ((CollisionVoxelShape)voxel).getSingleAABBRepresentation();
|
||||
final AABB single_aabb = ((CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation();
|
||||
if (single_aabb != null) {
|
||||
return single_aabb.contains(x, y, z);
|
||||
}
|
||||
@@ -781,15 +779,15 @@ public final class CollisionUtil {
|
||||
}
|
||||
|
||||
// offset input
|
||||
x -= ((CollisionVoxelShape)voxel).offsetX();
|
||||
y -= ((CollisionVoxelShape)voxel).offsetY();
|
||||
z -= ((CollisionVoxelShape)voxel).offsetZ();
|
||||
x -= ((CollisionVoxelShape)voxel).moonrise$offsetX();
|
||||
y -= ((CollisionVoxelShape)voxel).moonrise$offsetY();
|
||||
z -= ((CollisionVoxelShape)voxel).moonrise$offsetZ();
|
||||
|
||||
final double[] coords_x = ((CollisionVoxelShape)voxel).rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)voxel).rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)voxel).rootCoordinatesZ();
|
||||
final double[] coords_x = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesX();
|
||||
final double[] coords_y = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesY();
|
||||
final double[] coords_z = ((CollisionVoxelShape)voxel).moonrise$rootCoordinatesZ();
|
||||
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).getCachedVoxelData();
|
||||
final CachedShapeData cached_shape_data = ((CollisionVoxelShape)voxel).moonrise$getCachedVoxelData();
|
||||
|
||||
// note: size = coords.length - 1
|
||||
final int size_x = cached_shape_data.sizeX();
|
||||
@@ -983,8 +981,8 @@ public final class CollisionUtil {
|
||||
|
||||
if (!tt) {
|
||||
// try to check for no intersection, since tt = false
|
||||
final AABB aabbF = ((CollisionVoxelShape)first).getSingleAABBRepresentation();
|
||||
final AABB aabbS = ((CollisionVoxelShape)second).getSingleAABBRepresentation();
|
||||
final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation();
|
||||
final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation();
|
||||
|
||||
final boolean intersect;
|
||||
|
||||
@@ -1014,32 +1012,32 @@ public final class CollisionUtil {
|
||||
}
|
||||
|
||||
final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge(
|
||||
((CollisionVoxelShape)first).rootCoordinatesX(), ((CollisionVoxelShape)first).offsetX(),
|
||||
((CollisionVoxelShape)second).rootCoordinatesX(), ((CollisionVoxelShape)second).offsetX(),
|
||||
((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(),
|
||||
((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(),
|
||||
ft, tf
|
||||
);
|
||||
if (mergedX == MergedVoxelCoordinateList.EMPTY) {
|
||||
return Shapes.empty();
|
||||
}
|
||||
final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge(
|
||||
((CollisionVoxelShape)first).rootCoordinatesY(), ((CollisionVoxelShape)first).offsetY(),
|
||||
((CollisionVoxelShape)second).rootCoordinatesY(), ((CollisionVoxelShape)second).offsetY(),
|
||||
((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(),
|
||||
((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(),
|
||||
ft, tf
|
||||
);
|
||||
if (mergedY == MergedVoxelCoordinateList.EMPTY) {
|
||||
return Shapes.empty();
|
||||
}
|
||||
final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge(
|
||||
((CollisionVoxelShape)first).rootCoordinatesZ(), ((CollisionVoxelShape)first).offsetZ(),
|
||||
((CollisionVoxelShape)second).rootCoordinatesZ(), ((CollisionVoxelShape)second).offsetZ(),
|
||||
((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(),
|
||||
((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(),
|
||||
ft, tf
|
||||
);
|
||||
if (mergedZ == MergedVoxelCoordinateList.EMPTY) {
|
||||
return Shapes.empty();
|
||||
}
|
||||
|
||||
final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).getCachedVoxelData();
|
||||
final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).getCachedVoxelData();
|
||||
final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData();
|
||||
final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData();
|
||||
|
||||
final BitSetDiscreteVoxelShape mergedShape = merge(
|
||||
shapeDataFirst, shapeDataSecond,
|
||||
@@ -1078,8 +1076,8 @@ public final class CollisionUtil {
|
||||
final boolean tf = operator.apply(true, false);
|
||||
|
||||
// try to check intersection
|
||||
final AABB aabbF = ((CollisionVoxelShape)first).getSingleAABBRepresentation();
|
||||
final AABB aabbS = ((CollisionVoxelShape)second).getSingleAABBRepresentation();
|
||||
final AABB aabbF = ((CollisionVoxelShape)first).moonrise$getSingleAABBRepresentation();
|
||||
final AABB aabbS = ((CollisionVoxelShape)second).moonrise$getSingleAABBRepresentation();
|
||||
|
||||
final boolean intersect;
|
||||
|
||||
@@ -1112,32 +1110,32 @@ public final class CollisionUtil {
|
||||
}
|
||||
|
||||
final MergedVoxelCoordinateList mergedX = MergedVoxelCoordinateList.merge(
|
||||
((CollisionVoxelShape)first).rootCoordinatesX(), ((CollisionVoxelShape)first).offsetX(),
|
||||
((CollisionVoxelShape)second).rootCoordinatesX(), ((CollisionVoxelShape)second).offsetX(),
|
||||
((CollisionVoxelShape)first).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)first).moonrise$offsetX(),
|
||||
((CollisionVoxelShape)second).moonrise$rootCoordinatesX(), ((CollisionVoxelShape)second).moonrise$offsetX(),
|
||||
ft, tf
|
||||
);
|
||||
if (mergedX == MergedVoxelCoordinateList.EMPTY) {
|
||||
return false;
|
||||
}
|
||||
final MergedVoxelCoordinateList mergedY = MergedVoxelCoordinateList.merge(
|
||||
((CollisionVoxelShape)first).rootCoordinatesY(), ((CollisionVoxelShape)first).offsetY(),
|
||||
((CollisionVoxelShape)second).rootCoordinatesY(), ((CollisionVoxelShape)second).offsetY(),
|
||||
((CollisionVoxelShape)first).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)first).moonrise$offsetY(),
|
||||
((CollisionVoxelShape)second).moonrise$rootCoordinatesY(), ((CollisionVoxelShape)second).moonrise$offsetY(),
|
||||
ft, tf
|
||||
);
|
||||
if (mergedY == MergedVoxelCoordinateList.EMPTY) {
|
||||
return false;
|
||||
}
|
||||
final MergedVoxelCoordinateList mergedZ = MergedVoxelCoordinateList.merge(
|
||||
((CollisionVoxelShape)first).rootCoordinatesZ(), ((CollisionVoxelShape)first).offsetZ(),
|
||||
((CollisionVoxelShape)second).rootCoordinatesZ(), ((CollisionVoxelShape)second).offsetZ(),
|
||||
((CollisionVoxelShape)first).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)first).moonrise$offsetZ(),
|
||||
((CollisionVoxelShape)second).moonrise$rootCoordinatesZ(), ((CollisionVoxelShape)second).moonrise$offsetZ(),
|
||||
ft, tf
|
||||
);
|
||||
if (mergedZ == MergedVoxelCoordinateList.EMPTY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).getCachedVoxelData();
|
||||
final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).getCachedVoxelData();
|
||||
final CachedShapeData shapeDataFirst = ((CollisionVoxelShape)first).moonrise$getCachedVoxelData();
|
||||
final CachedShapeData shapeDataSecond = ((CollisionVoxelShape)second).moonrise$getCachedVoxelData();
|
||||
|
||||
return !isMergeEmpty(
|
||||
shapeDataFirst, shapeDataSecond,
|
||||
@@ -1298,8 +1296,8 @@ public final class CollisionUtil {
|
||||
}
|
||||
|
||||
public static boolean equals(final DiscreteVoxelShape shape1, final DiscreteVoxelShape shape2) {
|
||||
final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).getOrCreateCachedShapeData();
|
||||
final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).getOrCreateCachedShapeData();
|
||||
final CachedShapeData cachedShapeData1 = ((CollisionDiscreteVoxelShape)shape1).moonrise$getOrCreateCachedShapeData();
|
||||
final CachedShapeData cachedShapeData2 = ((CollisionDiscreteVoxelShape)shape2).moonrise$getOrCreateCachedShapeData();
|
||||
|
||||
final boolean isEmpty1 = cachedShapeData1.isEmpty();
|
||||
final boolean isEmpty2 = cachedShapeData2.isEmpty();
|
||||
@@ -1662,13 +1660,13 @@ public final class CollisionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
final int minSection = ((CollisionLevel)world).getMinSectionMoonrise();
|
||||
final int minSection = ((CollisionLevel)world).moonrise$getMinSection();
|
||||
|
||||
final int minBlockX = Mth.floor(aabb.minX - COLLISION_EPSILON) - 1;
|
||||
final int maxBlockX = Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1;
|
||||
|
||||
final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - COLLISION_EPSILON) - 1);
|
||||
final int maxBlockY = Math.min((((CollisionLevel)world).getMaxSectionMoonrise() << 4) + 16, Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1);
|
||||
final int maxBlockY = Math.min((((CollisionLevel)world).moonrise$getMaxSection() << 4) + 16, Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1);
|
||||
|
||||
final int minBlockZ = Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1;
|
||||
final int maxBlockZ = Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1;
|
||||
@@ -1724,7 +1722,7 @@ public final class CollisionUtil {
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean hasSpecial = ((CollisionLevelChunkSection)section).getSpecialCollidingBlocks() != 0;
|
||||
final boolean hasSpecial = ((CollisionLevelChunkSection)section).moonrise$getSpecialCollidingBlocks() != 0;
|
||||
final int sectionAdjust = !hasSpecial ? 1 : 0;
|
||||
|
||||
final PalettedContainer<BlockState> blocks = section.states;
|
||||
@@ -1753,19 +1751,19 @@ public final class CollisionUtil {
|
||||
|
||||
final BlockState blockData = blocks.get(localBlockIndex);
|
||||
|
||||
if (((CollisionBlockState)blockData).emptyCollisionShape()) {
|
||||
if (((CollisionBlockState)blockData).moonrise$emptyCollisionShape()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) {
|
||||
VoxelShape blockCollision = ((CollisionBlockState)blockData).getConstantCollisionShape();
|
||||
VoxelShape blockCollision = ((CollisionBlockState)blockData).moonrise$getConstantCollisionShape();
|
||||
|
||||
if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) {
|
||||
if (blockCollision == null) {
|
||||
mutablePos.set(blockX, blockY, blockZ);
|
||||
blockCollision = blockData.getCollisionShape(world, mutablePos, collisionShape);
|
||||
}
|
||||
|
||||
AABB singleAABB = ((CollisionVoxelShape)blockCollision).getSingleAABBRepresentation();
|
||||
AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation();
|
||||
if (singleAABB != null) {
|
||||
singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ);
|
||||
if (!voxelShapeIntersect(aabb, singleAABB)) {
|
||||
@@ -1823,12 +1821,9 @@ public final class CollisionUtil {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean getEntityHardCollisions(final CollisionGetter getter, final Entity entity, AABB aabb,
|
||||
public static boolean getEntityHardCollisions(final Level world, final Entity entity, AABB aabb,
|
||||
final List<AABB> into, final int collisionFlags, final Predicate<Entity> predicate) {
|
||||
final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0;
|
||||
if (!(getter instanceof EntityGetter entityGetter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean ret = false;
|
||||
|
||||
@@ -1837,10 +1832,10 @@ public final class CollisionUtil {
|
||||
// specifically with boat collisions.
|
||||
aabb = aabb.inflate(-COLLISION_EPSILON, -COLLISION_EPSILON, -COLLISION_EPSILON);
|
||||
final List<Entity> entities;
|
||||
if (entity != null && ((CollisionEntity)entity).isHardColliding()) {
|
||||
entities = entityGetter.getEntities(entity, aabb, predicate);
|
||||
if (entity != null && ((CollisionEntity)entity).moonrise$isHardColliding()) {
|
||||
entities = world.getEntities(entity, aabb, predicate);
|
||||
} else {
|
||||
entities = ((CollisionEntityGetter)entityGetter).getHardCollidingEntities(entity, aabb, predicate);
|
||||
entities = ((CollisionEntityGetter)world).moonrise$getHardCollidingEntities(entity, aabb, predicate);
|
||||
}
|
||||
|
||||
for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
|
||||
@@ -7,23 +7,23 @@ public interface CollisionBlockState {
|
||||
|
||||
// note: this does not consider canOcclude, it is only based on the cached collision shape (i.e hasCache())
|
||||
// and whether Shapes.faceShapeOccludes(EMPTY, cached shape) is true
|
||||
public boolean occludesFullBlock();
|
||||
public boolean moonrise$occludesFullBlock();
|
||||
|
||||
// whether the cached collision shape exists and is empty
|
||||
public boolean emptyCollisionShape();
|
||||
public boolean moonrise$emptyCollisionShape();
|
||||
|
||||
// indicates that occludesFullBlock is cached for the collision shape
|
||||
public boolean hasCache();
|
||||
public boolean moonrise$hasCache();
|
||||
|
||||
// note: this is HashCommon#murmurHash3(incremental id); and since murmurHash3 has an inverse function the returned
|
||||
// value is still unique
|
||||
public int uniqueId1();
|
||||
public int moonrise$uniqueId1();
|
||||
|
||||
// note: this is HashCommon#murmurHash3(incremental id); and since murmurHash3 has an inverse function the returned
|
||||
// value is still unique
|
||||
public int uniqueId2();
|
||||
public int moonrise$uniqueId2();
|
||||
|
||||
public VoxelShape getConstantCollisionShape();
|
||||
public VoxelShape moonrise$getConstantCollisionShape();
|
||||
|
||||
public AABB getConstantCollisionAABB();
|
||||
public AABB moonrise$getConstantCollisionAABB();
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import net.minecraft.world.entity.vehicle.Boat;
|
||||
|
||||
public interface CollisionEntity {
|
||||
|
||||
public boolean isHardColliding();
|
||||
public boolean moonrise$isHardColliding();
|
||||
|
||||
// for mods to override
|
||||
public default boolean isHardCollidingUncached() {
|
||||
public default boolean moonrise$isHardCollidingUncached() {
|
||||
return this instanceof Boat || this instanceof AbstractMinecart || this instanceof Shulker || ((Entity)this).canBeCollidedWith();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ package ca.spottedleaf.moonrise.patches.collisions.shape;
|
||||
|
||||
public interface CollisionDiscreteVoxelShape {
|
||||
|
||||
public CachedShapeData getOrCreateCachedShapeData();
|
||||
public CachedShapeData moonrise$getOrCreateCachedShapeData();
|
||||
|
||||
}
|
||||
|
||||
@@ -6,35 +6,35 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public interface CollisionVoxelShape {
|
||||
|
||||
public double offsetX();
|
||||
public double moonrise$offsetX();
|
||||
|
||||
public double offsetY();
|
||||
public double moonrise$offsetY();
|
||||
|
||||
public double offsetZ();
|
||||
public double moonrise$offsetZ();
|
||||
|
||||
public double[] rootCoordinatesX();
|
||||
public double[] moonrise$rootCoordinatesX();
|
||||
|
||||
public double[] rootCoordinatesY();
|
||||
public double[] moonrise$rootCoordinatesY();
|
||||
|
||||
public double[] rootCoordinatesZ();
|
||||
public double[] moonrise$rootCoordinatesZ();
|
||||
|
||||
public CachedShapeData getCachedVoxelData();
|
||||
public CachedShapeData moonrise$getCachedVoxelData();
|
||||
|
||||
// rets null if not possible to represent this shape as one AABB
|
||||
public AABB getSingleAABBRepresentation();
|
||||
public AABB moonrise$getSingleAABBRepresentation();
|
||||
|
||||
// ONLY USE INTERNALLY, ONLY FOR INITIALISING IN CONSTRUCTOR: VOXELSHAPES ARE STATIC
|
||||
public void initCache();
|
||||
public void moonrise$initCache();
|
||||
|
||||
// this returns empty if not clamped to 1.0 or 0.0 depending on direction
|
||||
public VoxelShape getFaceShapeClamped(final Direction direction);
|
||||
public VoxelShape moonrise$getFaceShapeClamped(final Direction direction);
|
||||
|
||||
public boolean isFullBlock();
|
||||
public boolean moonrise$isFullBlock();
|
||||
|
||||
public boolean occludesFullBlock();
|
||||
public boolean moonrise$occludesFullBlock();
|
||||
|
||||
public boolean occludesFullBlockIfCached();
|
||||
public boolean moonrise$occludesFullBlockIfCached();
|
||||
|
||||
// uses a cache internally
|
||||
public VoxelShape orUnoptimized(final VoxelShape other);
|
||||
public VoxelShape moonrise$orUnoptimized(final VoxelShape other);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public final class ChunkEntitySlices {
|
||||
|
||||
this.allEntities.addEntity(entity, sectionIndex);
|
||||
|
||||
if (((CollisionEntity)entity).isHardColliding()) {
|
||||
if (((CollisionEntity)entity).moonrise$isHardColliding()) {
|
||||
this.hardCollidingEntities.addEntity(entity, sectionIndex);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public final class ChunkEntitySlices {
|
||||
|
||||
this.allEntities.removeEntity(entity, sectionIndex);
|
||||
|
||||
if (((CollisionEntity)entity).isHardColliding()) {
|
||||
if (((CollisionEntity)entity).moonrise$isHardColliding()) {
|
||||
this.hardCollidingEntities.removeEntity(entity, sectionIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,6 @@ public interface CollisionDirection {
|
||||
|
||||
// note: this is HashCommon#murmurHash3(some unique id) and since murmurHash3 has an inverse function the returned
|
||||
// value is still unique
|
||||
public int uniqueId();
|
||||
public int moonrise$uniqueId();
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ import java.util.function.Predicate;
|
||||
|
||||
public interface CollisionEntityGetter {
|
||||
|
||||
public List<Entity> getHardCollidingEntities(final Entity entity, final AABB box, final Predicate<? super Entity> predicate);
|
||||
public List<Entity> moonrise$getHardCollidingEntities(final Entity entity, final AABB box, final Predicate<? super Entity> predicate);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ import ca.spottedleaf.moonrise.patches.collisions.slices.EntityLookup;
|
||||
|
||||
public interface CollisionLevel {
|
||||
|
||||
public EntityLookup getCollisionLookup();
|
||||
public EntityLookup moonrise$getCollisionLookup();
|
||||
|
||||
// avoid name conflicts by appending mod name
|
||||
|
||||
public int getMinSectionMoonrise();
|
||||
public int moonrise$getMinSection();
|
||||
|
||||
public int getMaxSectionMoonrise();
|
||||
public int moonrise$getMaxSection();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package ca.spottedleaf.moonrise.patches.collisions.world;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface CollisionLevelChunkSection {
|
||||
|
||||
public int getSpecialCollidingBlocks();
|
||||
public int moonrise$getSpecialCollidingBlocks();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package ca.spottedleaf.moonrise.patches.fluids;
|
||||
|
||||
public enum FluidClassification {
|
||||
EMPTY,
|
||||
WATER,
|
||||
LAVA;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package ca.spottedleaf.moonrise.patches.fluids;
|
||||
|
||||
public interface FluidFluid {
|
||||
|
||||
public FluidClassification getClassification();
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package ca.spottedleaf.moonrise.patches.fluids;
|
||||
|
||||
public interface FluidFluidState {
|
||||
|
||||
public FluidClassification getClassification();
|
||||
}
|
||||
@@ -2,8 +2,8 @@ package ca.spottedleaf.moonrise.patches.starlight.blockstate;
|
||||
|
||||
public interface StarlightAbstractBlockState {
|
||||
|
||||
public boolean isConditionallyFullOpaque();
|
||||
public boolean starlight$isConditionallyFullOpaque();
|
||||
|
||||
public int getOpacityIfCached();
|
||||
public int starlight$getOpacityIfCached();
|
||||
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ import ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray;
|
||||
|
||||
public interface StarlightChunk {
|
||||
|
||||
public SWMRNibbleArray[] getBlockNibbles();
|
||||
public void setBlockNibbles(final SWMRNibbleArray[] nibbles);
|
||||
public SWMRNibbleArray[] starlight$getBlockNibbles();
|
||||
public void starlight$setBlockNibbles(final SWMRNibbleArray[] nibbles);
|
||||
|
||||
public SWMRNibbleArray[] getSkyNibbles();
|
||||
public void setSkyNibbles(final SWMRNibbleArray[] nibbles);
|
||||
public SWMRNibbleArray[] starlight$getSkyNibbles();
|
||||
public void starlight$setSkyNibbles(final SWMRNibbleArray[] nibbles);
|
||||
|
||||
public boolean[] getSkyEmptinessMap();
|
||||
public void setSkyEmptinessMap(final boolean[] emptinessMap);
|
||||
public boolean[] starlight$getSkyEmptinessMap();
|
||||
public void starlight$setSkyEmptinessMap(final boolean[] emptinessMap);
|
||||
|
||||
public boolean[] getBlockEmptinessMap();
|
||||
public void setBlockEmptinessMap(final boolean[] emptinessMap);
|
||||
public boolean[] starlight$getBlockEmptinessMap();
|
||||
public void starlight$setBlockEmptinessMap(final boolean[] emptinessMap);
|
||||
}
|
||||
|
||||
@@ -24,22 +24,22 @@ public final class BlockStarLightEngine extends StarLightEngine {
|
||||
|
||||
@Override
|
||||
protected boolean[] getEmptinessMap(final ChunkAccess chunk) {
|
||||
return ((StarlightChunk)chunk).getBlockEmptinessMap();
|
||||
return ((StarlightChunk)chunk).starlight$getBlockEmptinessMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEmptinessMap(final ChunkAccess chunk, final boolean[] to) {
|
||||
((StarlightChunk)chunk).setBlockEmptinessMap(to);
|
||||
((StarlightChunk)chunk).starlight$setBlockEmptinessMap(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SWMRNibbleArray[] getNibblesOnChunk(final ChunkAccess chunk) {
|
||||
return ((StarlightChunk)chunk).getBlockNibbles();
|
||||
return ((StarlightChunk)chunk).starlight$getBlockNibbles();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setNibbles(final ChunkAccess chunk, final SWMRNibbleArray[] to) {
|
||||
((StarlightChunk)chunk).setBlockNibbles(to);
|
||||
((StarlightChunk)chunk).starlight$setBlockNibbles(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,7 +100,7 @@ public final class BlockStarLightEngine extends StarLightEngine {
|
||||
((worldX + (worldZ << 6) + (worldY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1))
|
||||
| (emittedLevel & 0xFL) << (6 + 6 + 16)
|
||||
| (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4))
|
||||
| (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque() ? FLAG_HAS_SIDED_TRANSPARENT_BLOCKS : 0)
|
||||
| (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? FLAG_HAS_SIDED_TRANSPARENT_BLOCKS : 0)
|
||||
);
|
||||
}
|
||||
// this also accounts for a change in emitted light that would cause a decrease
|
||||
@@ -133,12 +133,12 @@ public final class BlockStarLightEngine extends StarLightEngine {
|
||||
|
||||
final int sectionOffset = this.chunkSectionIndexOffset;
|
||||
final BlockState conditionallyOpaqueState;
|
||||
int opacity = ((StarlightAbstractBlockState)centerState).getOpacityIfCached();
|
||||
int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached();
|
||||
|
||||
if (opacity == -1) {
|
||||
this.recalcCenterPos.set(worldX, worldY, worldZ);
|
||||
opacity = centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos);
|
||||
if (((StarlightAbstractBlockState)centerState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) {
|
||||
conditionallyOpaqueState = centerState;
|
||||
} else {
|
||||
conditionallyOpaqueState = null;
|
||||
@@ -165,7 +165,7 @@ public final class BlockStarLightEngine extends StarLightEngine {
|
||||
}
|
||||
|
||||
final BlockState neighbourState = this.getBlockState(offX, offY, offZ);
|
||||
if (((StarlightAbstractBlockState)neighbourState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)neighbourState).starlight$isConditionallyFullOpaque()) {
|
||||
// here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that
|
||||
// we don't read the blockstate because most of the time this is false, so using the faster
|
||||
// known transparency lookup results in a net win
|
||||
@@ -254,7 +254,7 @@ public final class BlockStarLightEngine extends StarLightEngine {
|
||||
((pos.getX() + (pos.getZ() << 6) + (pos.getY() << (6 + 6)) + this.coordinateOffset) & ((1L << (6 + 6 + 16)) - 1))
|
||||
| (emittedLight & 0xFL) << (6 + 6 + 16)
|
||||
| (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4))
|
||||
| (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque() ? FLAG_HAS_SIDED_TRANSPARENT_BLOCKS : 0)
|
||||
| (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? FLAG_HAS_SIDED_TRANSPARENT_BLOCKS : 0)
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -208,22 +208,22 @@ public final class SkyStarLightEngine extends StarLightEngine {
|
||||
|
||||
@Override
|
||||
protected boolean[] getEmptinessMap(final ChunkAccess chunk) {
|
||||
return ((StarlightChunk)chunk).getSkyEmptinessMap();
|
||||
return ((StarlightChunk)chunk).starlight$getSkyEmptinessMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEmptinessMap(final ChunkAccess chunk, final boolean[] to) {
|
||||
((StarlightChunk)chunk).setSkyEmptinessMap(to);
|
||||
((StarlightChunk)chunk).starlight$setSkyEmptinessMap(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SWMRNibbleArray[] getNibblesOnChunk(final ChunkAccess chunk) {
|
||||
return ((StarlightChunk)chunk).getSkyNibbles();
|
||||
return ((StarlightChunk)chunk).starlight$getSkyNibbles();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setNibbles(final ChunkAccess chunk, final SWMRNibbleArray[] to) {
|
||||
((StarlightChunk)chunk).setSkyNibbles(to);
|
||||
((StarlightChunk)chunk).starlight$setSkyNibbles(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -302,13 +302,13 @@ public final class SkyStarLightEngine extends StarLightEngine {
|
||||
|
||||
final int sectionOffset = this.chunkSectionIndexOffset;
|
||||
final BlockState centerState = this.getBlockState(worldX, worldY, worldZ);
|
||||
int opacity = ((StarlightAbstractBlockState)centerState).getOpacityIfCached();
|
||||
int opacity = ((StarlightAbstractBlockState)centerState).starlight$getOpacityIfCached();
|
||||
|
||||
final BlockState conditionallyOpaqueState;
|
||||
if (opacity < 0) {
|
||||
this.recalcCenterPos.set(worldX, worldY, worldZ);
|
||||
opacity = Math.max(1, centerState.getLightBlock(lightAccess.getLevel(), this.recalcCenterPos));
|
||||
if (((StarlightAbstractBlockState)centerState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)centerState).starlight$isConditionallyFullOpaque()) {
|
||||
conditionallyOpaqueState = centerState;
|
||||
} else {
|
||||
conditionallyOpaqueState = null;
|
||||
@@ -336,7 +336,7 @@ public final class SkyStarLightEngine extends StarLightEngine {
|
||||
|
||||
final BlockState neighbourState = this.getBlockState(offX, offY, offZ);
|
||||
|
||||
if (((StarlightAbstractBlockState)neighbourState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)neighbourState).starlight$isConditionallyFullOpaque()) {
|
||||
// here the block can be conditionally opaque (i.e light cannot propagate from it), so we need to test that
|
||||
// we don't read the blockstate because most of the time this is false, so using the faster
|
||||
// known transparency lookup results in a net win
|
||||
@@ -631,7 +631,7 @@ public final class SkyStarLightEngine extends StarLightEngine {
|
||||
final BlockState current = this.getBlockState(worldX, startY, worldZ);
|
||||
|
||||
final VoxelShape fromShape;
|
||||
if (((StarlightAbstractBlockState)above).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)above).starlight$isConditionallyFullOpaque()) {
|
||||
this.mutablePos2.set(worldX, startY + 1, worldZ);
|
||||
fromShape = above.getFaceOcclusionShape(world, this.mutablePos2, AxisDirection.NEGATIVE_Y.nms);
|
||||
if (Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) {
|
||||
@@ -642,7 +642,7 @@ public final class SkyStarLightEngine extends StarLightEngine {
|
||||
fromShape = Shapes.empty();
|
||||
}
|
||||
|
||||
final int opacityIfCached = ((StarlightAbstractBlockState)current).getOpacityIfCached();
|
||||
final int opacityIfCached = ((StarlightAbstractBlockState)current).starlight$getOpacityIfCached();
|
||||
// does light propagate from the top down?
|
||||
if (opacityIfCached != -1) {
|
||||
if (opacityIfCached != 0) {
|
||||
@@ -660,7 +660,7 @@ public final class SkyStarLightEngine extends StarLightEngine {
|
||||
} else {
|
||||
mutablePos.set(worldX, startY, worldZ);
|
||||
long flags = 0L;
|
||||
if (((StarlightAbstractBlockState)current).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)current).starlight$isConditionallyFullOpaque()) {
|
||||
final VoxelShape cullingFace = current.getFaceOcclusionShape(world, mutablePos, AxisDirection.POSITIVE_Y.nms);
|
||||
|
||||
if (Shapes.faceShapeOccludes(fromShape, cullingFace)) {
|
||||
|
||||
@@ -1150,7 +1150,7 @@ public abstract class StarLightEngine {
|
||||
if (blockState == null) {
|
||||
continue;
|
||||
}
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).getOpacityIfCached();
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached();
|
||||
if (opacityCached != -1) {
|
||||
final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached);
|
||||
if (targetLevel > currentLevel) {
|
||||
@@ -1172,7 +1172,7 @@ public abstract class StarLightEngine {
|
||||
} else {
|
||||
this.mutablePos1.set(offX, offY, offZ);
|
||||
long flags = 0;
|
||||
if (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) {
|
||||
final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms);
|
||||
|
||||
if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) {
|
||||
@@ -1212,7 +1212,7 @@ public abstract class StarLightEngine {
|
||||
final int offY = posY + propagate.y;
|
||||
final int offZ = posZ + propagate.z;
|
||||
|
||||
final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty();
|
||||
final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty();
|
||||
|
||||
if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) {
|
||||
continue;
|
||||
@@ -1232,7 +1232,7 @@ public abstract class StarLightEngine {
|
||||
if (blockState == null) {
|
||||
continue;
|
||||
}
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).getOpacityIfCached();
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached();
|
||||
if (opacityCached != -1) {
|
||||
final int targetLevel = propagatedLightLevel - Math.max(1, opacityCached);
|
||||
if (targetLevel > currentLevel) {
|
||||
@@ -1254,7 +1254,7 @@ public abstract class StarLightEngine {
|
||||
} else {
|
||||
this.mutablePos1.set(offX, offY, offZ);
|
||||
long flags = 0;
|
||||
if (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) {
|
||||
final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms);
|
||||
|
||||
if (Shapes.faceShapeOccludes(fromShape, cullingFace)) {
|
||||
@@ -1335,7 +1335,7 @@ public abstract class StarLightEngine {
|
||||
if (blockState == null) {
|
||||
continue;
|
||||
}
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).getOpacityIfCached();
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached();
|
||||
if (opacityCached != -1) {
|
||||
final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached));
|
||||
if (lightLevel > targetLevel) {
|
||||
@@ -1361,7 +1361,7 @@ public abstract class StarLightEngine {
|
||||
((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1))
|
||||
| ((emittedLight & 0xFL) << (6 + 6 + 16))
|
||||
| (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4))
|
||||
| (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL);
|
||||
| (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL);
|
||||
}
|
||||
|
||||
currentNibble.set(localIndex, 0);
|
||||
@@ -1381,7 +1381,7 @@ public abstract class StarLightEngine {
|
||||
} else {
|
||||
this.mutablePos1.set(offX, offY, offZ);
|
||||
long flags = 0;
|
||||
if (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) {
|
||||
final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms);
|
||||
|
||||
if (Shapes.faceShapeOccludes(Shapes.empty(), cullingFace)) {
|
||||
@@ -1446,7 +1446,7 @@ public abstract class StarLightEngine {
|
||||
final int sectionIndex = (offX >> 4) + 5 * (offZ >> 4) + (5 * 5) * (offY >> 4) + sectionOffset;
|
||||
final int localIndex = (offX & 15) | ((offZ & 15) << 4) | ((offY & 15) << 8);
|
||||
|
||||
final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty();
|
||||
final VoxelShape fromShape = (((StarlightAbstractBlockState)fromBlock).starlight$isConditionallyFullOpaque()) ? fromBlock.getFaceOcclusionShape(world, this.mutablePos2, propagate.nms) : Shapes.empty();
|
||||
|
||||
if (fromShape != Shapes.empty() && Shapes.faceShapeOccludes(Shapes.empty(), fromShape)) {
|
||||
continue;
|
||||
@@ -1464,7 +1464,7 @@ public abstract class StarLightEngine {
|
||||
if (blockState == null) {
|
||||
continue;
|
||||
}
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).getOpacityIfCached();
|
||||
final int opacityCached = ((StarlightAbstractBlockState)blockState).starlight$getOpacityIfCached();
|
||||
if (opacityCached != -1) {
|
||||
final int targetLevel = Math.max(0, propagatedLightLevel - Math.max(1, opacityCached));
|
||||
if (lightLevel > targetLevel) {
|
||||
@@ -1490,7 +1490,7 @@ public abstract class StarLightEngine {
|
||||
((offX + (offZ << 6) + (offY << 12) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1))
|
||||
| ((emittedLight & 0xFL) << (6 + 6 + 16))
|
||||
| (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4))
|
||||
| (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL);
|
||||
| (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque() ? (FLAG_WRITE_LEVEL | FLAG_HAS_SIDED_TRANSPARENT_BLOCKS) : FLAG_WRITE_LEVEL);
|
||||
}
|
||||
|
||||
currentNibble.set(localIndex, 0);
|
||||
@@ -1510,7 +1510,7 @@ public abstract class StarLightEngine {
|
||||
} else {
|
||||
this.mutablePos1.set(offX, offY, offZ);
|
||||
long flags = 0;
|
||||
if (((StarlightAbstractBlockState)blockState).isConditionallyFullOpaque()) {
|
||||
if (((StarlightAbstractBlockState)blockState).starlight$isConditionallyFullOpaque()) {
|
||||
final VoxelShape cullingFace = blockState.getFaceOcclusionShape(world, this.mutablePos1, propagate.getOpposite().nms);
|
||||
|
||||
if (Shapes.faceShapeOccludes(fromShape, cullingFace)) {
|
||||
|
||||
@@ -117,11 +117,11 @@ public final class StarLightInterface {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (((StarlightChunk)chunk).getSkyEmptinessMap() == null) {
|
||||
if (((StarlightChunk)chunk).starlight$getSkyEmptinessMap() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((StarlightChunk)chunk).getSkyNibbles()[sectionY - StarLightInterface.this.minLightSection].toVanillaNibble();
|
||||
return ((StarlightChunk)chunk).starlight$getSkyNibbles()[sectionY - StarLightInterface.this.minLightSection].toVanillaNibble();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,7 +169,7 @@ public final class StarLightInterface {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((StarlightChunk)chunk).getBlockNibbles()[pos.getY() - StarLightInterface.this.minLightSection].toVanillaNibble();
|
||||
return ((StarlightChunk)chunk).starlight$getBlockNibbles()[pos.getY() - StarLightInterface.this.minLightSection].toVanillaNibble();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,14 +220,14 @@ public final class StarLightInterface {
|
||||
y = sectionY << 4;
|
||||
}
|
||||
|
||||
final SWMRNibbleArray[] nibbles = ((StarlightChunk)chunk).getSkyNibbles();
|
||||
final SWMRNibbleArray[] nibbles = ((StarlightChunk)chunk).starlight$getSkyNibbles();
|
||||
final SWMRNibbleArray immediate = nibbles[sectionY - minLightSection];
|
||||
|
||||
if (!immediate.isNullNibbleVisible()) {
|
||||
return immediate.getVisible(x, y, z);
|
||||
}
|
||||
|
||||
final boolean[] emptinessMap = ((StarlightChunk)chunk).getSkyEmptinessMap();
|
||||
final boolean[] emptinessMap = ((StarlightChunk)chunk).starlight$getSkyEmptinessMap();
|
||||
|
||||
if (emptinessMap == null) {
|
||||
return 15;
|
||||
@@ -280,7 +280,7 @@ public final class StarLightInterface {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final SWMRNibbleArray nibble = ((StarlightChunk)chunk).getBlockNibbles()[cy - minLightSection];
|
||||
final SWMRNibbleArray nibble = ((StarlightChunk)chunk).starlight$getBlockNibbles()[cy - minLightSection];
|
||||
return nibble.getVisible(blockPos.getX(), y, blockPos.getZ());
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ public final class StarLightInterface {
|
||||
// empty world
|
||||
return null;
|
||||
}
|
||||
return ((StarlightWorld)this.world).getAnyChunkImmediately(chunkX, chunkZ);
|
||||
return ((StarlightWorld)this.world).starlight$getAnyChunkImmediately(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
public boolean hasUpdates() {
|
||||
|
||||
@@ -8,13 +8,13 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
||||
|
||||
public interface StarLightLightingProvider {
|
||||
|
||||
public StarLightInterface getLightEngine();
|
||||
public StarLightInterface starlight$getLightEngine();
|
||||
|
||||
public void clientUpdateLight(final LightLayer lightType, final SectionPos pos,
|
||||
final DataLayer nibble, final boolean trustEdges);
|
||||
public void starlight$clientUpdateLight(final LightLayer lightType, final SectionPos pos,
|
||||
final DataLayer nibble, final boolean trustEdges);
|
||||
|
||||
public void clientRemoveLightData(final ChunkPos chunkPos);
|
||||
public void starlight$clientRemoveLightData(final ChunkPos chunkPos);
|
||||
|
||||
public void clientChunkLoad(final ChunkPos pos, final LevelChunk chunk);
|
||||
public void starlight$clientChunkLoad(final ChunkPos pos, final LevelChunk chunk);
|
||||
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ public final class SaveUtil {
|
||||
final int minSection = WorldUtil.getMinLightSection(world);
|
||||
final int maxSection = WorldUtil.getMaxLightSection(world);
|
||||
|
||||
SWMRNibbleArray[] blockNibbles = ((StarlightChunk)chunk).getBlockNibbles();
|
||||
SWMRNibbleArray[] skyNibbles = ((StarlightChunk)chunk).getSkyNibbles();
|
||||
SWMRNibbleArray[] blockNibbles = ((StarlightChunk)chunk).starlight$getBlockNibbles();
|
||||
SWMRNibbleArray[] skyNibbles = ((StarlightChunk)chunk).starlight$getSkyNibbles();
|
||||
|
||||
boolean lit = chunk.isLightCorrect() || !(world instanceof ServerLevel);
|
||||
// diff start - store our tag for whether light data is init'd
|
||||
@@ -185,8 +185,8 @@ public final class SaveUtil {
|
||||
}
|
||||
// end copy from vanilla
|
||||
|
||||
((StarlightChunk)into).setBlockNibbles(blockNibbles);
|
||||
((StarlightChunk)into).setSkyNibbles(skyNibbles);
|
||||
((StarlightChunk)into).starlight$setBlockNibbles(blockNibbles);
|
||||
((StarlightChunk)into).starlight$setSkyNibbles(skyNibbles);
|
||||
into.setLightCorrect(lit); // now we set lit here, only after we've correctly parsed data
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
||||
public interface StarlightWorld {
|
||||
|
||||
// rets full chunk without blocking
|
||||
public LevelChunk getChunkAtImmediately(final int chunkX, final int chunkZ);
|
||||
public LevelChunk starlight$getChunkAtImmediately(final int chunkX, final int chunkZ);
|
||||
|
||||
// rets chunk at any stage, if it exists, immediately
|
||||
public ChunkAccess getAnyChunkImmediately(final int chunkX, final int chunkZ);
|
||||
public ChunkAccess starlight$getAnyChunkImmediately(final int chunkX, final int chunkZ);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"id": "moonrise",
|
||||
"version": "${version}",
|
||||
"name": "Moonrise",
|
||||
"description": "",
|
||||
"description": "Optimisation mod for the client and server",
|
||||
"authors": [
|
||||
"Spottedleaf"
|
||||
],
|
||||
"contact": {
|
||||
"issues": "https://github.com/Spottedleaf/Moonrise/issues",
|
||||
"sources": "https://github.com/Spottedleaf/Moonrise",
|
||||
"issues": "https://github.com/Tuinity/Moonrise/issues",
|
||||
"sources": "https://github.com/Tuinity/Moonrise",
|
||||
"discord": "https://discord.gg/tuinity",
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/moonrise"
|
||||
},
|
||||
@@ -27,7 +27,7 @@
|
||||
],
|
||||
"accessWidener" : "moonrise.accesswidener",
|
||||
"depends": {
|
||||
"fabricloader": ">=0.14.19",
|
||||
"minecraft": "1.20.2"
|
||||
"fabricloader": ">=${loader_version}",
|
||||
"minecraft": "${minecraft_version}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,4 +118,9 @@ accessible method net/minecraft/world/level/material/Fluid isRandomlyTicking ()Z
|
||||
|
||||
# VisibilitySet
|
||||
accessible field net/minecraft/client/renderer/chunk/VisibilitySet FACINGS I
|
||||
accessible field net/minecraft/client/renderer/chunk/VisibilitySet data Ljava/util/BitSet;
|
||||
accessible field net/minecraft/client/renderer/chunk/VisibilitySet data Ljava/util/BitSet;
|
||||
|
||||
|
||||
# Level
|
||||
mutable field net/minecraft/world/level/Level blockEntityTickers Ljava/util/List;
|
||||
mutable field net/minecraft/world/level/Level pendingBlockEntityTickers Ljava/util/List;
|
||||
@@ -6,6 +6,7 @@
|
||||
"mixins": [
|
||||
"bitstorage.SimpleBitStorageMixin",
|
||||
"bitstorage.ZeroBitStorageMixin",
|
||||
"block_entity_remove.LevelMixin",
|
||||
"blockstate_propertyaccess.BooleanPropertyMixin",
|
||||
"blockstate_propertyaccess.EnumPropertyMixin",
|
||||
"blockstate_propertyaccess.IntegerPropertyMixin",
|
||||
@@ -39,7 +40,6 @@
|
||||
"explosions.ExplosionMixin",
|
||||
"explosions.ExplosionProfileMixin",
|
||||
"fluid.FlowingFluidMixin",
|
||||
"fluid.FluidMixin",
|
||||
"fluid.FluidStateMixin",
|
||||
"hopper.HopperBlockEntityMixin",
|
||||
"hopper.RandomizableContainerBlockEntityMixin",
|
||||
|
||||
Reference in New Issue
Block a user