From 96d7cc8ddb1aa2b54adb79da88be82aa327a297a Mon Sep 17 00:00:00 2001 From: Aaron <51387595+AzureAaron@users.noreply.github.com> Date: Sat, 16 Nov 2024 14:37:39 -0500 Subject: [PATCH] Fix Glow (#1050) * Fix Glow * Remove cache --- .../skyblocker/mixins/WorldRendererMixin.java | 31 +++++++++++ .../skyblocker/skyblock/entity/MobGlow.java | 54 +------------------ .../assets/skyblocker/lang/en_us.json | 2 +- 3 files changed, 34 insertions(+), 53 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/mixins/WorldRendererMixin.java b/src/main/java/de/hysky/skyblocker/mixins/WorldRendererMixin.java index 6f0b9349fd..01b1a0d603 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/WorldRendererMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/WorldRendererMixin.java @@ -1,7 +1,9 @@ package de.hysky.skyblocker.mixins; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +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.ModifyVariable; @@ -17,6 +19,7 @@ import de.hysky.skyblocker.skyblock.entity.MobBoundingBoxes; import de.hysky.skyblocker.skyblock.entity.MobGlow; import de.hysky.skyblocker.skyblock.slayers.SlayerEntitiesGlow; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.DefaultFramebufferSet; import net.minecraft.client.render.WorldRenderer; import net.minecraft.entity.Entity; @@ -25,7 +28,30 @@ @Mixin(WorldRenderer.class) public class WorldRendererMixin { @Shadow + @Final + private MinecraftClient client; + @Shadow + @Final private DefaultFramebufferSet framebufferSet; + @Unique + private boolean atLeastOneMobHasCustomGlow; + + @ModifyExpressionValue(method = "getEntitiesToRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z")) + private boolean skyblocker$setupEntityOutlineFramebufferIfCustomGlow(boolean original, @Local Entity entity) { + boolean hasCustomGlow = MobGlow.shouldMobGlow(entity); + + if (hasCustomGlow) atLeastOneMobHasCustomGlow = true; + + return original || hasCustomGlow; + } + + @Inject(method = "method_62214", + slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;canDrawEntityOutlines()Z")), + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/Framebuffer;clear()V", ordinal = 0, shift = At.Shift.AFTER) + ) + private void skyblocker$copyFramebufferDepth2AdjustGlowVisibility(CallbackInfo ci) { + if (atLeastOneMobHasCustomGlow) framebufferSet.entityOutlineFramebuffer.get().copyDepthFrom(client.getFramebuffer()); + } @ModifyExpressionValue(method = "renderEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z")) private boolean skyblocker$shouldMobGlow(boolean original, @Local Entity entity, @Share("hasCustomGlow") LocalBooleanRef hasCustomGlow) { @@ -54,4 +80,9 @@ public class WorldRendererMixin { ); } } + + @Inject(method = "render", at = @At("TAIL")) + private void skyblocker$resetCustomGlowBool(CallbackInfo ci) { + atLeastOneMobHasCustomGlow = false; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java index 91ac62bd4e..131df01069 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java @@ -1,7 +1,6 @@ package de.hysky.skyblocker.skyblock.entity; import com.google.common.collect.Streams; -import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.SlayersConfig; import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; @@ -14,7 +13,6 @@ import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.SlayerUtils; import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.scheduler.Scheduler; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; import net.minecraft.entity.decoration.ArmorStandEntity; @@ -28,63 +26,23 @@ import net.minecraft.world.World; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; public class MobGlow { - /** * The Nukekubi head texture id is eb07594e2df273921a77c101d0bfdfa1115abed5b9b2029eb496ceba9bdbb4b3. */ - public static final String NUKEKUBI_HEAD_TEXTURE = "eyJ0aW1lc3RhbXAiOjE1MzQ5NjM0MzU5NjIsInByb2ZpbGVJZCI6ImQzNGFhMmI4MzFkYTRkMjY5NjU1ZTMzYzE0M2YwOTZjIiwicHJvZmlsZU5hbWUiOiJFbmRlckRyYWdvbiIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWIwNzU5NGUyZGYyNzM5MjFhNzdjMTAxZDBiZmRmYTExMTVhYmVkNWI5YjIwMjllYjQ5NmNlYmE5YmRiYjRiMyJ9fX0="; - private static final long GLOW_CACHE_DURATION = 50; - private static final long PLAYER_CAN_SEE_CACHE_DURATION = 100; - private static final ConcurrentHashMap<Entity, CacheEntry> glowCache = new ConcurrentHashMap<>(); - private static final ConcurrentHashMap<Entity, CacheEntry> canSeeCache = new ConcurrentHashMap<>(); - - @Init - public static void init() { - Scheduler.INSTANCE.scheduleCyclic(MobGlow::clearCache, 300 * 20); - } + private static final String NUKEKUBI_HEAD_TEXTURE = "eyJ0aW1lc3RhbXAiOjE1MzQ5NjM0MzU5NjIsInByb2ZpbGVJZCI6ImQzNGFhMmI4MzFkYTRkMjY5NjU1ZTMzYzE0M2YwOTZjIiwicHJvZmlsZU5hbWUiOiJFbmRlckRyYWdvbiIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWIwNzU5NGUyZGYyNzM5MjFhNzdjMTAxZDBiZmRmYTExMTVhYmVkNWI5YjIwMjllYjQ5NmNlYmE5YmRiYjRiMyJ9fX0="; public static boolean shouldMobGlow(Entity entity) { - - long currentTime = System.currentTimeMillis(); - - CacheEntry cachedGlow = glowCache.get(entity); - if (cachedGlow == null || (currentTime - cachedGlow.timestamp) > GLOW_CACHE_DURATION) { - boolean shouldGlow = computeShouldMobGlow(entity); - glowCache.put(entity, new CacheEntry(shouldGlow, currentTime)); - cachedGlow = glowCache.get(entity); - } - - return cachedGlow.value && playerCanSee(entity, currentTime); - } - - - /** - * Checks if the player can see the entity. - * Has "True sight" within a certain aura, but since name tags exist I think this is fine... - */ - private static boolean playerCanSee(Entity entity, long currentTime) { - - CacheEntry canSee = canSeeCache.get(entity); - if (canSee == null || (currentTime - canSee.timestamp) > PLAYER_CAN_SEE_CACHE_DURATION) { - boolean playerCanSee = entity.distanceTo(MinecraftClient.getInstance().player) <= 20 || MinecraftClient.getInstance().player.canSee(entity); - canSeeCache.put(entity, new CacheEntry(playerCanSee, currentTime)); - return playerCanSee; - } - - return canSee.value; + return computeShouldMobGlow(entity); } private static boolean computeShouldMobGlow(Entity entity) { - // Dungeons if (Utils.isInDungeons()) { String name = entity.getName().getString(); return switch (entity) { - // Minibosses case PlayerEntity p when (name.equals("Lost Adventurer") || name.equals("Shadow Assassin") || name.equals("Diamond Guy")) && !DungeonManager.getBoss().isFloor(4) -> SkyblockerConfigManager.get().dungeons.starredMobGlow; case PlayerEntity p when entity.getId() == LividColor.getCorrectLividId() -> LividColor.shouldGlow(name); @@ -101,7 +59,6 @@ private static boolean computeShouldMobGlow(Entity entity) { } return switch (entity) { - // Rift Blobbercyst case PlayerEntity p when Utils.isInTheRift() && p.getName().getString().equals("Blobbercyst ") -> SkyblockerConfigManager.get().otherLocations.rift.blobbercystGlow; @@ -193,11 +150,4 @@ public static int getGlowColor(Entity entity) { private static boolean isNukekubiHead(ArmorStandEntity entity) { return Streams.stream(entity.getArmorItems()).map(ItemUtils::getHeadTexture).anyMatch(headTexture -> headTexture.contains(NUKEKUBI_HEAD_TEXTURE)); } - - private record CacheEntry(boolean value, long timestamp) {} - - private static void clearCache() { - canSeeCache.clear(); - glowCache.clear(); - } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 43d44b41f2..c590d37605 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -216,7 +216,7 @@ "skyblocker.config.dungeons.starredMobBoundingBoxes.@Tooltip": "Draws the bounding boxes of starred mobs.", "skyblocker.config.dungeons.starredMobGlow": "Starred Mob Glow", - "skyblocker.config.dungeons.starredMobGlow.@Tooltip": "Applies the glowing effect to starred mobs that are visible.\n\nWARNING: This feature utilises ray casting on entities which may have an impact on performance.", + "skyblocker.config.dungeons.starredMobGlow.@Tooltip": "Applies the glowing effect to starred mobs that are visible.\n\nNote that using this will result in the teammate glow no longer being visible through walls when a starred mob is present.", "skyblocker.config.dungeons.terminals": "Terminal Solvers (F7/M7)", "skyblocker.config.dungeons.terminals.blockIncorrectClicks": "Block Incorrect Clicks", "skyblocker.config.dungeons.terminals.solveColor": "Solve Select Colored",