Skip to content

Commit

Permalink
F3/M3 Guardian Health Display (#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
KhafraDev authored Dec 7, 2023
1 parent 1b27e97 commit 3ce9d9a
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/java/de/hysky/skyblocker/SkyblockerMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public void onInitializeClient() {
DungeonBlaze.init();
ChestValue.init();
FireFreezeStaffTimer.init();
GuardianHealth.init();
TheRift.init();
TitleContainer.init();
ScreenMaster.init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,9 @@ public static class Dungeons {
@SerialEntry
public boolean fireFreezeStaffTimer = true;

@SerialEntry
public boolean floor3GuardianHealthDisplay = true;

@SerialEntry
public LividColor lividColor = new LividColor();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,14 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig
newValue -> config.locations.dungeons.fireFreezeStaffTimer = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.floor3GuardianHealthDisplay"))
.description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.floor3GuardianHealthDisplay.@Tooltip")))
.binding(defaults.locations.dungeons.floor3GuardianHealthDisplay,
() -> config.locations.dungeons.floor3GuardianHealthDisplay,
newValue -> config.locations.dungeons.floor3GuardianHealthDisplay = newValue)
.controller(ConfigUtils::createBooleanController)
.build())

//Livid Color
.group(OptionGroup.createBuilder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package de.hysky.skyblocker.skyblock.dungeon;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.render.RenderHelper;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.mob.GuardianEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.Box;

public class GuardianHealth {
private static final Box bossRoom = new Box(34, 65, -32, -32, 100, 36);
private static final Pattern guardianRegex = Pattern.compile("^(.*?) Guardian (.*?)([A-Za-z])❤$");
private static final Pattern professorRegex = Pattern.compile("^﴾ The Professor (.*?)([A-za-z])❤ ﴿$");
private static boolean inBoss;

public static void init() {
ClientReceiveMessageEvents.GAME.register(GuardianHealth::onChatMessage);
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> GuardianHealth.reset());
WorldRenderEvents.AFTER_ENTITIES.register(GuardianHealth::onWorldRender);
}

private static void onWorldRender(WorldRenderContext context) {
if (!SkyblockerConfigManager.get().locations.dungeons.floor3GuardianHealthDisplay) return;

MinecraftClient client = MinecraftClient.getInstance();

if (Utils.isInDungeons() && inBoss && client.player != null && client.world != null) {
List<GuardianEntity> guardians =
client.world.getEntitiesByClass(
GuardianEntity.class, bossRoom, guardianEntity -> true);

for (GuardianEntity guardian : guardians) {
List<ArmorStandEntity> armorStands =
client.world.getEntitiesByType(
EntityType.ARMOR_STAND,
guardian.getBoundingBox().expand(0, 1, 0),
GuardianHealth::isGuardianName);

for (ArmorStandEntity armorStand : armorStands) {
String display = armorStand.getDisplayName().getString();
boolean professor = display.contains("The Professor");
Matcher matcher =
professor
? professorRegex.matcher(display)
: guardianRegex.matcher(display);
matcher.matches(); // name is validated in isGuardianName

String health = matcher.group(professor ? 1 : 2);
String quantity = matcher.group(professor ? 2 : 3);

double distance = context.camera().getPos().distanceTo(guardian.getPos());

RenderHelper.renderText(
context,
Text.literal(health + quantity).formatted(Formatting.GREEN),
guardian.getPos(),
(float) (1 + (distance / 10)),
true);
}
}
}
}

private static void reset() {
inBoss = false;
}

private static void onChatMessage(Text text, boolean overlay) {
if (Utils.isInDungeons() && SkyblockerConfigManager.get().locations.dungeons.floor3GuardianHealthDisplay && !inBoss) {
String unformatted = Formatting.strip(text.getString());

inBoss = unformatted.equals("[BOSS] The Professor: I was burdened with terrible news recently...");
}
}

private static boolean isGuardianName(ArmorStandEntity entity) {
String display = entity.getDisplayName().getString();

if (display.contains("The Professor")) {
return professorRegex.matcher(display).matches();
}

return !display.equals("Armor Stand") && guardianRegex.matcher(display).matches();
}
}

2 changes: 2 additions & 0 deletions src/main/resources/assets/skyblocker/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@
"text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveStartsWith": "Solve Starts With",
"text.autoconfig.skyblocker.option.locations.dungeons.fireFreezeStaffTimer": "Fire Freeze Staff Timer (F3/M3)",
"text.autoconfig.skyblocker.option.locations.dungeons.fireFreezeStaffTimer.@Tooltip": "Display a timer when to use a Fire Freeze Staff in the F3/M3 boss fight.",
"text.autoconfig.skyblocker.option.locations.dungeons.floor3GuardianHealthDisplay": "Guardian Health Display (F3/M3)",
"text.autoconfig.skyblocker.option.locations.dungeons.floor3GuardianHealthDisplay.@Tooltip": "Displays guardian's health below them in the F3/M3 boss fight.",
"text.autoconfig.skyblocker.option.locations.dwarvenMines": "Dwarven Mines",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.enableDrillFuel": "Enable Drill Fuel",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.solveFetchur": "Solve Fetchur",
Expand Down

0 comments on commit 3ce9d9a

Please sign in to comment.