Narrow and make damage overlay a config option (#1886)

This commit is contained in:
Eclipse-Sol authored and GitHub committed 2026-06-27 10:12:39 -07:00
1 parent eb0ecb0483
commit b27834cbd9
3 files changed
+27 -72

No files matched your search

@@ -357,8 +357,13 @@ public class AngelicaConfig {
@Config.RequiresMcRestart
public static boolean disableErrorChecks;
@Config.Comment("Fixes various issues with entity overlays, such as z-fighting, damage animations and eyes.")
@Config.Comment("Fixes various issues with entity overlays, such as z-fighting and eyes.")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean entityOverlayFixes;
@Config.Comment("Swap the vanilla damage overlay with one similar to modern. Fixes specific issues with z-fighting.")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean entityModernDamageOverlay;
}
@@ -64,7 +64,15 @@ public enum Mixins implements IMixins {
.addExcludedMod(TargetedMod.CUSTOM_PLAYER_MODELS)
.addClientMixins(
"angelica.bugfixes.MixinRendererLivingEntity_EyeDepth"
, "angelica.bugfixes.MixinRendererLivingEntity_OverlayTint"
)
),
ANGELICA_DAMAGE_OVERLAY(new MixinBuilder()
.setPhase(Phase.EARLY)
.setApplyIf(() -> AngelicaConfig.entityModernDamageOverlay)
.addExcludedMod(TargetedMod.CUSTOM_PLAYER_MODELS)
.addClientMixins(
"angelica.bugfixes.MixinRendererLivingEntity_OverlayTint"
)
),
@@ -13,7 +13,6 @@ import net.minecraft.client.renderer.entity.RendererLivingEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@@ -23,6 +22,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* Single-pass damage-overlay tint, modeled on modern Minecraft's OverlayTexture.
* The tint is applied only while the main body model renders.
*/
@Mixin(RendererLivingEntity.class)
public class MixinRendererLivingEntity_OverlayTint {
@@ -33,8 +33,6 @@ public class MixinRendererLivingEntity_OverlayTint {
@Unique private boolean angelica$ffpOverlayActive;
@Unique private boolean angelica$shaderEntityColorActive;
@Unique private boolean angelica$emissivePass;
@Inject(
method = "doRender(Lnet/minecraft/entity/EntityLivingBase;DDDFF)V",
at = @At(value = "INVOKE",
@@ -64,20 +62,13 @@ public class MixinRendererLivingEntity_OverlayTint {
@Inject(
method = "doRender(Lnet/minecraft/entity/EntityLivingBase;DDDFF)V",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/RendererLivingEntity;renderEquippedItems(Lnet/minecraft/entity/EntityLivingBase;F)V"),
target = "Lnet/minecraft/client/renderer/entity/RendererLivingEntity;renderModel(Lnet/minecraft/entity/EntityLivingBase;FFFFFF)V",
shift = At.Shift.AFTER),
require = 1, expect = 1
)
private void angelica$teardownOverlay(EntityLivingBase entity, double x, double y, double z,
float yaw, float partialTick, CallbackInfo ci) {
if (angelica$ffpOverlayActive) {
GLStateManager.setOverlayColor(0.0F, 0.0F, 0.0F, 0.0F);
angelica$ffpOverlayActive = false;
}
if (angelica$shaderEntityColorActive) {
// Don't tint held items
CapturedRenderingState.INSTANCE.setCurrentEntityColor(0.0F, 0.0F, 0.0F, 0.0F);
angelica$shaderEntityColorActive = false;
}
private void angelica$clearBodyTint(EntityLivingBase entity, double x, double y, double z,
float yaw, float partialTick, CallbackInfo ci) {
angelica$clearOverlayColor();
}
/**
@@ -100,64 +91,17 @@ public class MixinRendererLivingEntity_OverlayTint {
original.call(model, entity, p1, p2, p3, p4, p5, p6);
}
/**
* Prevent bleed by saving last state and comparing with current blend state.
*/
@WrapOperation(
method = "doRender(Lnet/minecraft/entity/EntityLivingBase;DDDFF)V",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/RendererLivingEntity;shouldRenderPass(Lnet/minecraft/entity/EntityLivingBase;IF)I"),
require = 1, expect = 1
)
private int angelica$detectEmissivePass(RendererLivingEntity self, EntityLivingBase entity, int pass,
float partialTick, Operation<Integer> original) {
GLStateManager.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
final int result = original.call(self, entity, pass, partialTick);
final int srcAfter = GLStateManager.glGetInteger(GL14.GL_BLEND_SRC_RGB);
final int dstAfter = GLStateManager.glGetInteger(GL14.GL_BLEND_DST_RGB);
angelica$emissivePass = srcAfter == GL11.GL_ONE && dstAfter == GL11.GL_ONE;
return result;
}
/**
* Skip the overlay on emissive eye pass.
*/
@WrapOperation(
method = "doRender(Lnet/minecraft/entity/EntityLivingBase;DDDFF)V",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/model/ModelBase;render(Lnet/minecraft/entity/Entity;FFFFFF)V"),
slice = @Slice(
from = @At(value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/RendererLivingEntity;shouldRenderPass(Lnet/minecraft/entity/EntityLivingBase;IF)I"),
to = @At(value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/RendererLivingEntity;renderEquippedItems(Lnet/minecraft/entity/EntityLivingBase;F)V")
),
require = 1, expect = 1
)
private void angelica$untintEmissivePass(ModelBase model, Entity entity,
float p1, float p2, float p3, float p4, float p5, float p6, Operation<Void> original) {
if (!angelica$skipReRender || !angelica$emissivePass) {
original.call(model, entity, p1, p2, p3, p4, p5, p6);
return;
}
if (angelica$ffpOverlayActive) {
GLStateManager.setOverlayColor(0.0F, 0.0F, 0.0F, 0.0F);
original.call(model, entity, p1, p2, p3, p4, p5, p6);
GLStateManager.setOverlayColor(1.0F, 0.0F, 0.0F, ANGELICA$RED_MIX);
} else if (angelica$shaderEntityColorActive) {
CapturedRenderingState.INSTANCE.setCurrentEntityColor(0.0F, 0.0F, 0.0F, 0.0F);
original.call(model, entity, p1, p2, p3, p4, p5, p6);
CapturedRenderingState.INSTANCE.setCurrentEntityColor(1.0F, 0.0F, 0.0F, ANGELICA$RED_MIX);
} else {
original.call(model, entity, p1, p2, p3, p4, p5, p6);
}
}
@Inject(
method = "doRender(Lnet/minecraft/entity/EntityLivingBase;DDDFF)V",
at = @At("RETURN")
)
private void angelica$reset(CallbackInfo ci) {
angelica$clearOverlayColor();
angelica$skipReRender = false;
}
@Unique
private void angelica$clearOverlayColor() {
if (angelica$ffpOverlayActive) {
GLStateManager.setOverlayColor(0.0F, 0.0F, 0.0F, 0.0F);
angelica$ffpOverlayActive = false;
@@ -166,8 +110,6 @@ public class MixinRendererLivingEntity_OverlayTint {
CapturedRenderingState.INSTANCE.setCurrentEntityColor(0.0F, 0.0F, 0.0F, 0.0F);
angelica$shaderEntityColorActive = false;
}
angelica$skipReRender = false;
angelica$emissivePass = false;
}
@Unique