forked from iPortalTeam/ImmersivePortalsMod
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Addresses #105
- Loading branch information
Showing
11 changed files
with
253 additions
and
2 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
30 changes: 30 additions & 0 deletions
30
imm_ptl_core/src/main/java/qouteall/imm_ptl/core/compat/LucentCompat.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,30 @@ | ||
package qouteall.imm_ptl.core.compat; | ||
|
||
import com.legacy.lucent.api.plugin.ILucentPlugin; | ||
import com.legacy.lucent.api.plugin.LucentPlugin; | ||
import com.legacy.lucent.api.registry.EntityLightSourcePosRegistry; | ||
import net.minecraft.world.entity.EntityType; | ||
import net.minecraft.world.phys.Vec3; | ||
import qouteall.imm_ptl.core.platform_specific.IPModEntry; | ||
import qouteall.imm_ptl.core.render.context_management.RenderStates; | ||
|
||
@LucentPlugin | ||
public class LucentCompat implements ILucentPlugin { | ||
|
||
@Override | ||
public String ownerModID() { | ||
return IPModEntry.MODID; | ||
} | ||
|
||
@Override | ||
public int getPriority() { | ||
return 10; | ||
} | ||
|
||
@Override | ||
public void registerEntityLightSourcePositionGetter(EntityLightSourcePosRegistry registry) { | ||
registry.register(EntityType.PLAYER, player -> new Vec3(RenderStates.originalPlayerPos.x(), | ||
RenderStates.originalPlayerBoundingBox.getYsize() / 2.0 + RenderStates.originalPlayerPos.y(), | ||
RenderStates.originalPlayerPos.z())); | ||
} | ||
} |
125 changes: 125 additions & 0 deletions
125
imm_ptl_core/src/main/java/qouteall/imm_ptl/core/compat/mixin/MixinLucent.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,125 @@ | ||
package qouteall.imm_ptl.core.compat.mixin; | ||
|
||
import com.legacy.lucent.api.LucentData; | ||
import com.legacy.lucent.core.dynamic_lighting.DynamicLightingEngine; | ||
import com.legacy.lucent.core.dynamic_lighting.LightData; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.client.multiplayer.ClientLevel; | ||
import net.minecraft.client.player.LocalPlayer; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.core.Direction; | ||
import net.minecraft.core.SectionPos; | ||
import net.minecraft.world.entity.Entity; | ||
import net.minecraft.world.level.BlockAndTintGetter; | ||
import net.minecraft.world.level.ClipContext; | ||
import net.minecraft.world.level.Level; | ||
import net.minecraft.world.level.LightLayer; | ||
import net.minecraft.world.level.block.state.BlockState; | ||
import net.minecraft.world.phys.AABB; | ||
import net.minecraft.world.phys.BlockHitResult; | ||
import net.minecraft.world.phys.Vec3; | ||
import net.minecraft.world.phys.shapes.Shapes; | ||
import net.minecraft.world.phys.shapes.VoxelShape; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.injection.*; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; | ||
import qouteall.imm_ptl.core.ClientWorldLoader; | ||
import qouteall.imm_ptl.core.render.context_management.RenderStates; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
// TODO @Nick1st Optimize this, by reducing the mixins if possible, as they add some overhead. | ||
@Mixin(value = DynamicLightingEngine.class, remap = false) | ||
public abstract class MixinLucent { | ||
|
||
@Shadow | ||
private static VoxelShape getShape(BlockState state, BlockPos pos, Direction dir) { | ||
return null; | ||
} | ||
|
||
|
||
@Shadow private static Map<BlockPos, LightData> lightData; | ||
|
||
// Make sure the getShape Helper method gets the right level | ||
@Inject(method = "getShape", at = @At("HEAD"), cancellable = true) | ||
private static void patchedGetShape(BlockState state, BlockPos pos, Direction dir, CallbackInfoReturnable<VoxelShape> cir) { | ||
ClientLevel level = ClientWorldLoader.getWorldAsync(RenderStates.originalPlayerDimension); | ||
VoxelShape shape = (state.getLightBlock(level, pos) < 15 && !state.canOcclude()) | ||
|| !state.getMaterial().isSolid() ? Shapes.empty() : state.getFaceOcclusionShape(level, pos, dir); | ||
cir.setReturnValue(shape); | ||
cir.cancel(); | ||
} | ||
|
||
// Make sure the can lightPass occlusion test runs in the right level | ||
@Inject(method = "canLightPass", at = @At("HEAD"), cancellable = true) | ||
private static void patchedCanLightPass(BlockPos currentPos, BlockPos relativePos, Direction dir, CallbackInfoReturnable<Boolean> cir) { | ||
ClientLevel level = ClientWorldLoader.getWorldAsync(RenderStates.originalPlayerDimension); | ||
boolean canLightPass = !Shapes.faceShapeOccludes(getShape(level.getBlockState(currentPos), currentPos, dir), getShape(level.getBlockState(relativePos), relativePos, dir.getOpposite())); | ||
cir.setReturnValue(canLightPass); | ||
cir.cancel(); | ||
} | ||
|
||
// Make sure Lucent gets the entities from the right level | ||
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientLevel;getEntitiesOfClass(Ljava/lang/Class;Lnet/minecraft/world/phys/AABB;)Ljava/util/List;"), remap = true) | ||
private static List<Entity> getAllEntitiesFromTheRightDimension(ClientLevel instance, Class<Entity> entityClass, AABB aabb) { | ||
aabb = RenderStates.originalPlayerBoundingBox.inflate(LucentData.maxVisibleDistance); | ||
List<Entity> allEntities = ClientWorldLoader.getWorldAsync(RenderStates.originalPlayerDimension).getEntitiesOfClass(entityClass, aabb); | ||
if (!allEntities.contains(Minecraft.getInstance().player)) { | ||
allEntities.add(Minecraft.getInstance().player); | ||
} | ||
return allEntities; | ||
} | ||
|
||
//Give Lucent the correct player position | ||
@ModifyArg(method = "getEntityLightLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ClipContext;<init>(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/level/ClipContext$Block;Lnet/minecraft/world/level/ClipContext$Fluid;Lnet/minecraft/world/entity/Entity;)V"), index = 0) | ||
private static Vec3 truePlayerEyePosition(Vec3 pFrom) { | ||
return new Vec3(RenderStates.originalPlayerPos.x, RenderStates.originalPlayerPos.y + Minecraft.getInstance().player.getEyeY(), RenderStates.originalPlayerPos.z); // TODO @Nick1st Make sure I can get the EyeHeight like this | ||
} | ||
|
||
// Give Lucent the correct level to clip | ||
@Redirect(method = "getEntityLightLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;clip(Lnet/minecraft/world/level/ClipContext;)Lnet/minecraft/world/phys/BlockHitResult;"), remap = true) | ||
private static BlockHitResult clipWithRightPosition(Level instance, ClipContext clipContext) { | ||
return ClientWorldLoader.getWorldAsync(RenderStates.originalPlayerDimension).clip(clipContext); | ||
} | ||
|
||
// Calculate the distance correctly. | ||
@Redirect(method = "getEntityLightLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;distanceTo(Lnet/minecraft/world/entity/Entity;)F"), remap = true) | ||
private static float correctAlwaysVisibleDistanceCheck(LocalPlayer instance, Entity entity) { | ||
Vec3 entityPos = new Vec3(entity.getX(), entity.getY(), entity.getZ()); | ||
if (entity instanceof LocalPlayer) { | ||
entityPos = RenderStates.originalPlayerPos; | ||
} | ||
return (float) RenderStates.originalPlayerPos.distanceTo(entityPos); | ||
} | ||
|
||
// Calculate the correct Skylight value | ||
@Redirect(method = "getEntityLightLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientLevel;getBrightness(Lnet/minecraft/world/level/LightLayer;Lnet/minecraft/core/BlockPos;)I"), remap = true) | ||
private static int correctSkyLight(ClientLevel instance, LightLayer lightLayer, BlockPos blockPos) { | ||
return ClientWorldLoader.getWorldAsync(RenderStates.originalPlayerDimension).getBrightness(lightLayer, blockPos); | ||
} | ||
|
||
// Set the player level renderer dirty instead of a random one | ||
@Inject(method = "setDirty", at = @At(value = "INVOKE", target = "Lcom/legacy/lucent/core/LucentClient;setDirty(Lnet/minecraft/core/SectionPos;)V"), cancellable = true) | ||
private static void setDirtyPatched(SectionPos section, CallbackInfo ci) { | ||
ClientWorldLoader.getWorldRenderer(RenderStates.originalPlayerDimension).setSectionDirty(section.getX(), section.getY(), section.getZ()); | ||
ci.cancel(); | ||
} | ||
|
||
// Fixes the level used to query the skylight | ||
@ModifyVariable(method = "calcLight", at = @At(value = "HEAD"), argsOnly = true) | ||
private static BlockAndTintGetter getCorrectSkylightLevel(BlockAndTintGetter level) { | ||
return ClientWorldLoader.getWorldAsync(RenderStates.originalPlayerDimension); | ||
} | ||
|
||
// Fix a race condition if the Renderstate originalPlayerDimension is not yet set. | ||
@Inject(method = "blockChanged", at = @At("HEAD"), cancellable = true) | ||
private static void injectNullCheck(BlockPos pos, CallbackInfo ci) { | ||
if (RenderStates.originalPlayerDimension == null) { | ||
ci.cancel(); | ||
} | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
...c/main/java/qouteall/imm_ptl/core/compat/mixin/MixinLucentChunkRenderDispatcherHooks.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,19 @@ | ||
package qouteall.imm_ptl.core.compat.mixin; | ||
|
||
import com.legacy.lucent.core.asm_hooks.ChunkRenderDispatcherHooks; | ||
import net.minecraft.core.SectionPos; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
import qouteall.imm_ptl.core.ClientWorldLoader; | ||
import qouteall.imm_ptl.core.render.context_management.RenderStates; | ||
|
||
@Mixin(value = ChunkRenderDispatcherHooks.class, remap = false) | ||
public class MixinLucentChunkRenderDispatcherHooks { | ||
|
||
// Set the correct levelRenderer dirty | ||
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lcom/legacy/lucent/core/LucentClient;setDirty(Lnet/minecraft/core/SectionPos;)V")) | ||
private static void setDirty(SectionPos section) { | ||
ClientWorldLoader.getWorldRenderer(RenderStates.originalPlayerDimension).setSectionDirty(section.getX(), section.getY(), section.getZ()); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
imm_ptl_core/src/main/java/qouteall/imm_ptl/core/compat/mixin/MixinLucentLevelRenderer.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 qouteall.imm_ptl.core.compat.mixin; | ||
|
||
import net.minecraft.client.multiplayer.ClientLevel; | ||
import net.minecraft.client.renderer.LevelRenderer; | ||
import net.minecraft.client.renderer.chunk.RenderChunkRegion; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.world.level.BlockAndTintGetter; | ||
import net.minecraft.world.level.block.state.BlockState; | ||
import net.minecraftforge.api.distmarker.Dist; | ||
import net.minecraftforge.api.distmarker.OnlyIn; | ||
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.CallbackInfoReturnable; | ||
import qouteall.imm_ptl.core.render.context_management.RenderStates; | ||
|
||
@OnlyIn(Dist.CLIENT) | ||
@Mixin(value = LevelRenderer.class, priority = 900) | ||
public class MixinLucentLevelRenderer { | ||
|
||
// Inject before Lucent and return if the level doesn't fit. | ||
@Inject(at = @At(value = "RETURN", ordinal = 1), method = "getLightColor(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;)I", cancellable = true) | ||
private static void blockLightDimensionCheck(BlockAndTintGetter level, BlockState state, BlockPos pos, CallbackInfoReturnable<Integer> cir) | ||
{ | ||
ClientLevel clientLevel = null; | ||
if (level instanceof ClientLevel) { | ||
clientLevel = (ClientLevel) level; | ||
} else if (level instanceof RenderChunkRegion renderChunkRegion) { | ||
clientLevel = (ClientLevel) renderChunkRegion.level; | ||
} | ||
|
||
if (clientLevel == null || clientLevel.dimension() != RenderStates.originalPlayerDimension) { | ||
cir.cancel(); | ||
} | ||
} | ||
} |
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