-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
449 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
...g/valkyrienskies/mod/mixin/mod_compat/immersive_portals/MixinIpNewChunkTrackingGraph.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package org.valkyrienskies.mod.mixin.mod_compat.immersive_portals; | ||
|
||
import com.llamalad7.mixinextras.sugar.Local; | ||
import net.minecraft.server.level.ServerLevel; | ||
import org.joml.primitives.AABBd; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
import org.valkyrienskies.core.api.ships.Ship; | ||
import org.valkyrienskies.mod.common.VSGameUtilsKt; | ||
import qouteall.imm_ptl.core.chunk_loading.ChunkLoader; | ||
import qouteall.imm_ptl.core.chunk_loading.ChunkLoader.ChunkPosConsumer; | ||
import qouteall.imm_ptl.core.chunk_loading.NewChunkTrackingGraph; | ||
|
||
/** | ||
* This mixin ensures that ship chunks are sent to players | ||
*/ | ||
@Mixin(NewChunkTrackingGraph.class) | ||
public class MixinIpNewChunkTrackingGraph { | ||
|
||
@Redirect( | ||
method = "updateForPlayer", | ||
at = @At(value = "INVOKE", | ||
target = "Lqouteall/imm_ptl/core/chunk_loading/ChunkLoader;foreachChunkPos(Lqouteall/imm_ptl/core/chunk_loading/ChunkLoader$ChunkPosConsumer;)V") | ||
) | ||
private static void addShipChunks(final ChunkLoader instance, final ChunkPosConsumer func, @Local final ServerLevel world) { | ||
// region original function | ||
for (int dx = -instance.radius; dx <= instance.radius; dx++) { | ||
for (int dz = -instance.radius; dz <= instance.radius; dz++) { | ||
func.consume( | ||
instance.center.dimension, | ||
instance.center.x + dx, | ||
instance.center.z + dz, | ||
Math.max(Math.abs(dx), Math.abs(dz)) | ||
); | ||
} | ||
} | ||
// endregion | ||
|
||
// region inject ships | ||
final AABBd box = new AABBd( | ||
(instance.center.x - instance.radius) << 4, | ||
world.getMinBuildHeight(), | ||
(instance.center.z - instance.radius) << 4, | ||
(instance.center.x + instance.radius) << 4, | ||
world.getMaxBuildHeight(), | ||
(instance.center.z + instance.radius) << 4 | ||
); | ||
for (final Ship ship : VSGameUtilsKt.getShipsIntersecting(world, box)) { | ||
ship.getActiveChunksSet().forEach((x, z) -> { | ||
func.consume( | ||
instance.center.dimension, | ||
x, | ||
z, | ||
1 // todo: change this? | ||
); | ||
}); | ||
} | ||
// endregion | ||
} | ||
|
||
} |
139 changes: 139 additions & 0 deletions
139
...a/org/valkyrienskies/mod/mixin/mod_compat/immersive_portals/MixinMyBuiltChunkStorage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package org.valkyrienskies.mod.mixin.mod_compat.immersive_portals; | ||
|
||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; | ||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry; | ||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; | ||
import net.minecraft.client.renderer.LevelRenderer; | ||
import net.minecraft.client.renderer.ViewArea; | ||
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher; | ||
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher.RenderChunk; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.util.Mth; | ||
import net.minecraft.world.level.ChunkPos; | ||
import net.minecraft.world.level.Level; | ||
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; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; | ||
import org.valkyrienskies.mod.common.VSGameUtilsKt; | ||
import org.valkyrienskies.mod.mixinducks.client.render.IVSViewAreaMethods; | ||
import qouteall.imm_ptl.core.render.MyBuiltChunkStorage; | ||
|
||
/** | ||
* Reimplementation of {@link org.valkyrienskies.mod.mixin.mod_compat.vanilla_renderer.MixinViewAreaVanilla} for immersive portals | ||
*/ | ||
@Mixin(MyBuiltChunkStorage.class) | ||
public class MixinMyBuiltChunkStorage extends ViewArea implements IVSViewAreaMethods { | ||
|
||
// Maps chunk position to an array of BuiltChunk, indexed by the y value. | ||
@Unique | ||
private final Long2ObjectMap<RenderChunk[]> vs$shipRenderChunks = | ||
new Long2ObjectOpenHashMap<>(); | ||
// This creates render chunks | ||
@Unique | ||
private ChunkRenderDispatcher vs$chunkBuilder; | ||
|
||
public MixinMyBuiltChunkStorage(final ChunkRenderDispatcher chunkRenderDispatcher, final Level level, final int i, | ||
final LevelRenderer levelRenderer) { | ||
super(chunkRenderDispatcher, level, i, levelRenderer); | ||
} | ||
|
||
/** | ||
* This mixin stores the [chunkBuilder] object from the constructor. It is used to create new render chunks. | ||
*/ | ||
@Inject(method = "<init>", at = @At("TAIL")) | ||
private void postInit(final ChunkRenderDispatcher chunkBuilder, final Level world, final int viewDistance, | ||
final LevelRenderer worldRenderer, final CallbackInfo callbackInfo) { | ||
|
||
this.vs$chunkBuilder = chunkBuilder; | ||
} | ||
|
||
/** | ||
* This mixin creates render chunks for ship chunks. | ||
*/ | ||
@Inject(method = "setDirty", at = @At("HEAD"), cancellable = true) | ||
private void preScheduleRebuild(final int x, final int y, final int z, final boolean important, | ||
final CallbackInfo callbackInfo) { | ||
|
||
final int yIndex = y - level.getMinSection(); | ||
|
||
if (yIndex < 0 || yIndex >= chunkGridSizeY) { | ||
return; // Weird, but just ignore it | ||
} | ||
|
||
if (VSGameUtilsKt.isChunkInShipyard(level, x, z)) { | ||
final long chunkPosAsLong = ChunkPos.asLong(x, z); | ||
final ChunkRenderDispatcher.RenderChunk[] renderChunksArray = | ||
vs$shipRenderChunks.computeIfAbsent(chunkPosAsLong, | ||
k -> new ChunkRenderDispatcher.RenderChunk[chunkGridSizeY]); | ||
|
||
if (renderChunksArray[yIndex] == null) { | ||
final ChunkRenderDispatcher.RenderChunk builtChunk = | ||
vs$chunkBuilder.new RenderChunk(0, x << 4, y << 4, z << 4); | ||
renderChunksArray[yIndex] = builtChunk; | ||
} | ||
|
||
renderChunksArray[yIndex].setDirty(important); | ||
|
||
callbackInfo.cancel(); | ||
} | ||
} | ||
|
||
/** | ||
* This mixin allows {@link ViewArea} to return the render chunks for ships. | ||
*/ | ||
@Inject(method = "getRenderChunkAt", at = @At("HEAD"), cancellable = true) | ||
private void preGetRenderedChunk(final BlockPos pos, | ||
final CallbackInfoReturnable<RenderChunk> callbackInfoReturnable) { | ||
final int chunkX = Mth.floorDiv(pos.getX(), 16); | ||
final int chunkY = Mth.floorDiv(pos.getY() - level.getMinBuildHeight(), 16); | ||
final int chunkZ = Mth.floorDiv(pos.getZ(), 16); | ||
|
||
if (chunkY < 0 || chunkY >= chunkGridSizeY) { | ||
return; // Weird, but ignore it | ||
} | ||
|
||
if (VSGameUtilsKt.isChunkInShipyard(level, chunkX, chunkZ)) { | ||
final long chunkPosAsLong = ChunkPos.asLong(chunkX, chunkZ); | ||
final ChunkRenderDispatcher.RenderChunk[] renderChunksArray = vs$shipRenderChunks.get(chunkPosAsLong); | ||
if (renderChunksArray == null) { | ||
callbackInfoReturnable.setReturnValue(null); | ||
return; | ||
} | ||
final ChunkRenderDispatcher.RenderChunk renderChunk = renderChunksArray[chunkY]; | ||
callbackInfoReturnable.setReturnValue(renderChunk); | ||
} | ||
} | ||
|
||
@Override | ||
public void unloadChunk(final int chunkX, final int chunkZ) { | ||
if (VSGameUtilsKt.isChunkInShipyard(level, chunkX, chunkZ)) { | ||
final ChunkRenderDispatcher.RenderChunk[] chunks = | ||
vs$shipRenderChunks.remove(ChunkPos.asLong(chunkX, chunkZ)); | ||
if (chunks != null) { | ||
for (final ChunkRenderDispatcher.RenderChunk chunk : chunks) { | ||
if (chunk != null) { | ||
chunk.releaseBuffers(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Clear VS ship render chunks so that we don't leak memory | ||
*/ | ||
@Inject(method = "releaseAllBuffers", at = @At("HEAD")) | ||
private void postReleaseAllBuffers(final CallbackInfo ci) { | ||
for (final Entry<RenderChunk[]> entry : vs$shipRenderChunks.long2ObjectEntrySet()) { | ||
for (final ChunkRenderDispatcher.RenderChunk renderChunk : entry.getValue()) { | ||
if (renderChunk != null) { | ||
renderChunk.releaseBuffers(); | ||
} | ||
} | ||
} | ||
vs$shipRenderChunks.clear(); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
...g/valkyrienskies/mod/mixin/mod_compat/immersive_portals/MixinVisibleSectionDiscovery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package org.valkyrienskies.mod.mixin.mod_compat.immersive_portals; | ||
|
||
import it.unimi.dsi.fastutil.objects.ObjectArrayList; | ||
import net.minecraft.client.Camera; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.client.multiplayer.ClientLevel; | ||
import net.minecraft.client.renderer.LevelRenderer.RenderChunkInfo; | ||
import net.minecraft.client.renderer.culling.Frustum; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
import org.valkyrienskies.mod.mixinducks.client.render.LevelRendererVanillaDuck; | ||
import qouteall.imm_ptl.core.render.MyBuiltChunkStorage; | ||
import qouteall.imm_ptl.core.render.VisibleSectionDiscovery; | ||
|
||
/** | ||
* Calls vs$addShipVisibleChunks, since immersive portals injects and cancels a callback preventing | ||
* MixinLevelRendererVanilla from calling it at the right time. | ||
*/ | ||
@Mixin(VisibleSectionDiscovery.class) | ||
public class MixinVisibleSectionDiscovery { | ||
|
||
@Inject( | ||
method = "discoverVisibleSections", | ||
at = @At("RETURN") | ||
) | ||
private static void onDiscoverVisibleSections(ClientLevel world, MyBuiltChunkStorage builtChunks_, Camera camera, | ||
Frustum frustum, ObjectArrayList<RenderChunkInfo> resultHolder_, CallbackInfo ci) { | ||
|
||
if (!(Minecraft.getInstance().levelRenderer instanceof final LevelRendererVanillaDuck renderer)) return; | ||
|
||
renderer.vs$addShipVisibleChunks(frustum); | ||
|
||
} | ||
} |
1 change: 1 addition & 0 deletions
1
...c/main/java/org/valkyrienskies/mod/mixin/mod_compat/immersive_portals/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
These mixins add compatibility with the Immersive Portals mod |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.