BCLib/src/main/java/ru/bclib/mixin/client/BackgroundRendererMixin.java
2021-07-10 16:07:44 +03:00

138 lines
5 KiB
Java

package ru.bclib.mixin.client;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.material.FogType;
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.callback.CallbackInfo;
import ru.bclib.api.BiomeAPI;
import ru.bclib.util.BackgroundInfo;
import ru.bclib.util.MHelper;
import ru.bclib.world.biomes.BCLBiome;
@Mixin(FogRenderer.class)
public class BackgroundRendererMixin {
private static final MutableBlockPos BCL_LAST_POS = new MutableBlockPos(0, -100, 0);
private static final MutableBlockPos BCL_MUT_POS = new MutableBlockPos();
private static final float[] BCL_FOG_DENSITY = new float[8];
@Shadow
private static float fogRed;
@Shadow
private static float fogGreen;
@Shadow
private static float fogBlue;
@Inject(method = "setupColor", at = @At("RETURN"))
private static void bcl_onRender(Camera camera, float tickDelta, ClientLevel world, int i, float f, CallbackInfo info) {
FogType fogType = camera.getFluidInCamera();
if (fogType != FogType.WATER && world.dimension().equals(Level.END)) {
Entity entity = camera.getEntity();
boolean skip = false;
if (entity instanceof LivingEntity) {
MobEffectInstance effect = ((LivingEntity) entity).getEffect(MobEffects.NIGHT_VISION);
skip = effect != null && effect.getDuration() > 0;
}
if (!skip) {
fogRed *= 4;
fogGreen *= 4;
fogBlue *= 4;
}
}
BackgroundInfo.fogColorRed = fogRed;
BackgroundInfo.fogColorGreen = fogGreen;
BackgroundInfo.fogColorBlue = fogBlue;
}
@Inject(method = "setupFog", at = @At("HEAD"), cancellable = true)
private static void bcl_fogDensity(Camera camera, FogRenderer.FogMode fogMode, float viewDistance, boolean thickFog, CallbackInfo info) {
Entity entity = camera.getEntity();
FogType fogType = camera.getFluidInCamera();
if (fogType != FogType.WATER) {
float fog = bcl_getFogDensity(entity.level, entity.getX(), entity.getEyeY(), entity.getZ());
BackgroundInfo.fogDensity = fog;
float start = viewDistance * 0.75F / fog;
float end = viewDistance / fog;
if (entity instanceof LivingEntity) {
LivingEntity le = (LivingEntity) entity;
MobEffectInstance effect = le.getEffect(MobEffects.BLINDNESS);
if (effect != null) {
int duration = effect.getDuration();
if (duration > 20) {
start = 0;
end *= 0.03F;
BackgroundInfo.blindness = 1;
}
else {
float delta = (float) duration / 20F;
BackgroundInfo.blindness = delta;
start = Mth.lerp(delta, start, 0);
end = Mth.lerp(delta, end, end * 0.03F);
}
}
else {
BackgroundInfo.blindness = 0;
}
}
RenderSystem.setShaderFogStart(start);
RenderSystem.setShaderFogEnd(end);
info.cancel();
}
}
private static float bcl_getFogDensityI(Level level, int x, int y, int z) {
Biome biome = level.getBiome(BCL_MUT_POS.set(x, y, z));
BCLBiome renderBiome = BiomeAPI.getRenderBiome(biome);
return renderBiome.getFogDensity();
}
private static float bcl_getFogDensity(Level level, double x, double y, double z) {
int x1 = (MHelper.floor(x) >> 3) << 3;
int y1 = (MHelper.floor(y) >> 3) << 3;
int z1 = (MHelper.floor(z) >> 3) << 3;
float dx = (float) (x - x1) / 8F;
float dy = (float) (y - y1) / 8F;
float dz = (float) (z - z1) / 8F;
if (BCL_LAST_POS.getX() != x1 || BCL_LAST_POS.getY() != y1 || BCL_LAST_POS.getZ() != z1) {
int x2 = x1 + 8;
int y2 = y1 + 8;
int z2 = z1 + 8;
BCL_LAST_POS.set(x1, y1, z1);
BCL_FOG_DENSITY[0] = bcl_getFogDensityI(level, x1, y1, z1);
BCL_FOG_DENSITY[1] = bcl_getFogDensityI(level, x2, y1, z1);
BCL_FOG_DENSITY[2] = bcl_getFogDensityI(level, x1, y2, z1);
BCL_FOG_DENSITY[3] = bcl_getFogDensityI(level, x2, y2, z1);
BCL_FOG_DENSITY[4] = bcl_getFogDensityI(level, x1, y1, z2);
BCL_FOG_DENSITY[5] = bcl_getFogDensityI(level, x2, y1, z2);
BCL_FOG_DENSITY[6] = bcl_getFogDensityI(level, x1, y2, z2);
BCL_FOG_DENSITY[7] = bcl_getFogDensityI(level, x2, y2, z2);
}
float a = Mth.lerp(dx, BCL_FOG_DENSITY[0], BCL_FOG_DENSITY[1]);
float b = Mth.lerp(dx, BCL_FOG_DENSITY[2], BCL_FOG_DENSITY[3]);
float c = Mth.lerp(dx, BCL_FOG_DENSITY[4], BCL_FOG_DENSITY[5]);
float d = Mth.lerp(dx, BCL_FOG_DENSITY[6], BCL_FOG_DENSITY[7]);
a = Mth.lerp(dy, a, b);
b = Mth.lerp(dy, c, d);
return Mth.lerp(dz, a, b);
}
}