diff --git a/src/main/java/org/saturnclient/modules/interfaces/PingInterface.java b/src/main/java/org/saturnclient/modules/interfaces/PingInterface.java new file mode 100644 index 0000000..2a93473 --- /dev/null +++ b/src/main/java/org/saturnclient/modules/interfaces/PingInterface.java @@ -0,0 +1,8 @@ +package org.saturnclient.modules.interfaces; + +public interface PingInterface { + + /** Returns current player ping in milliseconds */ + int getPing(); + +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/modules/interfaces/SpeedometerInterface.java b/src/main/java/org/saturnclient/modules/interfaces/SpeedometerInterface.java new file mode 100644 index 0000000..da896bd --- /dev/null +++ b/src/main/java/org/saturnclient/modules/interfaces/SpeedometerInterface.java @@ -0,0 +1,20 @@ +package org.saturnclient.modules.interfaces; + +public interface SpeedometerInterface { + + /** Returns the current player or vehicle velocity in blocks per tick */ + Velocity getVelocity(); + + /** Returns true if player or vehicle is on ground */ + boolean isOnGround(); + + class Velocity { + public final double x, y, z; + + public Velocity(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/modules/interfaces/StatusEffectsInterface.java b/src/main/java/org/saturnclient/modules/interfaces/StatusEffectsInterface.java new file mode 100644 index 0000000..0ff0f54 --- /dev/null +++ b/src/main/java/org/saturnclient/modules/interfaces/StatusEffectsInterface.java @@ -0,0 +1,36 @@ +package org.saturnclient.modules.interfaces; + +import java.util.List; +import org.saturnclient.common.minecraft.bindings.SaturnSprite; + +public interface StatusEffectsInterface { + + /** Returns a list of currently active effects */ + List getActiveEffects(); + + /** Returns a dummy list of effects for dummy rendering */ + List getDummyEffects(); + + /** Represents a single effect for rendering purposes */ + class Effect { + private final SaturnSprite icon; + private final int durationSeconds; + private final boolean infinite; + private final boolean showIcon; + private final String infiniteText; + + public Effect(SaturnSprite icon, int durationSeconds, boolean infinite, boolean showIcon, String infiniteText) { + this.icon = icon; + this.durationSeconds = durationSeconds; + this.infinite = infinite; + this.showIcon = showIcon; + this.infiniteText = infiniteText; + } + + public SaturnSprite getIcon() { return icon; } + public int getDurationSeconds() { return durationSeconds; } + public boolean isInfinite() { return infinite; } + public boolean shouldShowIcon() { return showIcon; } + public String getInfiniteText() { return infiniteText; } + } +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/modules/mods/Ping.java b/src/main/java/org/saturnclient/modules/mods/Ping.java new file mode 100644 index 0000000..7d84914 --- /dev/null +++ b/src/main/java/org/saturnclient/modules/mods/Ping.java @@ -0,0 +1,59 @@ +package org.saturnclient.modules.mods; + +import org.saturnclient.modules.HudMod; +import org.saturnclient.modules.ModDimensions; +import org.saturnclient.modules.Module; +import org.saturnclient.modules.ModuleDetails; +import org.saturnclient.config.manager.Property; +import org.saturnclient.modules.interfaces.PingInterface; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.resources.Fonts; + +public class Ping extends Module implements HudMod { + + private static Property enabled = Property.bool(false); + private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight()); + + private final PingInterface pingProvider; + + public Ping(PingInterface pingProvider) { + super(new ModuleDetails("Ping Display", "ping") + .description("Displays ping") + .version("v0.1.0") + .tags("Utility"), + enabled.named("Enabled"), + dimensions.prop()); + + this.pingProvider = pingProvider; + } + + @Override + public void renderHud(RenderScope scope) { + int ping = pingProvider.getPing(); + String text = ping + " ms"; + scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value); + dimensions.width = Fonts.getWidth(text, dimensions.font.value); + } + + @Override + public void renderDummy(RenderScope scope) { + String text = "10 ms"; + scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value); + dimensions.width = Fonts.getWidth(text, dimensions.font.value); + } + + @Override + public boolean isEnabled() { + return enabled.value; + } + + @Override + public void onEnabled(boolean e) { + enabled.value = e; + } + + @Override + public ModDimensions getDimensions() { + return dimensions; + } +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/modules/mods/Speedometer.java b/src/main/java/org/saturnclient/modules/mods/Speedometer.java new file mode 100644 index 0000000..b131ace --- /dev/null +++ b/src/main/java/org/saturnclient/modules/mods/Speedometer.java @@ -0,0 +1,96 @@ +package org.saturnclient.modules.mods; + +import org.saturnclient.modules.HudMod; +import org.saturnclient.modules.ModDimensions; +import org.saturnclient.modules.Module; +import org.saturnclient.modules.ModuleDetails; +import org.saturnclient.config.manager.Property; +import org.saturnclient.modules.interfaces.SpeedometerInterface; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.resources.Fonts; + +public class Speedometer extends Module implements HudMod { + + private static Property enabled = Property.bool(false); + private static Property axis = Property.select(1, "Absolute", "X axis", "Y axis"); + private static Property unitText = Property.select(0, "None", "Blocks/s", "blocks/s", "b/s"); + private static Property speedText = Property.bool(true); + private static ModDimensions dimensions = new ModDimensions(40, 18); + + private final SpeedometerInterface provider; + private double speed = 0.; + + public Speedometer(SpeedometerInterface provider) { + super(new ModuleDetails("Speedometer", "speed") + .description("Displays your current speed") + .version("v0.1.0") + .tags("Utility"), + enabled.named("Enabled"), + axis.named("Speed type"), + unitText.named("Unit text"), + speedText.named("Show speed text"), + dimensions.prop()); + + this.provider = provider; + } + + @Override + public void renderDummy(RenderScope scope) { + renderSpeed(2.71, scope); + } + + @Override + public void renderHud(RenderScope scope) { + SpeedometerInterface.Velocity velocity = provider.getVelocity(); + boolean onGround = provider.isOnGround(); + + double y = onGround ? 0.0 : velocity.y; + + switch (axis.value) { + case 0: // Absolute + speed = Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(y, 2) + Math.pow(velocity.z, 2)); + break; + case 1: // X axis + speed = Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(velocity.z, 2)); + break; + case 2: // Y axis + speed = Math.abs(y); + break; + } + + renderSpeed(speed * 20, scope); // blocks/tick to blocks/s + } + + public void renderSpeed(double speed, RenderScope scope) { + String text = String.format("%.2f ", speed); + + switch (unitText.value) { + case 1 -> text += "Blocks/s"; + case 2 -> text += "blocks/s"; + case 3 -> text += "b/s"; + } + + if (speedText.value) { + text = "Speed: " + text; + } + + scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value); + dimensions.width = Fonts.getWidth(text, dimensions.font.value); + dimensions.height = 18 * text.split("\n").length; + } + + @Override + public boolean isEnabled() { + return enabled.value; + } + + @Override + public ModDimensions getDimensions() { + return dimensions; + } + + @Override + public void onEnabled(boolean e) { + enabled.value = e; + } +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/modules/mods/StatusEffects.java b/src/main/java/org/saturnclient/modules/mods/StatusEffects.java new file mode 100644 index 0000000..cbd8efe --- /dev/null +++ b/src/main/java/org/saturnclient/modules/mods/StatusEffects.java @@ -0,0 +1,86 @@ +package org.saturnclient.modules.mods; + +import java.util.List; + +import org.saturnclient.modules.HudMod; +import org.saturnclient.modules.ModDimensions; +import org.saturnclient.modules.Module; +import org.saturnclient.modules.ModuleDetails; +import org.saturnclient.modules.interfaces.StatusEffectsInterface; +import org.saturnclient.config.manager.Property; +import org.saturnclient.ui.RenderScope; + +public class StatusEffects extends Module implements HudMod { + + public static Property enabled = Property.bool(false); + private static ModDimensions dimensions = new ModDimensions(60, 0); + + private final StatusEffectsInterface provider; + + public StatusEffects(StatusEffectsInterface provider) { + super(new ModuleDetails("Status effects", "effect") + .description("Displays status effects") + .version("v0.1.0") + .tags("Utility"), + enabled.named("Enabled"), + dimensions.prop()); + + this.provider = provider; + } + + private void renderEffects(RenderScope scope, List effects) { + int row = 0; + + for (StatusEffectsInterface.Effect effect : effects) { + if (!effect.shouldShowIcon()) continue; + + scope.drawSpriteStretched(effect.getIcon(), 0, 18 * row, 16, 16); + scope.drawText(0.5f, getDurationAsString(effect), 18, 18 * row + 3, dimensions.font.value, -1); + row++; + } + + dimensions.height = 18 * row; + } + + @Override + public void renderHud(RenderScope scope) { + renderEffects(scope, provider.getActiveEffects()); + } + + @Override + public void renderDummy(RenderScope scope) { + renderEffects(scope, provider.getDummyEffects()); + } + + private String getDurationAsString(StatusEffectsInterface.Effect effect) { + if (effect.isInfinite()) { + return effect.getInfiniteText(); + } + + int totalSeconds = effect.getDurationSeconds(); + if (totalSeconds >= 3600) { + return totalSeconds / 3600 + "h"; + } else if (totalSeconds >= 60) { + int minutes = totalSeconds / 60; + int seconds = totalSeconds % 60; + return String.format("%d:%02d", minutes, seconds); + } else { + return totalSeconds + "s"; + } + } + + @Override + public ModDimensions getDimensions() { + return dimensions; + } + + @Override + public boolean isEnabled() { + return enabled.value; + } + + @Override + public void onEnabled(boolean e) { + enabled.value = e; + } +} \ No newline at end of file