diff --git a/src/main/java/de/fullrisk/citrusDev/Config.java b/src/main/java/de/fullrisk/citrusDev/Config.java index 91d9dd6..6231e1b 100644 --- a/src/main/java/de/fullrisk/citrusDev/Config.java +++ b/src/main/java/de/fullrisk/citrusDev/Config.java @@ -35,6 +35,16 @@ public class Config { public boolean hitboxEnabled = false; public int hitboxHue = 0; + public int effectsX = 1; + public int effectsY = 1; + public int effectsP = 4; + public boolean effectsEnabled = true; + public boolean effectsBgEnabled = true; + public boolean effectsTimerEnabled = true; + public boolean effectsNameEnabled = true; + + public float panelBlur = 5.0f; + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); private static final Path PATH = FabricLoader.getInstance().getConfigDir().resolve("citrus-dev.json"); diff --git a/src/main/java/de/fullrisk/citrusDev/UI/Module_Coords.java b/src/main/java/de/fullrisk/citrusDev/UI/Module_Coords.java index 47ccece..f75c88e 100644 --- a/src/main/java/de/fullrisk/citrusDev/UI/Module_Coords.java +++ b/src/main/java/de/fullrisk/citrusDev/UI/Module_Coords.java @@ -35,8 +35,6 @@ public class Module_Coords { private static final Surface GLASS_PANEL = Surface.blur(5f, 15f) .and(Surface.flat(0x40FFFFFF)); - // ---- coords toggle ---- - public static boolean isEnabled() { return toggle; } @@ -47,8 +45,6 @@ public class Module_Coords { CONFIG.save(); } - // ---- biome toggle ---- - public static boolean isBiomeEnabled() { return toggleBiome; } @@ -59,8 +55,6 @@ public class Module_Coords { CONFIG.save(); } - // ---- positioning ---- - public static void setPosition(int x, int y) { if (coordinates != null) { coordinates.positioning(Positioning.relative(x, y)); @@ -82,8 +76,6 @@ public class Module_Coords { return coordinates; } - // ---- HUD registration ---- - public static void register() { Hud.add(Identifier.fromNamespaceAndPath("citrus-dev", "coords_display"), () -> { if (coordinates == null) { @@ -104,8 +96,6 @@ public class Module_Coords { }); } - // ---- data getters ---- - public static Vec3 getPlayerPosition() { LocalPlayer player = Minecraft.getInstance().player; return player != null ? player.position() : null; @@ -145,8 +135,6 @@ public class Module_Coords { .orElse("Unknown"); } - // ---- tick ---- - public static void tick() { if (coordinates == null) return; diff --git a/src/main/java/de/fullrisk/citrusDev/UI/Module_Effects.java b/src/main/java/de/fullrisk/citrusDev/UI/Module_Effects.java new file mode 100644 index 0000000..2479ed1 --- /dev/null +++ b/src/main/java/de/fullrisk/citrusDev/UI/Module_Effects.java @@ -0,0 +1,222 @@ +package de.fullrisk.citrusDev.UI; + +import io.wispforest.owo.ui.component.LabelComponent; +import io.wispforest.owo.ui.component.UIComponents; +import io.wispforest.owo.ui.container.FlowLayout; +import io.wispforest.owo.ui.container.UIContainers; +import io.wispforest.owo.ui.core.*; +import io.wispforest.owo.ui.hud.Hud; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.world.effect.MobEffectInstance; +import de.fullrisk.citrusDev.Config; + +import java.util.ArrayList; +import java.util.List; + +public class Module_Effects { + + public static FlowLayout effectsContainer; + private static final List rows = new ArrayList<>(); + private static List lastEffects = List.of(); + + private static final Config CONFIG = Config.get(); + + static boolean toggle = CONFIG.effectsEnabled; + static boolean bgToggle = CONFIG.effectsBgEnabled; + static boolean timerToggle = CONFIG.effectsTimerEnabled; + static boolean nameToggle = CONFIG.effectsNameEnabled; + private static boolean shown = false; + + private static final Surface GLASS_PANEL = Surface.blur(5f, 15f) + .and(Surface.flat(0x40FFFFFF)); + + public static boolean isEnabled() { + return toggle; + } + + public static void setEnabled(boolean value) { + toggle = value; + CONFIG.effectsEnabled = value; + CONFIG.save(); + } + + public static boolean isBackgroundEnabled() { + return bgToggle; + } + + public static void setBackgroundEnabled(boolean value) { + bgToggle = value; + CONFIG.effectsBgEnabled = value; + CONFIG.save(); + updateSurface(); + } + + public static boolean isTimerEnabled() { + return timerToggle; + } + + public static void setTimerEnabled(boolean value) { + timerToggle = value; + CONFIG.effectsTimerEnabled = value; + CONFIG.save(); + rebuildRows(); + } + + public static boolean isNameEnabled() { + return nameToggle; + } + + public static void setNameEnabled(boolean value) { + nameToggle = value; + CONFIG.effectsNameEnabled = value; + CONFIG.save(); + rebuildRows(); + } + + private static void rebuildRows() { + if (effectsContainer == null || !shown) return; + List current = lastEffects; + if (current.isEmpty()) return; + effectsContainer.clearChildren(); + rows.clear(); + for (MobEffectInstance instance : current) { + FlowLayout row = makeEffectRow(instance); + rows.add(row); + effectsContainer.child(row); + } + } + + + + private static void updateSurface() { + if (effectsContainer == null || !shown) return; + effectsContainer.surface(bgToggle ? GLASS_PANEL : Surface.flat(0)); + } + + public static void setPosition(int x, int y) { + if (effectsContainer != null) { + effectsContainer.positioning(Positioning.relative(x, y)); + } + CONFIG.effectsX = x; + CONFIG.effectsY = y; + CONFIG.save(); + } + + public static void setEffectsPadding(int padding) { + CONFIG.effectsP = padding; + CONFIG.save(); + + if (effectsContainer == null) return; + effectsContainer.padding(Insets.of(padding)); + } + + public static FlowLayout getEffectsContainer() { + return effectsContainer; + } + + public static void register() { + Hud.add(Identifier.fromNamespaceAndPath("citrus-dev", "effects_display"), () -> { + if (effectsContainer == null) { + effectsContainer = UIContainers.verticalFlow(Sizing.content(), Sizing.content()); + effectsContainer.gap(2); + effectsContainer.verticalAlignment(VerticalAlignment.CENTER); + effectsContainer.horizontalAlignment(HorizontalAlignment.LEFT); + effectsContainer.padding(Insets.of(0)); + + effectsContainer.positioning(Positioning.relative(CONFIG.effectsX, CONFIG.effectsY)); + } + return effectsContainer; + }); + } + + private static FlowLayout makeEffectRow(MobEffectInstance instance) { + FlowLayout row = UIContainers.horizontalFlow(Sizing.content(), Sizing.content()); + row.gap(4); + row.verticalAlignment(VerticalAlignment.CENTER); + row.horizontalAlignment(HorizontalAlignment.CENTER); + + Identifier iconId = Identifier.fromNamespaceAndPath( + "minecraft", + "textures/mob_effect/" + BuiltInRegistries.MOB_EFFECT.getKey(instance.getEffect().value()).getPath() + ".png" + ); + row.child(UIComponents.texture(iconId, 0, 0, 18, 18, 18, 18)); + + if (nameToggle) { + var effectLabel = UIComponents.label(instance.getEffect().value().getDisplayName()); + row.child(effectLabel); + } + + if (timerToggle) { + var durationLabel = UIComponents.label(Component.literal(formatDuration(instance.getDuration()))); + durationLabel.color(Color.ofRgb(0xAAAAAA)); + row.child(durationLabel); + } + + return row; + } + + private static String formatDuration(int ticks) { + int totalSeconds = ticks / 20; + int minutes = totalSeconds / 60; + int seconds = totalSeconds % 60; + return String.format("%d:%02d", minutes, seconds); + } + + public static void tick() { + if (effectsContainer == null) return; + + LocalPlayer player = Minecraft.getInstance().player; + + if (toggle && !shown) { + effectsContainer.surface(bgToggle ? GLASS_PANEL : Surface.flat(0)); + effectsContainer.padding(Insets.of(CONFIG.effectsP)); + shown = true; + } else if (!toggle && shown) { + effectsContainer.clearChildren(); + rows.clear(); + lastEffects = List.of(); + effectsContainer.surface(Surface.flat(0)); + effectsContainer.padding(Insets.of(0)); + shown = false; + return; + } + + if (!toggle || player == null) return; + + List current = new ArrayList<>(player.getActiveEffects()); + + boolean changed = current.size() != lastEffects.size(); + if (!changed) { + for (int i = 0; i < current.size(); i++) { + if (!current.get(i).getEffect().equals(lastEffects.get(i).getEffect())) { + changed = true; + break; + } + } + } + + if (changed) { + effectsContainer.clearChildren(); + rows.clear(); + for (MobEffectInstance instance : current) { + FlowLayout row = makeEffectRow(instance); + rows.add(row); + effectsContainer.child(row); + } + } else { + int durationIdx = nameToggle ? 2 : 1; + for (int i = 0; i < current.size(); i++) { + if (timerToggle && rows.get(i).children().size() > durationIdx) { + var label = (LabelComponent) rows.get(i).children().get(durationIdx); + label.text(Component.literal(formatDuration(current.get(i).getDuration()))); + } + } + } + + lastEffects = current; + } +} \ No newline at end of file diff --git a/src/main/java/de/fullrisk/citrusDev/UI/Module_Hitbox.java b/src/main/java/de/fullrisk/citrusDev/UI/Module_Hitbox.java index 5730628..b6ca78b 100644 --- a/src/main/java/de/fullrisk/citrusDev/UI/Module_Hitbox.java +++ b/src/main/java/de/fullrisk/citrusDev/UI/Module_Hitbox.java @@ -4,7 +4,7 @@ import de.fullrisk.citrusDev.Config; public class Module_Hitbox { private static boolean enabled = Config.get().hitboxEnabled; - private static int hue = Config.get().hitboxHue; // 0-360 + private static int hue = Config.get().hitboxHue; public static volatile int color = hueToArgb(hue); public static boolean isEnabled() { @@ -31,6 +31,6 @@ public class Module_Hitbox { private static int hueToArgb(int hueDegrees) { float h = (hueDegrees % 360) / 360.0F; int rgb = java.awt.Color.HSBtoRGB(h, 1.0F, 1.0F); - return 0xFF000000 | (rgb & 0x00FFFFFF); // force opaque + return 0xFF000000 | (rgb & 0x00FFFFFF); } } \ No newline at end of file diff --git a/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java b/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java index 66b7e5f..ef64dca 100644 --- a/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java +++ b/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java @@ -26,16 +26,36 @@ public class MyScreen extends BaseOwoScreen { static final Identifier MC_FIVE = Identifier.fromNamespaceAndPath("citrus-dev", "minecraft_five"); - static final Surface GLASS_PANEL = Surface.blur(5f, 15f) + static Surface PANEL_SURFACE = buildPanelSurface(); + + static Surface GLASS_PANEL = Surface.blur(5f, 15f) .and(Surface.flat(0x40FFFFFF)) .and(Surface.outline(0x64de4b)); - private static final Surface DISABLED = Surface.blur(5f, 15f) + private static Surface DISABLED = Surface.blur(5f, 15f) .and(Surface.flat(0x401c1c1c)); - private static final Surface FLAT = Surface.blur(5f, 15f) + private static Surface FLAT = Surface.blur(5f, 15f) .and(Surface.flat(0x40FFFFFF)); + private static Surface buildPanelSurface() { + float blur = Config.get().panelBlur; + if (blur <= 0f) { + return Surface.flat(0x40FFFFFF) + .and(Surface.outline(0x64de4b)); + } + return Surface.blur(blur, 15f) + .and(Surface.flat(0x40FFFFFF)) + .and(Surface.outline(0x64de4b)); + } + + public static void rebuildSurfaces() { + PANEL_SURFACE = buildPanelSurface(); + if (panelRef != null) { + panelRef.surface(PANEL_SURFACE); + } + } + private static final int PANEL_WIDTH = 250; private static final int PANEL_HEIGHT = 150; private static final int INNER_WIDTH = PANEL_WIDTH - 4; @@ -56,6 +76,7 @@ public class MyScreen extends BaseOwoScreen { private FlowLayout content; private final String initialModule; + private static FlowLayout panelRef; public MyScreen() { @@ -83,6 +104,7 @@ public class MyScreen extends BaseOwoScreen { .verticalAlignment(VerticalAlignment.CENTER); FlowLayout panel = UIContainers.verticalFlow(Sizing.content(), Sizing.content()); + panelRef = panel; panel.gap(0); panel.padding(Insets.of(2)); panel.horizontalAlignment(HorizontalAlignment.CENTER); @@ -91,7 +113,7 @@ public class MyScreen extends BaseOwoScreen { panel.verticalSizing(Sizing.fixed(0)); panel.horizontalSizing().animate(300, Easing.CUBIC, Sizing.fixed(PANEL_WIDTH)).forwards(); panel.verticalSizing().animate(300, Easing.CUBIC, Sizing.fixed(PANEL_HEIGHT)).forwards(); - panel.surface(GLASS_PANEL); + panel.surface(PANEL_SURFACE); FlowLayout navbar = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(NAVBAR_HEIGHT)); buildNavbar(navbar); @@ -281,8 +303,8 @@ public class MyScreen extends BaseOwoScreen { FlowLayout fpsRow = ModuleRow.build( GLASS_PANEL, DISABLED, FLAT, - Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), - 18, 12, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/fps.png"), + 18, 18, MC_FIVE, "FPS", "Displays your FPS", @@ -302,8 +324,8 @@ public class MyScreen extends BaseOwoScreen { FlowLayout keyStrokesRow = ModuleRow.build( GLASS_PANEL, DISABLED, FLAT, - Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), - 18, 12, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/keystrokes.png"), + 24, 24, MC_FIVE, "Keystrokes", "Current Key Presses", @@ -323,8 +345,8 @@ public class MyScreen extends BaseOwoScreen { FlowLayout coordinatesRow = ModuleRow.build( GLASS_PANEL, DISABLED, FLAT, - Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), - 18, 12, + Identifier.fromNamespaceAndPath("minecraft", "textures/item/map.png"), + 18, 18, MC_FIVE, "Coordinates", "Shows your Position", @@ -348,8 +370,8 @@ public class MyScreen extends BaseOwoScreen { FlowLayout fullbrightRow = ModuleRow.build( GLASS_PANEL, DISABLED, FLAT, - Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), - 18, 12, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/fullbright.png"), + 18, 18, MC_FIVE, "Fullbright", "Max brightness", @@ -387,11 +409,33 @@ public class MyScreen extends BaseOwoScreen { "Module Disabled", "Hitbox color is now inactive" ); + FlowLayout effectsRow = ModuleRow.build( + GLASS_PANEL, DISABLED, FLAT, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/effect.png"), + 18, 18, + MC_FIVE, + "Effects", + "Shows active effects", + new ModuleRow.ToggleState() { + public boolean get() { return Module_Effects.isEnabled(); } + public void set(boolean value) { Module_Effects.setEnabled(value); } + }, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png"), + () -> { + Config.get().lastModule = "Effects"; + Config.get().save(); + openModuleSettings("Effects", effectsSettings()); + }, + "Module Enabled", "Effects display is now active", + "Module Disabled", "Effects display is now inactive" + ); + FlowLayout rowsContainer = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content()); rowsContainer.gap(4); rowsContainer.verticalAlignment(VerticalAlignment.TOP); rowsContainer.horizontalAlignment(HorizontalAlignment.CENTER); + rowsContainer.child(effectsRow); rowsContainer.child(hitboxRow); rowsContainer.child(coordinatesRow); rowsContainer.child(keyStrokesRow); @@ -423,10 +467,35 @@ public class MyScreen extends BaseOwoScreen { editButton.horizontalSizing(Sizing.fixed(CONTENT_WIDTH - 8)); rowsContainer.child(editButton); + FlowLayout blurSlider = SettingsControls.makeSlider( + FLAT, + 80, + 0.0, 15.0, + Config.get().panelBlur, + value -> (int) value + "px", + value -> { + Config.get().panelBlur = (float) (double) value; + Config.get().save(); + rebuildSurfaces(); + } + ); + + FlowLayout blurRow = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(16)); + blurRow.verticalAlignment(VerticalAlignment.CENTER); + blurRow.horizontalAlignment(HorizontalAlignment.LEFT); + blurRow.padding(Insets.of(0)); + blurRow.gap(4); + blurRow.child(UIComponents.label(Component.literal("Panel Blur") + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))) + .color(Color.ofRgb(0xFF5c5c66))); + blurRow.child(UIComponents.spacer()); + blurRow.child(blurSlider); + rowsContainer.child(blurRow); + FlowLayout hintRow = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content()); hintRow.padding(Insets.of(4, 0, 0, 0)); hintRow.child(UIComponents.label(Component.literal("Drag HUD modules to reposition. Press ESC to stop.")) - .color(Color.ofRgb(0x797b86))); + .color(Color.ofRgb(0xFF5c5c66))); rowsContainer.child(hintRow); content.child(rowsContainer); @@ -452,7 +521,7 @@ public class MyScreen extends BaseOwoScreen { header.child(UIComponents.label(Component.literal(title) .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))) - .color(Color.ofRgb(0xCCCCCC))); + .color(Color.ofRgb(0x80FFFFFF))); content.child(header); @@ -464,7 +533,7 @@ public class MyScreen extends BaseOwoScreen { for (SettingRow row : rows) { FlowLayout settingRow = makeSettingRow(row); - settingRow.verticalSizing(Sizing.fixed(16)); // pin each row to a compact fixed height + settingRow.verticalSizing(Sizing.fixed(16)); rowsContainer.child(settingRow); } @@ -482,6 +551,7 @@ public class MyScreen extends BaseOwoScreen { case "Key" -> openModuleSettings("Keystrokes", keyStrokesSettings()); case "Coords" -> openModuleSettings("Coordinates", CoordsSettings()); case "Hitbox" -> openModuleSettings("Hitbox", hitboxSettings()); + case "Effects" -> openModuleSettings("Effects", effectsSettings()); default -> buildGeneralPanel(content); } } @@ -493,8 +563,9 @@ public class MyScreen extends BaseOwoScreen { row.padding(Insets.of(0)); row.gap(4); - row.child(UIComponents.label(Component.literal(setting.label())) - .color(Color.ofRgb(0xa3a3ac))); + row.child(UIComponents.label(Component.literal(setting.label()) + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))) + .color(Color.ofRgb(0xFF5c5c66))); row.child(UIComponents.spacer()); row.child(setting.control()); @@ -523,7 +594,8 @@ public class MyScreen extends BaseOwoScreen { return List.of( new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)), - new SettingRow("Size", paddingSlider) + new SettingRow("", SettingsControls.makeSectionHeader(CONTENT_WIDTH - 8, "Display Options")), + new SettingRow("Padding", paddingSlider) ); } @@ -561,7 +633,6 @@ public class MyScreen extends BaseOwoScreen { new SettingsControls.ButtonState("L-BOTTOM", () -> Module_Coords.setPosition(1, 99)) ); - int currentIndex = positionIndex(Config.get().fpsX, Config.get().fpsY); FlowLayout biomeCheckbox = SettingsControls.makeCheckbox( @@ -571,11 +642,20 @@ public class MyScreen extends BaseOwoScreen { Module_Coords::setBiomeEnabled ); - return List.of( - new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)), - new SettingRow("Show Biome", biomeCheckbox) + FlowLayout sizeSlider = SettingsControls.makeSlider( + FLAT, + 80, + 0.0, 15.0, + Config.get().coordsP, + value -> (int) value + "px", + value -> Module_Coords.setCoordsPadding((int) value) ); + return List.of( + new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)), + new SettingRow("Show Biome", biomeCheckbox), + new SettingRow("Padding", sizeSlider) + ); } private List hitboxSettings() { @@ -586,7 +666,7 @@ public class MyScreen extends BaseOwoScreen { Module_Hitbox.isEnabled(), value -> { Module_Hitbox.setEnabled(value); - openModuleSettings("Hitbox", hitboxSettings()); // rebuild panel so slider appears/disappears + openModuleSettings("Hitbox", hitboxSettings()); } ); @@ -608,13 +688,52 @@ public class MyScreen extends BaseOwoScreen { return rows; } + private List effectsSettings() { + List positionStates = List.of( + new SettingsControls.ButtonState("L-TOP", () -> Module_Effects.setPosition(1, 1)), + new SettingsControls.ButtonState("R-TOP", () -> Module_Effects.setPosition(99, 1)), + new SettingsControls.ButtonState("R-BOTTOM", () -> Module_Effects.setPosition(99, 99)), + new SettingsControls.ButtonState("L-BOTTOM", () -> Module_Effects.setPosition(1, 99)) + ); + + int currentIndex = positionIndex(Config.get().effectsX, Config.get().effectsY); + + FlowLayout bgCheck = SettingsControls.makeCheckbox( + FLAT, + GLASS_PANEL, + Module_Effects.isBackgroundEnabled(), + Module_Effects::setBackgroundEnabled + ); + + FlowLayout timerCheck = SettingsControls.makeCheckbox( + FLAT, + GLASS_PANEL, + Module_Effects.isTimerEnabled(), + Module_Effects::setTimerEnabled + ); + + FlowLayout nameCheck = SettingsControls.makeCheckbox( + FLAT, + GLASS_PANEL, + Module_Effects.isNameEnabled(), + Module_Effects::setNameEnabled + ); + + return List.of( + new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)), + new SettingRow("Show Background", bgCheck), + new SettingRow("Show Timer", timerCheck), + new SettingRow("Show Name", nameCheck) + ); + } + private int positionIndex(int x, int y) { boolean right = x > 50; boolean bottom = y > 50; - if (!right && !bottom) return 0; // L-TOP - if (right && !bottom) return 1; // R-TOP - if (right && bottom) return 2; // R-BOTTOM - return 3; // L-BOTTOM + if (!right && !bottom) return 0; + if (right && !bottom) return 1; + if (right && bottom) return 2; + return 3; } @Override diff --git a/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java b/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java index 29fc253..4dd2b2a 100644 --- a/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java +++ b/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java @@ -113,7 +113,7 @@ public class QuestsPanel { summaryRow.child(UIComponents.label( Component.literal("quests " + unlockedCount + "/" + quests.size()) .withStyle(style -> style.withFont(new FontDescription.Resource(MyScreen.MC_FIVE)))) - .color(Color.ofRgb(0xa3a3ac))); + .color(Color.ofRgb(0xFF5c5c66))); content.child(summaryRow); @@ -140,22 +140,12 @@ public class QuestsPanel { return handle; } - /** - * Call this once per client tick (e.g. from ClientTickEvents.END_CLIENT_TICK) - * to keep the open panel's playtime/progress/quest state live. - * Throttled to once every 20 ticks (~1x/sec) since playtime itself only - * updates that often server-side. - */ public static void tick() { if (activeHandle != null && tickCounter++ % 20 == 0) { activeHandle.refresh(); } } - /** - * Call this from the screen's onClose() so a closed panel stops being - * refreshed and can be garbage collected. - */ public static void clearActiveHandle() { activeHandle = null; } @@ -216,7 +206,7 @@ public class QuestsPanel { textStack.child(titleLabel); var descLabel = UIComponents.label(Component.literal(quest.description())) - .color(Color.ofRgb(0xa3a3ac)) + .color(Color.ofRgb(0xFF5c5c66)) .maxWidth(entryWidth - 24); textStack.child(descLabel); diff --git a/src/main/java/de/fullrisk/citrusDev/UIHelper/DraggableHud.java b/src/main/java/de/fullrisk/citrusDev/UIHelper/DraggableHud.java index 6b04b9f..66787da 100644 --- a/src/main/java/de/fullrisk/citrusDev/UIHelper/DraggableHud.java +++ b/src/main/java/de/fullrisk/citrusDev/UIHelper/DraggableHud.java @@ -2,6 +2,7 @@ package de.fullrisk.citrusDev.UIHelper; import de.fullrisk.citrusDev.Config; import de.fullrisk.citrusDev.UI.Module_Coords; +import de.fullrisk.citrusDev.UI.Module_Effects; import de.fullrisk.citrusDev.UI.Module_FPS; import de.fullrisk.citrusDev.UI.Module_KeyStrokes; import io.wispforest.owo.ui.container.FlowLayout; @@ -191,6 +192,12 @@ public class DraggableHud { () -> c.fpsX, v -> c.fpsX = v, () -> c.fpsY, v -> c.fpsY = v, Module_FPS::isEnabled + ), + new ModuleDragConfig( + Module_Effects::getEffectsContainer, 120, 50, + () -> c.effectsX, v -> c.effectsX = v, + () -> c.effectsY, v -> c.effectsY = v, + Module_Effects::isEnabled ) }; } diff --git a/src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java b/src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java index 85343a7..4f6cbf8 100644 --- a/src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java +++ b/src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java @@ -62,7 +62,7 @@ public class ModuleRow { textStack.child(titleLabel); textStack.child(UIComponents.label(Component.literal(description)) - .color(Color.ofRgb(0xa3a3ac)) + .color(Color.ofRgb(0xFF5c5c66)) .maxWidth(130)); row.child(textStack); diff --git a/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java b/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java index fbcdbf3..bfe35fe 100644 --- a/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java +++ b/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java @@ -7,6 +7,7 @@ import io.wispforest.owo.ui.core.*; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FontDescription; import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvents; @@ -18,6 +19,8 @@ import java.util.function.DoubleFunction; public class SettingsControls { + private static final Identifier MC_FIVE = Identifier.fromNamespaceAndPath("citrus-dev", "minecraft_five"); + private static final Surface GLASS_PANEL = Surface.blur(5f, 15f) .and(Surface.flat(0x40FFFFFF)) .and(Surface.outline(0x64de4b)); @@ -55,7 +58,9 @@ public class SettingsControls { button.horizontalAlignment(HorizontalAlignment.CENTER); button.padding(Insets.of(2, 2, 4, 4)); button.surface(baseSurface); - button.child(UIComponents.label(Component.literal(text)).color(Color.ofRgb(0xFFFFFF))); + button.child(UIComponents.label(Component.literal(text) + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))) + .color(Color.ofRgb(0xFFFFFF))); button.mouseEnter().subscribe(() -> button.surface( Surface.blur(5f, 15f).and(Surface.flat(0x70FFFFFF)).and(Surface.outline(0xFFFFFFFF)) @@ -81,7 +86,8 @@ public class SettingsControls { button.horizontalAlignment(HorizontalAlignment.CENTER); button.surface(baseSurface); - var label = UIComponents.label(Component.literal(states.get(initialIndex).label())) + var label = UIComponents.label(Component.literal(states.get(initialIndex).label()) + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))) .color(Color.ofRgb(0xFFFFFF)); button.child(label); @@ -93,7 +99,8 @@ public class SettingsControls { currentIndex[0] = (currentIndex[0] + 1) % states.size(); ButtonState newState = states.get(currentIndex[0]); - label.text(Component.literal(newState.label())); + label.text(Component.literal(newState.label()) + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))); newState.onSelect().run(); return true; @@ -154,7 +161,8 @@ public class SettingsControls { wrapper.padding(Insets.of(2, 2, 4, 0)); wrapper.gap(2); - var valueLabel = UIComponents.label(Component.literal(labelFormatter.apply(initial))); + var valueLabel = UIComponents.label(Component.literal(labelFormatter.apply(initial)) + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))); valueLabel.color(Color.ofRgb(0xFFFFFF)); valueLabel.horizontalSizing(Sizing.fixed(labelWidth)); wrapper.child(valueLabel); @@ -168,7 +176,8 @@ public class SettingsControls { return doubled; }); slider.onChanged().subscribe(value -> { - valueLabel.text(Component.literal(labelFormatter.apply(value))); + valueLabel.text(Component.literal(labelFormatter.apply(value)) + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))); onChange.accept(value); }); @@ -176,4 +185,26 @@ public class SettingsControls { return wrapper; } + + public static FlowLayout makeSectionHeader(int width, String text) { + FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(width), Sizing.fixed(12)); + row.verticalAlignment(VerticalAlignment.CENTER); + row.horizontalAlignment(HorizontalAlignment.LEFT); + row.gap(4); + + FlowLayout shortLine = UIContainers.horizontalFlow(Sizing.fixed(10), Sizing.fixed(1)); + shortLine.surface(Surface.flat(0x80FFFFFF)); + row.child(shortLine); + + var label = UIComponents.label(Component.literal(text.toUpperCase()) + .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE)))) + .color(Color.ofRgb(0x9a9aa5)); + row.child(label); + + FlowLayout longLine = UIContainers.horizontalFlow(Sizing.fill(100), Sizing.fixed(1)); + longLine.surface(Surface.flat(0x80FFFFFF)); + row.child(longLine); + + return row; + } } \ No newline at end of file diff --git a/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java b/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java index 0e51974..ea4bc37 100644 --- a/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java +++ b/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java @@ -30,6 +30,7 @@ public class CitrusDevClient implements ClientModInitializer { Module_FPS.register(); Module_KeyStrokes.register(); Module_Coords.register(); + Module_Effects.register(); KeyMapping.Category category = KeyMapping.Category.register( @@ -57,6 +58,7 @@ public class CitrusDevClient implements ClientModInitializer { Module_KeyStrokes.tick(); Module_Coords.tick(); DraggableHud.tick(); + Module_Effects.tick(); while (openScreenKey.consumeClick()) { if (client.player != null && client.player.isShiftKeyDown()) { diff --git a/src/main/resources/assets/citrus-dev/textures/icons/effect.png b/src/main/resources/assets/citrus-dev/textures/icons/effect.png new file mode 100644 index 0000000..12e227a Binary files /dev/null and b/src/main/resources/assets/citrus-dev/textures/icons/effect.png differ diff --git a/src/main/resources/assets/citrus-dev/textures/icons/fps.png b/src/main/resources/assets/citrus-dev/textures/icons/fps.png new file mode 100644 index 0000000..bf76f6d Binary files /dev/null and b/src/main/resources/assets/citrus-dev/textures/icons/fps.png differ diff --git a/src/main/resources/assets/citrus-dev/textures/icons/fullbright.png b/src/main/resources/assets/citrus-dev/textures/icons/fullbright.png new file mode 100644 index 0000000..71be80b Binary files /dev/null and b/src/main/resources/assets/citrus-dev/textures/icons/fullbright.png differ diff --git a/src/main/resources/assets/citrus-dev/textures/icons/keystrokes.png b/src/main/resources/assets/citrus-dev/textures/icons/keystrokes.png new file mode 100644 index 0000000..50d91f7 Binary files /dev/null and b/src/main/resources/assets/citrus-dev/textures/icons/keystrokes.png differ