Skip to content

Commit

Permalink
Partial implementation for non-cubic-worlds with extended height
Browse files Browse the repository at this point in the history
  • Loading branch information
Barteks2x committed Nov 3, 2023
1 parent 381eb08 commit 7253e3c
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.github.opencubicchunks.cubicchunks.api.world.ICubicWorld;
import io.github.opencubicchunks.cubicchunks.api.world.IColumn;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.ViewFrustum;
import net.minecraft.client.renderer.chunk.RenderChunk;
Expand Down Expand Up @@ -76,6 +77,8 @@ public class MixinRenderGlobal {

@Shadow private ViewFrustum viewFrustum;

@Shadow private WorldClient world;

/*
* This allows to get the Y position of rendered entity by injecting itself directly before call to
* chunk.getEntityLists
Expand Down Expand Up @@ -163,7 +166,7 @@ private int getRenderChunkYPos(BlockPos pos) {
if (this.position != null) { // also set from optifine specific mixins
return 0;//must be 0 (or anything between 0 and 15)
}
return pos.getY();
return pos.getY() - ((ICubicWorld) world).getMinHeight();
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.github.opencubicchunks.cubicchunks.api.world.ICube;
import io.github.opencubicchunks.cubicchunks.api.world.ICubicWorld;
import io.github.opencubicchunks.cubicchunks.api.world.IHeightMap;
import io.github.opencubicchunks.cubicchunks.api.world.IMinMaxHeight;
import io.github.opencubicchunks.cubicchunks.core.CubicChunksConfig;
import io.github.opencubicchunks.cubicchunks.core.asm.mixin.ICubicWorldInternal;
import io.github.opencubicchunks.cubicchunks.core.world.ClientHeightMap;
Expand Down Expand Up @@ -148,7 +149,7 @@ public <T extends World & ICubicWorldInternal> T getWorld() {
@Unique @Nullable
private ExtendedBlockStorage getEBS_CubicChunks(int index) {
if (!isColumn) {
return storageArrays[index];
return storageArrays[index - Coords.blockToCube(getWorld().getMinHeight())];
}
if (cachedCube != null && cachedCube.getY() == index) {
return cachedCube.getStorage();
Expand All @@ -163,7 +164,7 @@ private ExtendedBlockStorage getEBS_CubicChunks(int index) {
// setEBS is unlikely to be used extremely frequently, no caching
@Unique private void setEBS_CubicChunks(int index, ExtendedBlockStorage ebs) {
if (!isColumn) {
storageArrays[index] = ebs;
storageArrays[index - Coords.blockToCube(getWorld().getMinHeight())] = ebs;
return;
}
if (index >= 0 && index < 16) {
Expand Down Expand Up @@ -221,6 +222,31 @@ private void cubicChunkColumn_construct(World world, int x, int z, CallbackInfo
Arrays.fill(getBiomeArray(), (byte) -1);
}

@ModifyConstant(method = "<init>(Lnet/minecraft/world/World;II)V", constant = @Constant(intValue = 16))
private int modifySectionArrayLength(int sixteen, World worldIn, int x, int z) {
IMinMaxHeight y = (IMinMaxHeight) worldIn;
return Coords.blockToCube(y.getMaxHeight()) - Coords.blockToCube(y.getMinHeight()) + 1;
}

@Redirect(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/ChunkPrimer;II)V",
at = @At(
value = "FIELD",
args = "array=get",
target = "Lnet/minecraft/world/chunk/Chunk;storageArrays:[Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;"
))
private ExtendedBlockStorage init_getStorage(ExtendedBlockStorage[] ebs, int y) {
return ebs[y - Coords.blockToCube(((IMinMaxHeight) world).getMinHeight())];
}

@Redirect(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/ChunkPrimer;II)V",
at = @At(
value = "FIELD",
args = "array=set",
target = "Lnet/minecraft/world/chunk/Chunk;storageArrays:[Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;"
))
private void getBlockState_getMaxHeight(ExtendedBlockStorage[] ebs, int y, ExtendedBlockStorage val) {
ebs[y - Coords.blockToCube(((IMinMaxHeight) world).getMinHeight())] = val;
}
@ModifyConstant(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/ChunkPrimer;II)V",
constant = @Constant(intValue = 16, ordinal = 0), require = 1)
private int getInitChunkLoopEnd(int _16, World world, ChunkPrimer primer, int x, int z) {
Expand Down Expand Up @@ -300,6 +326,17 @@ private void generateSkylightMap_CubicChunks_Replace(CallbackInfo cbi) {
}
}


@Nullable
@Redirect(method = "generateSkylightMap", at = @At(
value = "FIELD",
target = "Lnet/minecraft/world/chunk/Chunk;storageArrays:[Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;",
args = "array=get"
))
private ExtendedBlockStorage generateSkylightMapRedirectEBSAccess(ExtendedBlockStorage[] array, int index) {
return getEBS_CubicChunks(index);
}

// ==============================================
// propagateSkylightOcclusion
// ==============================================
Expand Down Expand Up @@ -402,7 +439,7 @@ private boolean getBlockLightOpacity_isChunkLoadedCubeRedirect(Chunk chunk, int
constant = @Constant(expandZeroConditions = Constant.Condition.GREATER_THAN_OR_EQUAL_TO_ZERO),
require = 1)
private int getBlockState_getMinHeight(int zero) {
return isColumn ? Integer.MIN_VALUE : 0;
return isColumn ? Integer.MIN_VALUE : getWorld().getMinHeight(); // this one is in block coords, max is in cube coords. Mojang logic.
}

@Redirect(method = "getBlockState(III)Lnet/minecraft/block/state/IBlockState;",
Expand All @@ -412,7 +449,7 @@ private int getBlockState_getMinHeight(int zero) {
target = "Lnet/minecraft/world/chunk/Chunk;storageArrays:[Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;"
))
private int getBlockState_getMaxHeight(ExtendedBlockStorage[] ebs) {
return isColumn ? Integer.MAX_VALUE : ebs.length;
return isColumn ? Integer.MAX_VALUE : (ebs.length - Coords.blockToCube(getWorld().getMinHeight()));
}

@Redirect(method = "getBlockState(III)Lnet/minecraft/block/state/IBlockState;",
Expand All @@ -421,7 +458,7 @@ private int getBlockState_getMaxHeight(ExtendedBlockStorage[] ebs) {
args = "array=get",
target = "Lnet/minecraft/world/chunk/Chunk;storageArrays:[Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;"
))
private ExtendedBlockStorage getBlockState_getMaxHeight(ExtendedBlockStorage[] ebs, int y) {
private ExtendedBlockStorage getBlockState_getStorage(ExtendedBlockStorage[] ebs, int y) {
return getEBS_CubicChunks(y);
}

Expand Down Expand Up @@ -592,7 +629,7 @@ private int addEntity_getMinY(int zero) {
),
require = 2)
private int addEntity_getMaxHeight(ClassInheritanceMultiMap<?>[] entityLists) {
return isColumn ? blockToCube(getWorld().getMaxHeight()) : entityLists.length;
return isColumn ? blockToCube(getWorld().getMaxHeight()) : (entityLists.length - Coords.blockToCube(getWorld().getMinHeight()));
}

@Redirect(method = "addEntity",
Expand All @@ -604,7 +641,7 @@ private int addEntity_getMaxHeight(ClassInheritanceMultiMap<?>[] entityLists) {
require = 1)
private ClassInheritanceMultiMap<?> addEntity_getEntityList(ClassInheritanceMultiMap<?>[] entityLists, int idx, Entity entity) {
if (!isColumn) {
return entityLists[idx];
return entityLists[idx - Coords.blockToCube(getWorld().getMinHeight())];
} else if (cachedCube != null && cachedCube.getY() == idx) {
cachedCube.getEntityContainer().addEntity(entity);
return null;
Expand Down Expand Up @@ -652,7 +689,7 @@ private int removeEntityAtIndex_getMinY(int zero) {
),
require = 2)
private int removeEntityAtIndex_getMaxHeight(ClassInheritanceMultiMap<?>[] entityLists) {
return isColumn ? blockToCube(getWorld().getMaxHeight()) : entityLists.length;
return isColumn ? blockToCube(getWorld().getMaxHeight()) : (entityLists.length - Coords.blockToCube(getWorld().getMinHeight()));
}

@Redirect(method = "removeEntityAtIndex",
Expand All @@ -665,7 +702,7 @@ private int removeEntityAtIndex_getMaxHeight(ClassInheritanceMultiMap<?>[] entit
private ClassInheritanceMultiMap<?> removeEntityAtIndex_getEntityList(ClassInheritanceMultiMap<?>[] entityLists, int idx, Entity entity,
int index) {
if (!isColumn) {
return entityLists[idx];
return entityLists[idx - Coords.blockToCube(getWorld().getMinHeight())];
} else if (cachedCube != null && cachedCube.getY() == idx) {
cachedCube.getEntityContainer().remove(entity);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,25 @@
*/
package io.github.opencubicchunks.cubicchunks.core.asm.mixin.noncritical.client;

import io.github.opencubicchunks.cubicchunks.api.util.Coords;
import io.github.opencubicchunks.cubicchunks.api.world.ICubicWorld;
import io.github.opencubicchunks.cubicchunks.core.CubicChunksConfig;
import io.github.opencubicchunks.cubicchunks.core.asm.CubicChunksMixinConfig;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.ViewFrustum;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Final;
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.Constant;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import javax.annotation.ParametersAreNonnullByDefault;
Expand All @@ -61,10 +66,32 @@ private void onSetCountChunks(int renderDistance, CallbackInfo cbi) {
this.renderDistance = (CubicChunksMixinConfig.BoolOptions.VERT_RENDER_DISTANCE.getValue() ?
CubicChunksConfig.verticalCubeLoadDistance : renderDistance) * 2 + 1;
} else {
this.renderDistance = 16;
ICubicWorld world = (ICubicWorld) this.world;
this.renderDistance = Coords.blockToCube(world.getMaxHeight()) - Coords.blockToCube(world.getMinHeight()) + 1;
}
}

@ModifyArg(method = "updateChunkPositions", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/chunk/RenderChunk;setPosition"
+ "(III)V"), index = 1)
private int modifyRenderChunkPosWhenUpdatingPositions(int y) {
return y + ((ICubicWorld) world).getMinHeight();
}

@ModifyVariable(method = "markBlocksForUpdate", at = @At("HEAD"), argsOnly = true, index = 2)
private int modifyMinYForUpdate(int minY) {
return minY - ((ICubicWorld) world).getMinHeight();
}

@ModifyVariable(method = "markBlocksForUpdate", at = @At("HEAD"), argsOnly = true, index = 5)
private int modifyMaxYForUpdate(int maxY) {
return maxY - ((ICubicWorld) world).getMinHeight();
}

@Redirect(method = "getRenderChunk", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos;getY()I"))
private int modifyMaxYForUpdate(BlockPos instance) {
return instance.getY() - ((ICubicWorld) world).getMinHeight();
}

@ModifyConstant(method = "setCountChunksXYZ", constant = @Constant(intValue = 16))
private int getYViewDistance(int oldDistance) {
return renderDistance;
Expand Down

0 comments on commit 7253e3c

Please sign in to comment.