Compare commits
124
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d3a27b5e7 | ||
|
|
b6eca22097 | ||
|
|
4de4605ee8 | ||
|
|
8018caf26b | ||
|
|
39266df45e | ||
|
|
25046b53f3 | ||
|
|
8e89a850b3 | ||
|
|
ccaa79e89b | ||
|
|
30b375aa6f | ||
|
|
6d2cad1c7a | ||
|
|
720ee3d8bd | ||
|
|
b4b348a54c | ||
|
|
a3be72c443 | ||
|
|
1c553d14bf | ||
|
|
cd967a907c | ||
|
|
ba04c45b75 | ||
|
|
ecb07ce730 | ||
|
|
6cd10240fc | ||
|
|
d162db3464 | ||
|
|
7e3b6cf7f8 | ||
|
|
6fb38e4f9b | ||
|
|
997fbbe9a9 | ||
|
|
01a8ea15a0 | ||
|
|
08cee2172c | ||
|
|
2c64eed329 | ||
|
|
66d7d7eab9 | ||
|
|
21b1dcc997 | ||
|
|
c2470378e1 | ||
|
|
f57e773a44 | ||
|
|
6c0575a03f | ||
|
|
9f93ea923e | ||
|
|
ecf5987434 | ||
|
|
89a5b2437e | ||
|
|
c8d28133a0 | ||
|
|
0980e3a5d4 | ||
|
|
420ba82b44 | ||
|
|
2f3c125bba | ||
|
|
9e64b2332e | ||
|
|
089cf4778c | ||
|
|
b9984c35a2 | ||
|
|
b035381ba7 | ||
|
|
87b326ce9f | ||
|
|
786f9cf6f7 | ||
|
|
464d0b502b | ||
|
|
e38f4480a3 | ||
|
|
d178f1504b | ||
|
|
5b77ea7363 | ||
|
|
78097b1d8f | ||
|
|
51040900cf | ||
|
|
f06e2a0aaa | ||
|
|
70fcd64f25 | ||
|
|
b2c7e9f03e | ||
|
|
08155bd49a | ||
|
|
67a5b219f5 | ||
|
|
6c608409e0 | ||
|
|
4c72f8e39f | ||
|
|
3d9d01a28f | ||
|
|
7e39532d1d | ||
|
|
76c20d8733 | ||
|
|
a1c68609d9 | ||
|
|
d49afbb981 | ||
|
|
fd0bf75750 | ||
|
|
edbfd0306a | ||
|
|
324ffe0c8b | ||
|
|
21daf473b1 | ||
|
|
d1030bb235 | ||
|
|
05fcd3032b | ||
|
|
47cafad92b | ||
|
|
744698fd71 | ||
|
|
86b638afca | ||
|
|
a016fd72c6 | ||
|
|
8e8737afcd | ||
|
|
6eb3fc8092 | ||
|
|
f9baa0fe5f | ||
|
|
a6e762b0d8 | ||
|
|
d72b152a26 | ||
|
|
2a202c4160 | ||
|
|
930d002b81 | ||
|
|
35440180ea | ||
|
|
7fd0565f7f | ||
|
|
1421d94647 | ||
|
|
fbb1460872 | ||
|
|
e7ca5c0297 | ||
|
|
3a54739410 | ||
|
|
1c80803994 | ||
|
|
191e9eba4c | ||
|
|
3d654685d0 | ||
|
|
d9bd2c60c9 | ||
|
|
984132991d | ||
|
|
7d649efa22 | ||
|
|
1ffadc9b45 | ||
|
|
9a7b93ccbe | ||
|
|
d37d4e49f9 | ||
|
|
b491f246c8 | ||
|
|
cfe518380a | ||
|
|
fe2521bee2 | ||
|
|
ae4d9786b2 | ||
|
|
0f4af22346 | ||
|
|
5a8ae263e9 | ||
|
|
2458906e3b | ||
|
|
42611d4aed | ||
|
|
e5cc68ecad | ||
|
|
b2ba693f92 | ||
|
|
cf9fd50e4b | ||
|
|
f1f17d807f | ||
|
|
22ad088ca4 | ||
|
|
52e8e572be | ||
|
|
a9ec3311c5 | ||
|
|
be1cca9c9a | ||
|
|
84f76ac577 | ||
|
|
76b882599b | ||
|
|
5b6810a32f | ||
|
|
f0e554d8bc | ||
|
|
bb9cc623c7 | ||
|
|
bf4e16d940 | ||
|
|
9849a38fe9 | ||
|
|
d16b66945f | ||
|
|
c0b088bb8a | ||
|
|
5cce4eabaf | ||
|
|
1254cd4b89 | ||
|
|
ff02427aa3 | ||
|
|
79d5419fcc | ||
|
|
ece5a16d34 | ||
|
|
32c1391336 |
@@ -8,10 +8,12 @@
|
|||||||
<b>Saturn Client is a free and open source Minecraft client</b>
|
<b>Saturn Client is a free and open source Minecraft client</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
# Credits
|
# Credits
|
||||||
|
|
||||||
- Cloak rendering: `IIpho3nix` & `Dhyan Blum`
|
- Cloak rendering: `IIpho3nix` & `Dhyan Blum`
|
||||||
- Who Am I: `FokshaWasTaken`
|
- Who Am I: `FokshaWasTaken`
|
||||||
- Panton font (ui): `Ivan Petrov` & `Fontfabric`
|
- Panorama: https://www.planetminecraft.com/texture-pack/minecraft-cavesand-cliffs-part-ii-main-menu-panorama/
|
||||||
|
|
||||||
If any of the code or assets are in your name and you want to remove them, please submit an issue, we are still in alpha to have any artists so we would also appreciate if you could help us make some cosmetics
|
If any of the code or assets are in your name and you want to remove them, please submit an issue, we are still in alpha to have any artists so we would also appreciate if you could help us make some cosmetics
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ dependencies {
|
|||||||
|
|
||||||
modApi "dev.felnull:special-model-loader:1.4.0+pre.1"
|
modApi "dev.felnull:special-model-loader:1.4.0+pre.1"
|
||||||
include "dev.felnull:special-model-loader:1.4.0+pre.1"
|
include "dev.felnull:special-model-loader:1.4.0+pre.1"
|
||||||
|
|
||||||
|
include modImplementation("dev.kosmx.player-anim:player-animation-lib-fabric:${project.player_anim}")
|
||||||
|
//You might want bendy-lib. playerAnimator will wrap it.
|
||||||
|
// include modRuntimeOnly("io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendylib_version}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +32,11 @@ repositories {
|
|||||||
name = "FelNull Maven"
|
name = "FelNull Maven"
|
||||||
url = "https://maven.felnull.dev"
|
url = "https://maven.felnull.dev"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maven {
|
||||||
|
name "KosmX's maven"
|
||||||
|
url 'https://maven.kosmx.dev/'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|||||||
+4
-8
@@ -1,17 +1,13 @@
|
|||||||
# Done to increase the memory available to gradle.
|
# Done to increase the memory available to gradle.
|
||||||
org.gradle.jvmargs=-Xmx1G
|
org.gradle.jvmargs=-Xmx1G
|
||||||
|
|
||||||
# Fabric Properties
|
|
||||||
# check these on https://modmuss50.me/fabric.html
|
|
||||||
minecraft_version=1.21.4
|
minecraft_version=1.21.4
|
||||||
yarn_mappings=1.21.4+build.7
|
yarn_mappings=1.21.4+build.7
|
||||||
loader_version=0.16.10
|
loader_version=0.16.10
|
||||||
|
fabric_version=0.114.0+1.21.4
|
||||||
|
|
||||||
# Mod Properties
|
mod_version = 0.0.4-beta2
|
||||||
mod_version = 0.0.1-alpha1
|
maven_group = org.saturnclient
|
||||||
maven_group = me.iipho3nix
|
|
||||||
archives_base_name = saturnclient
|
archives_base_name = saturnclient
|
||||||
|
|
||||||
# Dependencies
|
player_anim = 2.0.3+1.21.4
|
||||||
# check this on https://modmuss50.me/fabric.html
|
|
||||||
fabric_version=0.114.0+1.21.4
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package org.saturnclient.modules;
|
package org.saturnclient.modules;
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
public interface HudMod {
|
public interface HudMod {
|
||||||
public ModDimensions getDimensions();
|
public ModDimensions getDimensions();
|
||||||
|
|
||||||
public void renderDummy(DrawContext context);
|
public void renderDummy(RenderScope scope);
|
||||||
|
|
||||||
public void render(DrawContext context);
|
public void renderHud(RenderScope scope);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,54 @@
|
|||||||
package org.saturnclient.modules;
|
package org.saturnclient.modules;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.NamedProperty;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
|
||||||
public class ModDimensions {
|
public class ModDimensions {
|
||||||
public Property<Integer> x = new Property<>(0);
|
public Property<Integer> x = Property.integer(0);
|
||||||
public Property<Integer> y = new Property<>(0);
|
public Property<Integer> y = Property.integer(0);
|
||||||
public Property<Float> scale = new Property<>(1.0f);
|
public Property<Float> scale = Property.floatProp(1.0f);
|
||||||
|
public Property<Integer> bgColor = Property.color(0x00000000);
|
||||||
|
public Property<Integer> fgColor = Property.color(0xFFffffff);
|
||||||
|
public Property<Integer> radius = Property.integer(0);
|
||||||
|
public Property<Integer> font = Property.font(0);
|
||||||
|
public boolean renderBackground = true;
|
||||||
|
|
||||||
public int width = 0;
|
public int width = 0;
|
||||||
public int height = 0;
|
public int height = 0;
|
||||||
|
|
||||||
private final ConfigManager dimensionsConfig;
|
public NamedProperty<Map<String, Property<?>>> prop() {
|
||||||
|
return Property.namespace(Map.of(
|
||||||
public ModDimensions(ConfigManager configManager) {
|
"X", x,
|
||||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
"Y", y,
|
||||||
dimensionsConfig.property("x", this.x);
|
"Scale", scale,
|
||||||
dimensionsConfig.property("y", this.y);
|
"Background Color", bgColor,
|
||||||
dimensionsConfig.property("scale", this.scale);
|
"Foreground Color", fgColor,
|
||||||
|
"Corner Radius", radius,
|
||||||
|
"Font", font
|
||||||
|
)).named("In-Game Display");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModDimensions(ConfigManager configManager, int x, int y) {
|
public ModDimensions() {}
|
||||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
|
||||||
this.x.value = x;
|
public ModDimensions(int width, int height) {
|
||||||
this.y.value = y;
|
this.width = width;
|
||||||
dimensionsConfig.property("x", this.x);
|
this.height = height;
|
||||||
dimensionsConfig.property("y", this.y);
|
|
||||||
dimensionsConfig.property("scale", this.scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModDimensions(ConfigManager configManager, int x, int y, int width, int height) {
|
public ModDimensions(int x, int y, int width, int height) {
|
||||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
|
||||||
this.x.value = x;
|
this.x.value = x;
|
||||||
this.y.value = y;
|
this.y.value = y;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
dimensionsConfig.property("x", this.x);
|
|
||||||
dimensionsConfig.property("y", this.y);
|
|
||||||
dimensionsConfig.property("scale", this.scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModDimensions(ConfigManager configManager, int x, int y, float scale) {
|
public ModDimensions(int x, int y, int width, int height, float scale) {
|
||||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
|
||||||
this.x.value = x;
|
|
||||||
this.y.value = y;
|
|
||||||
this.scale.value = scale;
|
|
||||||
dimensionsConfig.property("x", this.x);
|
|
||||||
dimensionsConfig.property("y", this.y);
|
|
||||||
dimensionsConfig.property("scale", this.scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModDimensions(ConfigManager configManager, int x, int y, int width, int height, float scale) {
|
|
||||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
|
||||||
this.x.value = x;
|
this.x.value = x;
|
||||||
this.y.value = y;
|
this.y.value = y;
|
||||||
this.scale.value = scale;
|
this.scale.value = scale;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
dimensionsConfig.property("x", this.x);
|
|
||||||
dimensionsConfig.property("y", this.y);
|
|
||||||
dimensionsConfig.property("scale", this.scale);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
package org.saturnclient.modules;
|
package org.saturnclient.modules;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
|
||||||
import net.minecraft.client.font.TextRenderer;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.mods.*;
|
import org.saturnclient.modules.mods.*;
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
|
||||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
|
||||||
import org.saturnclient.ui2.RenderScope;
|
|
||||||
|
|
||||||
public class ModManager {
|
public class ModManager {
|
||||||
public static Module[] MODS = {
|
public static Module[] MODS = {
|
||||||
new Crosshair()
|
new Crosshair(),
|
||||||
|
new AutoSprint(),
|
||||||
|
new ArmorDisplay(),
|
||||||
|
new Fps(),
|
||||||
|
new PotionDisplay(),
|
||||||
|
new Coordinates(),
|
||||||
|
new Freelook(),
|
||||||
|
new Keystrokes()
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
@@ -24,34 +24,5 @@ public class ModManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
HudRenderCallback.EVENT.register((context, _o) -> {
|
|
||||||
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
|
||||||
|
|
||||||
if (textRenderer != null &&
|
|
||||||
!(SaturnClient.client.currentScreen instanceof HudEditor)) {
|
|
||||||
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
|
||||||
((DrawContextAccessor) context).getVertexConsumers());
|
|
||||||
|
|
||||||
for (Module m : MODS) {
|
|
||||||
if (m instanceof HudMod && m.isEnabled()) {
|
|
||||||
ModDimensions dim = ((HudMod) m).getDimensions();
|
|
||||||
|
|
||||||
MatrixStack matrices = context.getMatrices();
|
|
||||||
matrices.push();
|
|
||||||
|
|
||||||
matrices.translate(dim.x.value, (float) dim.y.value, 0);
|
|
||||||
|
|
||||||
matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
|
||||||
|
|
||||||
((HudMod) m).render(context);
|
|
||||||
|
|
||||||
matrices.pop();
|
|
||||||
} else {
|
|
||||||
m.render(renderScope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,34 +2,23 @@ package org.saturnclient.modules;
|
|||||||
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
import org.saturnclient.saturnclient.config.NamedProperty;
|
import org.saturnclient.saturnclient.config.NamedProperty;
|
||||||
import org.saturnclient.ui.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public abstract class Module {
|
public abstract class Module {
|
||||||
private final String name;
|
private final ModuleDetails details;
|
||||||
private final String namespace;
|
|
||||||
private final ConfigManager configManager;
|
private final ConfigManager configManager;
|
||||||
|
|
||||||
public Module(String name, String namespace, NamedProperty<?>... props) {
|
public Module(ModuleDetails details, NamedProperty<?>... props) {
|
||||||
this.name = name;
|
this.details = details;
|
||||||
this.namespace = namespace;
|
configManager = new ConfigManager(details.name);
|
||||||
|
|
||||||
configManager = new ConfigManager(name);
|
|
||||||
|
|
||||||
for (NamedProperty<?> prop : props) {
|
for (NamedProperty<?> prop : props) {
|
||||||
configManager.property(prop.name, prop.prop);
|
configManager.property(prop.name, prop.prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Module(ConfigManager config, String name, String namespace) {
|
|
||||||
this.name = name;
|
|
||||||
this.namespace = namespace;
|
|
||||||
|
|
||||||
configManager = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(RenderScope scope) {}
|
public void render(RenderScope scope) {}
|
||||||
public void tick() {}
|
public void tick() {}
|
||||||
|
|
||||||
@@ -38,14 +27,26 @@ public abstract class Module {
|
|||||||
public abstract void setEnabled(boolean e);
|
public abstract void setEnabled(boolean e);
|
||||||
|
|
||||||
public final String getName() {
|
public final String getName() {
|
||||||
return name;
|
return details.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Identifier getIconTexture() {
|
public Identifier getIconTexture() {
|
||||||
return Textures.getModIcon(namespace);
|
return Textures.getModIcon(details.namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigManager getConfig() {
|
public ConfigManager getConfig() {
|
||||||
return configManager;
|
return configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return details.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getTags() {
|
||||||
|
return details.tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return details.version;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package org.saturnclient.modules;
|
||||||
|
|
||||||
|
public class ModuleDetails {
|
||||||
|
public String name;
|
||||||
|
public String namespace;
|
||||||
|
public String description;
|
||||||
|
public String version;
|
||||||
|
public String[] tags = {};
|
||||||
|
|
||||||
|
public ModuleDetails(String name, String namespace) {
|
||||||
|
this.name = name;
|
||||||
|
this.namespace = namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleDetails name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleDetails namespace(String namespace) {
|
||||||
|
this.namespace = namespace;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleDetails description(String description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleDetails version(String version) {
|
||||||
|
this.version = version;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleDetails tags(String... tags) {
|
||||||
|
this.tags = tags;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Credits
|
||||||
|
### Freelook
|
||||||
|
- https://github.com/Celibistrial/freelook
|
||||||
|
- https://modrinth.com/mod/freelook
|
||||||
|
|
||||||
|
**The other mods are coded by us, if you have a concern or we missed something feel free to submit a issue with the credits tag**
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
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.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
|
||||||
|
public class ArmorDisplay extends Module implements HudMod {
|
||||||
|
private static Property<Boolean> enabled = Property.bool(false);
|
||||||
|
private static ModDimensions dimensions = new ModDimensions(40, 60);
|
||||||
|
|
||||||
|
public ArmorDisplay() {
|
||||||
|
super(new ModuleDetails("Armor Display", "armor")
|
||||||
|
.description("Displays armor durability")
|
||||||
|
.version("v0.1.0")
|
||||||
|
.tags("Utility"),
|
||||||
|
enabled.named("Enabled"),
|
||||||
|
dimensions.prop());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderArmor(RenderScope scope, ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots) {
|
||||||
|
int row = 0;
|
||||||
|
|
||||||
|
if (!helmet.isEmpty()) {
|
||||||
|
scope.drawItem(helmet, 0, 0);
|
||||||
|
renderHealth(scope, row, helmet.getMaxDamage(), helmet.getDamage());
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chestplate.isEmpty()) {
|
||||||
|
scope.drawItem(chestplate, 0, 15 * row);
|
||||||
|
renderHealth(scope, row, chestplate.getMaxDamage(), chestplate.getDamage());
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
if (!leggings.isEmpty()) {
|
||||||
|
scope.drawItem(leggings, 0, 15 * row);
|
||||||
|
renderHealth(scope, row, leggings.getMaxDamage(), leggings.getDamage());
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boots.isEmpty()) {
|
||||||
|
scope.drawItem(boots, 0, 15 * row);
|
||||||
|
renderHealth(scope, row, boots.getMaxDamage(), boots.getDamage());
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderHealth(RenderScope scope, int i, int max_damage, int damage) {
|
||||||
|
if (max_damage > 0 ) {
|
||||||
|
scope.drawText(0.5f, "" + (max_damage - damage), 17, (15 * i) + 3, dimensions.font.value, dimensions.fgColor.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderHud(RenderScope scope) {
|
||||||
|
renderArmor(scope,
|
||||||
|
SaturnClient.client.player.getEquippedStack(EquipmentSlot.HEAD),
|
||||||
|
SaturnClient.client.player.getEquippedStack(EquipmentSlot.CHEST),
|
||||||
|
SaturnClient.client.player.getEquippedStack(EquipmentSlot.LEGS),
|
||||||
|
SaturnClient.client.player.getEquippedStack(EquipmentSlot.FEET));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderDummy(RenderScope scope) {
|
||||||
|
renderArmor(scope, new ItemStack(Items.DIAMOND_HELMET), new ItemStack(Items.DIAMOND_CHESTPLATE), new ItemStack(Items.DIAMOND_LEGGINGS), new ItemStack(Items.DIAMOND_BOOTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModDimensions getDimensions() {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean e) {
|
||||||
|
enabled.value = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.saturnclient.modules.mods;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.saturnclient.modules.Module;
|
||||||
|
import org.saturnclient.modules.ModuleDetails;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
|
||||||
|
public class AutoSprint extends Module {
|
||||||
|
private static Property<Boolean> enabled = Property.bool(false);
|
||||||
|
|
||||||
|
public AutoSprint() {
|
||||||
|
super(
|
||||||
|
new ModuleDetails("Auto Sprint", "sprint")
|
||||||
|
.description("Makes the player always sprint")
|
||||||
|
.tags("Movement")
|
||||||
|
.version("v0.1.0"),
|
||||||
|
enabled.named("Enabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (SaturnClient.client.player == null || SaturnClient.client.getNetworkHandler() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (SaturnClient.client.options.forwardKey.isPressed() && !SaturnClient.client.options.backKey.isPressed() && !SaturnClient.client.player.isSneaking() &&
|
||||||
|
!SaturnClient.client.player.horizontalCollision) {
|
||||||
|
Objects.requireNonNull(SaturnClient.client.player).setSprinting(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean e) {
|
||||||
|
enabled.value = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
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.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class Coordinates extends Module implements HudMod {
|
||||||
|
private static Property<Boolean> enabled = Property.bool(false);
|
||||||
|
private static Property<Integer> displayMethod = Property.select(0, "Flat", "Flat annotated", "Newline", "Newline annotated");
|
||||||
|
private static ModDimensions dimensions = new ModDimensions(40, 18);
|
||||||
|
|
||||||
|
public Coordinates() {
|
||||||
|
super(new ModuleDetails("Coordinates", "coords")
|
||||||
|
.description("Displays your current coordinates")
|
||||||
|
.version("v0.1.0")
|
||||||
|
.tags("Utility"),
|
||||||
|
enabled.named("Enabled"),
|
||||||
|
displayMethod.named("Display Method"),
|
||||||
|
dimensions.prop()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderDummy(RenderScope scope) {
|
||||||
|
renderCoords(532, 69, 253, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderHud(RenderScope scope) {
|
||||||
|
Vec3d pos = SaturnClient.client.player.getPos();
|
||||||
|
renderCoords((int) pos.x, (int) pos.y, (int) pos.z, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderCoords(int x, int y, int z, RenderScope scope) {
|
||||||
|
String f = "%d %d %d"; // Flat
|
||||||
|
switch (displayMethod.value) {
|
||||||
|
case 1: // Flat annotated
|
||||||
|
f = "X: %d Y: %d Z: %d";
|
||||||
|
break;
|
||||||
|
case 2: // Newline
|
||||||
|
f = "%d\n%d\n%d";
|
||||||
|
break;
|
||||||
|
case 3: // Newline annotated
|
||||||
|
f = "X: %d\nY: %d\nZ: %d";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String text = String.format(f, x, y, z);
|
||||||
|
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 setEnabled(boolean e) {
|
||||||
|
enabled.value = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.saturnclient.modules.mods;
|
package org.saturnclient.modules.mods;
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
import org.saturnclient.modules.Module;
|
||||||
|
import org.saturnclient.modules.ModuleDetails;
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
@@ -9,26 +10,29 @@ import org.saturnclient.ui2.resources.Textures;
|
|||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
|
||||||
public class Crosshair extends Module {
|
public class Crosshair extends Module {
|
||||||
public static Property<Boolean> enabled = new Property<>(false);
|
public static Property<Boolean> enabled = Property.bool(false);
|
||||||
public static Property<Boolean> range_indicator = new Property<>(false);
|
|
||||||
|
|
||||||
public Crosshair() {
|
public Crosshair() {
|
||||||
super("Crosshair", "crosshair", enabled.named("Enabled"), range_indicator.named("Range Indicator"));
|
super(
|
||||||
|
new ModuleDetails("Crosshair", "crosshair")
|
||||||
|
.description("Changes the crosshair if you're aiming at a entity")
|
||||||
|
.tags("Visuals", "Utility")
|
||||||
|
.version("v0.1.0"),
|
||||||
|
enabled.named("Enabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope scope) {
|
public void render(RenderScope scope) {
|
||||||
if (enabled.value
|
if (enabled.value
|
||||||
&& range_indicator.value
|
|
||||||
&& SaturnClient.client.targetedEntity != null
|
&& SaturnClient.client.targetedEntity != null
|
||||||
&& SaturnClient.client.targetedEntity.isAlive()) {
|
&& SaturnClient.client.targetedEntity.isAlive()) {
|
||||||
int scaledWidth = 15;
|
int scaledWidth = 15;
|
||||||
int scaledHeight = 15;
|
int scaledHeight = 15;
|
||||||
|
|
||||||
scope.drawTexture(RenderLayer::getCrosshair, Textures.CROSSHAIR_RANGE,
|
scope.setRenderLayer(RenderLayer::getCrosshair);
|
||||||
|
scope.drawTexture(Textures.CROSSHAIR_RANGE,
|
||||||
(scope.getScaledWindowWidth() - scaledWidth) / 2,
|
(scope.getScaledWindowWidth() - scaledWidth) / 2,
|
||||||
(scope.getScaledWindowHeight() - scaledHeight) / 2, 0.0F, 0.0F, scaledWidth, scaledHeight,
|
(scope.getScaledWindowHeight() - scaledHeight) / 2, 0.0F, 0.0F, scaledWidth, scaledHeight);
|
||||||
scaledWidth, scaledHeight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
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.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
|
public class Fps extends Module implements HudMod {
|
||||||
|
private static Property<Boolean> enabled = Property.bool(false);
|
||||||
|
private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight());
|
||||||
|
|
||||||
|
public Fps() {
|
||||||
|
super(new ModuleDetails("FPS Display", "fps")
|
||||||
|
.description("Displays current FPS")
|
||||||
|
.version("v0.1.0")
|
||||||
|
.tags("Utility"),
|
||||||
|
enabled.named("Enabled"),
|
||||||
|
dimensions.prop());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderHud(RenderScope scope) {
|
||||||
|
String text = String.valueOf(SaturnClient.client.getCurrentFps()) + " FPS";
|
||||||
|
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 = "369 FPS";
|
||||||
|
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 setEnabled(boolean e) {
|
||||||
|
enabled.value = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModDimensions getDimensions() {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package org.saturnclient.modules.mods;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.saturnclient.modules.Module;
|
||||||
|
import org.saturnclient.modules.ModuleDetails;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
|
||||||
|
import net.minecraft.client.option.Perspective;
|
||||||
|
|
||||||
|
public class Freelook extends Module {
|
||||||
|
private static Property<Boolean> enabled = Property.bool(false);
|
||||||
|
private static Property<Boolean> toggle = Property.bool(true);
|
||||||
|
public static Property<Integer> freelookKey = Property.keybinding(GLFW.GLFW_KEY_H);
|
||||||
|
public static boolean isFreeLooking = false;
|
||||||
|
private static boolean was1stPerson = false;
|
||||||
|
|
||||||
|
public Freelook() {
|
||||||
|
super(
|
||||||
|
new ModuleDetails("Freelook", "freelook")
|
||||||
|
.description("Allows you to look around freely without moving your character")
|
||||||
|
.tags("Movement", "Camera")
|
||||||
|
.version("0.1.0"),
|
||||||
|
enabled.named("Enabled"),
|
||||||
|
toggle.named("Toggle freelook"),
|
||||||
|
freelookKey.named("Freelook Keybinding")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (toggle.value) {
|
||||||
|
if (freelookKey.wasKeyPressed()) {
|
||||||
|
if (isFreeLooking) {
|
||||||
|
stopFreelook();
|
||||||
|
} else {
|
||||||
|
startFreelook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (freelookKey.isKeyPressed()) {
|
||||||
|
if (!isFreeLooking) {
|
||||||
|
startFreelook();
|
||||||
|
}
|
||||||
|
} else if (isFreeLooking) {
|
||||||
|
stopFreelook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startFreelook() {
|
||||||
|
isFreeLooking = true;
|
||||||
|
was1stPerson = SaturnClient.client.options.getPerspective() == Perspective.FIRST_PERSON;
|
||||||
|
SaturnClient.client.options.setPerspective(Perspective.THIRD_PERSON_BACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopFreelook() {
|
||||||
|
if (was1stPerson) {
|
||||||
|
SaturnClient.client.options.setPerspective(Perspective.FIRST_PERSON);
|
||||||
|
}
|
||||||
|
isFreeLooking = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean e) {
|
||||||
|
enabled.value = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
package org.saturnclient.modules.mods;
|
||||||
|
|
||||||
|
import org.saturnclient.modules.Module;
|
||||||
|
import org.saturnclient.modules.HudMod;
|
||||||
|
import org.saturnclient.modules.ModDimensions;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.modules.ModuleDetails;
|
||||||
|
|
||||||
|
public class Keystrokes extends Module implements HudMod {
|
||||||
|
public static Property<Boolean> enabled = Property.bool(false);
|
||||||
|
public static Property<Boolean> showMouse = Property.bool(true);
|
||||||
|
public static Property<Boolean> showSpace = Property.bool(false);
|
||||||
|
public static ModDimensions dimensions = new ModDimensions(78, 46);
|
||||||
|
private boolean w = false;
|
||||||
|
private boolean a = false;
|
||||||
|
private boolean s = false;
|
||||||
|
private boolean d = false;
|
||||||
|
private boolean lmb = false;
|
||||||
|
private boolean rmb = false;
|
||||||
|
private boolean space = false;
|
||||||
|
|
||||||
|
private static Property<Integer> clickBg = Property.color(0xFFCCCCCC);
|
||||||
|
private static Property<Integer> clickFg = Property.color(0xFFFFFFFF);
|
||||||
|
|
||||||
|
public Keystrokes() {
|
||||||
|
super(new ModuleDetails("Keystrokes", "keystrokes")
|
||||||
|
.description("Displays the keystrokes for movement")
|
||||||
|
.version("v0.1.0")
|
||||||
|
.tags("Utility"),
|
||||||
|
|
||||||
|
enabled.named("Enabled"),
|
||||||
|
showMouse.named("Show mouse clicks"),
|
||||||
|
showSpace.named("Show space clicks"),
|
||||||
|
dimensions.prop(),
|
||||||
|
clickFg.named("Clicked fg"),
|
||||||
|
clickBg.named("Clicked bg"));
|
||||||
|
|
||||||
|
dimensions.renderBackground = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
w = SaturnClient.client.options.forwardKey.isPressed();
|
||||||
|
a = SaturnClient.client.options.leftKey.isPressed();
|
||||||
|
s = SaturnClient.client.options.backKey.isPressed();
|
||||||
|
d = SaturnClient.client.options.rightKey.isPressed();
|
||||||
|
lmb = SaturnClient.client.options.attackKey.isPressed();
|
||||||
|
rmb = SaturnClient.client.options.useKey.isPressed();
|
||||||
|
space = SaturnClient.client.options.jumpKey.isPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderDummy(RenderScope scope) {
|
||||||
|
dimensions.height = 54; // base height with padding considered
|
||||||
|
|
||||||
|
// WASD keys (3px padding between each key)
|
||||||
|
renderKey(scope, true, 'W', 27, 0); // Top center
|
||||||
|
renderKey(scope, false, 'A', 0, 27); // Bottom left
|
||||||
|
renderKey(scope, false, 'S', 27, 27); // Bottom center
|
||||||
|
renderKey(scope, false, 'D', 54, 27); // Bottom right
|
||||||
|
|
||||||
|
if (showMouse.value) {
|
||||||
|
renderKeyM(scope, true, "LMB", 0, 54); // Below A/S/D
|
||||||
|
renderKeyM(scope, false, "RMB", 40, 54); // With 3px between
|
||||||
|
dimensions.height += 27;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSpace.value) {
|
||||||
|
renderKeySpace(scope, false, 0, dimensions.height);
|
||||||
|
dimensions.height += 22;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderHud(RenderScope scope) {
|
||||||
|
dimensions.height = 54; // base height with padding considered
|
||||||
|
|
||||||
|
// WASD keys (3px padding between each key)
|
||||||
|
renderKey(scope, w, 'W', 27, 0); // Top center
|
||||||
|
renderKey(scope, a, 'A', 0, 27); // Bottom left
|
||||||
|
renderKey(scope, s, 'S', 27, 27); // Bottom center
|
||||||
|
renderKey(scope, d, 'D', 54, 27); // Bottom right
|
||||||
|
|
||||||
|
if (showMouse.value) {
|
||||||
|
renderKeyM(scope, lmb, "LMB", 0, 54); // Below A/S/D
|
||||||
|
renderKeyM(scope, rmb, "RMB", 40, 54); // With 3px between
|
||||||
|
dimensions.height += 27;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSpace.value) {
|
||||||
|
renderKeySpace(scope, space, 0, dimensions.height);
|
||||||
|
dimensions.height += 22;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consistent 3px padding applied below:
|
||||||
|
|
||||||
|
private void renderKeySpace(RenderScope scope, boolean isPressed, int x, int y) {
|
||||||
|
int height = 19;
|
||||||
|
scope.drawRoundedRectangle(x, y, dimensions.width, height, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||||
|
|
||||||
|
// A 30-pixel line centered vertically with 3px top padding
|
||||||
|
int lineY = y + (height - 1) / 2;
|
||||||
|
scope.drawRect(x + (dimensions.width - 30) / 2, lineY, 30, 1, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderKeyM(RenderScope scope, boolean isPressed, String c, int x, int y) {
|
||||||
|
int width = 38, height = 24;
|
||||||
|
scope.drawRoundedRectangle(x, y, width, height, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||||
|
|
||||||
|
// Apply padding: 3px top and left -> add slight offset to x/y
|
||||||
|
scope.drawText(0.6f, c, x + 9, y + 7, dimensions.font.value, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderKey(RenderScope scope, boolean isPressed, char c, int x, int y) {
|
||||||
|
int size = 24;
|
||||||
|
scope.drawRoundedRectangle(x, y, size, size, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||||
|
|
||||||
|
// Center the character with 3px top padding
|
||||||
|
scope.drawText(0.6f, String.valueOf(c), x + 9, y + 7, dimensions.font.value, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModDimensions getDimensions() {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean e) {
|
||||||
|
enabled.value = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package org.saturnclient.modules.mods;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.saturnclient.modules.HudMod;
|
||||||
|
import org.saturnclient.modules.ModDimensions;
|
||||||
|
import org.saturnclient.modules.Module;
|
||||||
|
import org.saturnclient.modules.ModuleDetails;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
|
import net.minecraft.client.resource.language.I18n;
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.client.texture.StatusEffectSpriteManager;
|
||||||
|
import net.minecraft.entity.effect.StatusEffect;
|
||||||
|
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
public class PotionDisplay extends Module implements HudMod {
|
||||||
|
public static Property<Boolean> enabled = Property.bool(false);
|
||||||
|
private static ModDimensions dimensions = new ModDimensions(60, 0);
|
||||||
|
|
||||||
|
private final StatusEffectInstance[] dummyEffects = {
|
||||||
|
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2),
|
||||||
|
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2),
|
||||||
|
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2),
|
||||||
|
};
|
||||||
|
|
||||||
|
public PotionDisplay() {
|
||||||
|
super(new ModuleDetails("Potion Display", "potion")
|
||||||
|
.description("Displays potion effects")
|
||||||
|
.version("v0.1.0")
|
||||||
|
.tags("Utility"),
|
||||||
|
|
||||||
|
enabled.named("Enabled"),
|
||||||
|
dimensions.prop());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderEffects(RenderScope scope, Iterable<StatusEffectInstance> effects) {
|
||||||
|
int row = 0;
|
||||||
|
|
||||||
|
StatusEffectSpriteManager statusEffectSpriteManager = SaturnClient.client.getStatusEffectSpriteManager();
|
||||||
|
|
||||||
|
for (StatusEffectInstance effect : effects) {
|
||||||
|
if (effect.shouldShowIcon()) {
|
||||||
|
RegistryEntry<StatusEffect> registryEntry = effect.getEffectType();
|
||||||
|
Sprite sprite = statusEffectSpriteManager.getSprite(registryEntry);
|
||||||
|
scope.drawSpriteStretched(sprite, 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, SaturnClient.client.player.getStatusEffects());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderDummy(RenderScope scope) {
|
||||||
|
renderEffects(scope, Arrays.asList(dummyEffects));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This code was from: https://github.com/magicus/statuseffecttimer/blob/master/src/main/java/se/icus/mag/statuseffecttimer/mixin/StatusEffectTimerMixin.java
|
||||||
|
private String getDurationAsString(StatusEffectInstance statusEffectInstance) {
|
||||||
|
if (statusEffectInstance.isInfinite()) {
|
||||||
|
return I18n.translate("effect.duration.infinite");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ticks = MathHelper.floor((float) statusEffectInstance.getDuration());
|
||||||
|
int totalSeconds = ticks / 20;
|
||||||
|
|
||||||
|
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 String.valueOf(totalSeconds) + "s";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModDimensions getDimensions() {
|
||||||
|
return dimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean e) {
|
||||||
|
enabled.value = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.saturnclient.modules.mods.mixins;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.render.Camera;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
|
||||||
|
import org.saturnclient.modules.mods.Freelook;
|
||||||
|
import org.saturnclient.modules.mods.utils.CameraOverriddenEntity;
|
||||||
|
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.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(Camera.class)
|
||||||
|
public abstract class CameraMixin {
|
||||||
|
@Unique
|
||||||
|
boolean firstTime = true;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected abstract void setRotation(float yaw, float pitch);
|
||||||
|
|
||||||
|
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
|
||||||
|
public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, float tickDelta, CallbackInfo ci) {
|
||||||
|
if (Freelook.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) {
|
||||||
|
CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity;
|
||||||
|
|
||||||
|
if (firstTime && MinecraftClient.getInstance().player != null) {
|
||||||
|
cameraOverriddenEntity.freelook$setCameraPitch(MinecraftClient.getInstance().player.getPitch());
|
||||||
|
cameraOverriddenEntity.freelook$setCameraYaw(MinecraftClient.getInstance().player.getYaw());
|
||||||
|
firstTime = false;
|
||||||
|
}
|
||||||
|
this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), cameraOverriddenEntity.freelook$getCameraPitch());
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!Freelook.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) {
|
||||||
|
firstTime = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package org.saturnclient.modules.mods.mixins;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
import org.saturnclient.modules.mods.Freelook;
|
||||||
|
import org.saturnclient.modules.mods.utils.CameraOverriddenEntity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
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.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class EntityMixin implements CameraOverriddenEntity {
|
||||||
|
@Unique
|
||||||
|
private float cameraPitch;
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private float cameraYaw;
|
||||||
|
|
||||||
|
@Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true)
|
||||||
|
public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) {
|
||||||
|
//noinspection ConstantValue// IntelliJ is incorrect here, this code block is reachable
|
||||||
|
if (Freelook.isFreeLooking && (Object) this instanceof ClientPlayerEntity) {
|
||||||
|
double pitchDelta = (yDelta * 0.15);
|
||||||
|
double yawDelta = (xDelta * 0.15);
|
||||||
|
|
||||||
|
this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f);
|
||||||
|
this.cameraYaw += (float) yawDelta;
|
||||||
|
|
||||||
|
ci.cancel();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Unique
|
||||||
|
public float freelook$getCameraPitch() {
|
||||||
|
return this.cameraPitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Unique
|
||||||
|
public float freelook$getCameraYaw() {
|
||||||
|
return this.cameraYaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Unique
|
||||||
|
public void freelook$setCameraPitch(float pitch) {
|
||||||
|
this.cameraPitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Unique
|
||||||
|
public void freelook$setCameraYaw(float yaw) {
|
||||||
|
this.cameraYaw = yaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.saturnclient.modules.mods.mixins;
|
||||||
|
|
||||||
|
import org.saturnclient.modules.HudMod;
|
||||||
|
import org.saturnclient.modules.ModDimensions;
|
||||||
|
import org.saturnclient.modules.ModManager;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||||
|
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import net.minecraft.client.font.TextRenderer;
|
||||||
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.gui.hud.InGameHud;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.client.render.RenderTickCounter;
|
||||||
|
|
||||||
|
@Mixin(InGameHud.class)
|
||||||
|
public class RenderMixin {
|
||||||
|
@Inject(method = "renderChat", at = @At("TAIL"))
|
||||||
|
public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
|
||||||
|
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||||
|
|
||||||
|
if (textRenderer != null &&
|
||||||
|
!(SaturnClient.client.currentScreen instanceof HudEditor)) {
|
||||||
|
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||||
|
((DrawContextAccessor) context).getVertexConsumers());
|
||||||
|
|
||||||
|
for (org.saturnclient.modules.Module m : ModManager.MODS) {
|
||||||
|
if (m instanceof HudMod && m.isEnabled()) {
|
||||||
|
ModDimensions dim = ((HudMod) m).getDimensions();
|
||||||
|
|
||||||
|
renderScope.matrices.push();
|
||||||
|
|
||||||
|
renderScope.matrices.translate(dim.x.value, (float) dim.y.value, 0);
|
||||||
|
|
||||||
|
renderScope.matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
||||||
|
|
||||||
|
if (dim.renderBackground) {
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, dim.width, dim.height, dim.radius.value,
|
||||||
|
dim.bgColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
|
((HudMod) m).renderHud(renderScope);
|
||||||
|
|
||||||
|
renderScope.matrices.pop();
|
||||||
|
} else {
|
||||||
|
m.render(renderScope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.saturnclient.modules.mods.utils;
|
||||||
|
|
||||||
|
public interface CameraOverriddenEntity {
|
||||||
|
float freelook$getCameraPitch();
|
||||||
|
float freelook$getCameraYaw();
|
||||||
|
|
||||||
|
void freelook$setCameraPitch(float pitch);
|
||||||
|
void freelook$setCameraYaw(float yaw);
|
||||||
|
}
|
||||||
@@ -4,17 +4,21 @@ import net.fabricmc.api.ModInitializer;
|
|||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
|
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.screen.TitleScreen;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
|
||||||
import org.saturnclient.modules.ModManager;
|
import org.saturnclient.modules.ModManager;
|
||||||
import org.saturnclient.saturnclient.auth.Auth;
|
import org.saturnclient.saturnclient.auth.Auth;
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
||||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||||
import org.saturnclient.saturnclient.event.KeyInputHandler;
|
import org.saturnclient.saturnclient.event.KeyInputHandler;
|
||||||
import org.saturnclient.saturnclient.menus.SaturnMenu;
|
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||||
import org.saturnclient.saturnclient.menus.SaturnTitleScreen;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
|
import org.saturnclient.ui2.elements.ImageTexture;
|
||||||
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
|
import org.saturnclient.ui2.screens.TitleMenu;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -33,24 +37,44 @@ public class SaturnClient implements ModInitializer {
|
|||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
LOGGER.info("Initializing " + MOD_ID);
|
LOGGER.info("Initializing " + MOD_ID);
|
||||||
client = MinecraftClient.getInstance();
|
client = MinecraftClient.getInstance();
|
||||||
ModManager.init();
|
|
||||||
SaturnClientConfig.init();
|
SaturnClientConfig.init();
|
||||||
ThemeManager.load();
|
ModManager.init();
|
||||||
ConfigManager.load();
|
|
||||||
|
|
||||||
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> {ConfigManager.save(); ThemeManager.save();});
|
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save());
|
||||||
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
|
|
||||||
if (SaturnClientConfig.saturnTitleScreen.value && screen instanceof TitleScreen
|
|
||||||
&& !(screen instanceof SaturnMenu)) {
|
|
||||||
client.setScreen(new SaturnTitleScreen());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> {
|
SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> {
|
||||||
return (resourceManager, location) -> MOD_ID.equals(location.getNamespace());
|
return (resourceManager, location) -> MOD_ID.equals(location.getNamespace());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
|
||||||
|
if (screen != null && !(screen instanceof TitleMenu)) {
|
||||||
|
if (screen instanceof SaturnScreen) {
|
||||||
|
((SaturnScreen) screen).draw(new ImageTexture(Textures.LOGO_TEXT_BIG).dimensions(180, 18)
|
||||||
|
.position(screen.width - 180 - 20, screen.height - 18 - 20));
|
||||||
|
} else {
|
||||||
|
ScreenEvents.afterRender(screen).register((screen1, context, mouseX, mouseY, tickDelta) -> {
|
||||||
|
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||||
|
((DrawContextAccessor) context).getVertexConsumers());
|
||||||
|
|
||||||
|
int width = context.getScaledWindowWidth();
|
||||||
|
int height = context.getScaledWindowHeight();
|
||||||
|
|
||||||
|
float scaleX = (float) screen1.width / width;
|
||||||
|
float scaleY = (float) screen1.height / height;
|
||||||
|
|
||||||
|
MatrixStack matrixStack = context.getMatrices();
|
||||||
|
matrixStack.push();
|
||||||
|
matrixStack.translate(width - 95, height - 14, 0);
|
||||||
|
matrixStack.scale(0.5f / scaleX, 0.5f / scaleY, 1.0f);
|
||||||
|
renderScope.drawTexture(Textures.LOGO_TEXT_BIG, 0, 0, 0, 0, 180, 18);
|
||||||
|
matrixStack.pop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
KeyInputHandler.register();
|
KeyInputHandler.register();
|
||||||
|
Emotes.initialize();
|
||||||
if (Auth.authenticate()) {
|
if (Auth.authenticate()) {
|
||||||
Cloaks.initialize();
|
Cloaks.initialize();
|
||||||
Hats.initialize();
|
Hats.initialize();
|
||||||
|
|||||||
@@ -1,48 +1,20 @@
|
|||||||
package org.saturnclient.saturnclient;
|
package org.saturnclient.saturnclient;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
import org.saturnclient.ui.SaturnAnimation;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import org.saturnclient.ui.animations.FadeIn;
|
|
||||||
|
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.ColorHelper;
|
|
||||||
|
|
||||||
public class SaturnClientConfig {
|
public class SaturnClientConfig {
|
||||||
public static ConfigManager config;
|
public static ConfigManager config;
|
||||||
|
|
||||||
public static Property<Integer> color =
|
public static Property<Boolean> realisticLogo = Property.bool(false);
|
||||||
new Property<>(
|
|
||||||
ColorHelper.getArgb(255, 251, 60, 79),
|
|
||||||
Property.PropertyType.HEX);
|
|
||||||
|
|
||||||
public static Property<Integer> normal =
|
public static Property<Boolean> saturnTitleScreen = Property.bool(true);
|
||||||
new Property<>(
|
public static Property<Integer> openEmoteWheel = Property.keybinding(GLFW.GLFW_KEY_B);
|
||||||
ColorHelper.getArgb(255, 182, 182, 182),
|
|
||||||
Property.PropertyType.HEX);
|
|
||||||
|
|
||||||
public static Property<Boolean> realisticLogo =
|
|
||||||
new Property<>(false);
|
|
||||||
|
|
||||||
public static Property<Boolean> saturnTitleScreen =
|
|
||||||
new Property<>(true);
|
|
||||||
|
|
||||||
public static int WHITE = ColorHelper.getArgb(255, 255, 255, 255);
|
|
||||||
|
|
||||||
public static int getWhite(float alpha) {
|
|
||||||
return ((int) (alpha * 255) << 24) | (normal.value & 0x00FFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getColor(boolean hovering, float alpha) {
|
|
||||||
return SaturnUi.getAlpha(hovering ? color.value : normal.value, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SaturnAnimation[] getAnimations() {
|
|
||||||
return new SaturnAnimation[] { new FadeIn(1) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Identifier getLogo() {
|
public static Identifier getLogo() {
|
||||||
return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO;
|
return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO;
|
||||||
@@ -71,10 +43,8 @@ public class SaturnClientConfig {
|
|||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
config = new ConfigManager("Saturn Client");
|
config = new ConfigManager("Saturn Client");
|
||||||
|
|
||||||
config.property("Primary color", color);
|
|
||||||
config.property("Default color", normal);
|
|
||||||
config.property("Realistic logo", realisticLogo);
|
config.property("Realistic logo", realisticLogo);
|
||||||
config.property("Saturn client title screen", saturnTitleScreen);
|
config.property("Saturn client title screen", saturnTitleScreen);
|
||||||
|
config.property("Open Emote Wheel", openEmoteWheel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,22 @@ package org.saturnclient.saturnclient.auth;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
|
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||||
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
|
import org.saturnclient.ui2.elements.Notification;
|
||||||
|
import org.saturnclient.ui2.elements.Notification.NotificationKind;
|
||||||
|
|
||||||
|
import dev.kosmx.playerAnim.api.layered.AnimationStack;
|
||||||
|
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
|
||||||
|
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationRegistry;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
|
||||||
public class Auth {
|
public class Auth {
|
||||||
@@ -96,9 +109,72 @@ public class Auth {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "successful_transaction":
|
||||||
|
String cloak = parser.getStringOrNull("cloak");
|
||||||
|
String hat = parser.getStringOrNull("hat");
|
||||||
|
if (cloak != null) {
|
||||||
|
Cloaks.availableCloaks.add(cloak);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (hat != null) {
|
||||||
|
Hats.availableHats.add(hat);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "update_cloak":
|
||||||
|
String targetUuid = parser.getStringOrNull("uuid");
|
||||||
|
String targetCloak = parser.getStringOrNull("cloak");
|
||||||
|
if (targetUuid != null && targetCloak != null) {
|
||||||
|
SaturnPlayer player = players.get(targetUuid);
|
||||||
|
if (player != null) {
|
||||||
|
player.cloak = targetCloak;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "update_hat":
|
||||||
|
targetUuid = parser.getStringOrNull("uuid");
|
||||||
|
String targetHat = parser.getStringOrNull("hat");
|
||||||
|
if (targetUuid != null && targetHat != null) {
|
||||||
|
SaturnPlayer player = players.get(targetUuid);
|
||||||
|
if (player != null) {
|
||||||
|
player.hat = targetHat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "emote":
|
||||||
|
targetUuid = parser.getStringOrNull("uuid");
|
||||||
|
String emote = parser.getStringOrNull("name");
|
||||||
|
|
||||||
|
for (AbstractClientPlayerEntity player : SaturnClient.client.world.getPlayers()) {
|
||||||
|
if (player.getUuidAsString().replace("-", "").equals(targetUuid)) {
|
||||||
|
AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(player);
|
||||||
|
if (emote != null && !emote.isEmpty()) {
|
||||||
|
if (animationStack.isActive() && animationStack.getPriority() == 1000) {
|
||||||
|
animationStack.removeLayer(1000);
|
||||||
|
}
|
||||||
|
animationStack.addAnimLayer(1000,
|
||||||
|
PlayerAnimationRegistry
|
||||||
|
.getAnimation(Identifier.of("saturnclient", emote))
|
||||||
|
.playAnimation());
|
||||||
|
} else {
|
||||||
|
animationStack.removeLayer(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (parser.error != null) {
|
if (parser.error != null) {
|
||||||
SaturnClient.LOGGER.error("Error from the server: " + parser.error);
|
SaturnClient.LOGGER.error("Error from the server: " + parser.error);
|
||||||
|
|
||||||
|
if (SaturnClient.client.currentScreen instanceof SaturnScreen) {
|
||||||
|
String[] a = parser.error.replace("!", "").split(": ");
|
||||||
|
((SaturnScreen) SaturnClient.client.currentScreen)
|
||||||
|
.draw(new Notification(SaturnClient.client.currentScreen.width,
|
||||||
|
SaturnClient.client.currentScreen.height, NotificationKind.Error,
|
||||||
|
a[0], a[1]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -117,17 +193,22 @@ public class Auth {
|
|||||||
private static void startPingThread() {
|
private static void startPingThread() {
|
||||||
pingThread = new Thread(() -> {
|
pingThread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
while (running) {
|
while (running && !Thread.currentThread().isInterrupted()) {
|
||||||
|
try {
|
||||||
Thread.sleep(25000); // 25 seconds
|
Thread.sleep(25000); // 25 seconds
|
||||||
if (running) {
|
if (running) {
|
||||||
Network.write("ping");
|
Network.write("ping");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
SaturnClient.LOGGER.warn("Ping thread interrupted", e);
|
Thread.currentThread().interrupt(); // Restore interrupt status
|
||||||
|
break; // Exit the loop on interruption
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
if (!(e instanceof InterruptedException)) {
|
||||||
SaturnClient.LOGGER.error("Error in ping thread", e);
|
SaturnClient.LOGGER.error("Error in ping thread", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
pingThread.setDaemon(true);
|
pingThread.setDaemon(true);
|
||||||
@@ -156,7 +237,7 @@ public class Auth {
|
|||||||
|
|
||||||
public static void setCloak(String cloakName) {
|
public static void setCloak(String cloakName) {
|
||||||
try {
|
try {
|
||||||
Network.write("set_cloak@cloak=" + cloakName);
|
Network.write("set_cloak@cloak=" + cloakName + "@notify=" + stringifyPlayers());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
SaturnClient.LOGGER.error("Request failed", e);
|
SaturnClient.LOGGER.error("Request failed", e);
|
||||||
}
|
}
|
||||||
@@ -164,12 +245,26 @@ public class Auth {
|
|||||||
|
|
||||||
public static void setHat(String hatName) {
|
public static void setHat(String hatName) {
|
||||||
try {
|
try {
|
||||||
Network.write("set_hat@hat=" + hatName);
|
Network.write("set_hat@hat=" + hatName + "@notify=" + stringifyPlayers());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
SaturnClient.LOGGER.error("Request failed", e);
|
SaturnClient.LOGGER.error("Request failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void emote(String name) {
|
||||||
|
try {
|
||||||
|
Network.write("emote@name=" + name + "@notify=" + stringifyPlayers());
|
||||||
|
} catch (Exception e) {
|
||||||
|
SaturnClient.LOGGER.error("Request failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String stringifyPlayers() {
|
||||||
|
return players.keySet().stream()
|
||||||
|
.filter(key -> key != uuid)
|
||||||
|
.collect(Collectors.joining("$"));
|
||||||
|
}
|
||||||
|
|
||||||
public static void player(String name, String uuid) {
|
public static void player(String name, String uuid) {
|
||||||
try {
|
try {
|
||||||
playerNames.put(name, uuid.replaceAll("-", ""));
|
playerNames.put(name, uuid.replaceAll("-", ""));
|
||||||
@@ -179,14 +274,19 @@ public class Auth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendReload() {
|
public static void buyCloak(String name) {
|
||||||
for (Map.Entry<String, String> player : playerNames.entrySet()) {
|
try {
|
||||||
if (players.containsKey(player.getValue()) && !player.getValue().equals(uuid)) {
|
Network.write("buy_cloak@cloak=" + name);
|
||||||
SaturnClient.client.player.networkHandler
|
} catch (Exception e) {
|
||||||
.sendChatCommand("msg " + player.getKey() + " "
|
SaturnClient.LOGGER.error("Request failed", e);
|
||||||
+ "$SATURN_RELOAD if you are seeing this as a player, please report this to https://github.com/saturnclientmc/saturnclient/issues");
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void buyHat(String name) {
|
||||||
|
try {
|
||||||
|
Network.write("buy_hat@hat=" + name);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SaturnClient.LOGGER.error("Request failed", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ public class SaturnParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getStringOrNull(String i) throws IOException {
|
||||||
|
String val = params.get(i);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getBool(String i) throws IOException {
|
public boolean getBool(String i) throws IOException {
|
||||||
String val = params.get(i);
|
String val = params.get(i);
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
|
|||||||
@@ -15,13 +15,14 @@ import java.util.Map;
|
|||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
|
||||||
public class ConfigManager {
|
public class ConfigManager {
|
||||||
|
|
||||||
private static File configFile = new File(
|
private static File configFile = new File(
|
||||||
SaturnClient.client.runDirectory,
|
SaturnClient.client.runDirectory,
|
||||||
"saturn.json");
|
"saturn.json");
|
||||||
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
||||||
|
private static JsonObject cachedThemeJson = null;
|
||||||
|
|
||||||
private Map<String, Property<?>> currentMap;
|
private Map<String, Property<?>> currentMap;
|
||||||
|
private String namespace;
|
||||||
|
|
||||||
public ConfigManager(String namespace) {
|
public ConfigManager(String namespace) {
|
||||||
currentMap = new LinkedHashMap<>();
|
currentMap = new LinkedHashMap<>();
|
||||||
@@ -31,21 +32,59 @@ public class ConfigManager {
|
|||||||
|
|
||||||
public ConfigManager(ConfigManager config, String namespace) {
|
public ConfigManager(ConfigManager config, String namespace) {
|
||||||
currentMap = new LinkedHashMap<>();
|
currentMap = new LinkedHashMap<>();
|
||||||
Property<Map<String, Property<?>>> namespaceProperty = new Property<>(currentMap,
|
Property<Map<String, Property<?>>> namespaceProperty = Property.namespace(currentMap);
|
||||||
Property.PropertyType.NAMESPACE);
|
|
||||||
config.property(namespace, namespaceProperty);
|
config.property(namespace, namespaceProperty);
|
||||||
// Update the parent's state
|
// Update the parent's state
|
||||||
config.currentMap.put(namespace, namespaceProperty);
|
config.currentMap.put(namespace, namespaceProperty);
|
||||||
System.out.println("Created sub-namespace: " + namespace);
|
System.out.println("Created sub-namespace: " + namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sub(String namespace) {
|
||||||
|
Property<Map<String, Property<?>>> namespaceProperty = Property.namespace(currentMap);
|
||||||
|
property(namespace, namespaceProperty);
|
||||||
|
}
|
||||||
|
|
||||||
// Generic method to store any type of property
|
// Generic method to store any type of property
|
||||||
public <T> Property<T> property(String name, Property<T> value) {
|
public <T> Property<T> property(String name, Property<T> value) {
|
||||||
System.out.println("Adding property: " + name);
|
|
||||||
currentMap.put(name, value);
|
currentMap.put(name, value);
|
||||||
|
loadProp(name, value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> void loadProp(String name, Property<T> prop) {
|
||||||
|
if (cachedThemeJson != null) {
|
||||||
|
JsonElement element = cachedThemeJson.get(namespace);
|
||||||
|
if (element != null && element.isJsonObject()) {
|
||||||
|
JsonObject theme = element.getAsJsonObject();
|
||||||
|
JsonElement value = theme.get(name);
|
||||||
|
if (value != null && prop.matchesJson(value)) {
|
||||||
|
switch (prop.getType()) {
|
||||||
|
case BOOLEAN:
|
||||||
|
((Property<Boolean>) prop).setValue(value.getAsBoolean());
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
((Property<Integer>) prop).setValue(value.getAsInt());
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
((Property<Float>) prop).setValue(value.getAsFloat());
|
||||||
|
break;
|
||||||
|
case STRING:
|
||||||
|
((Property<String>) prop).setValue(value.getAsString());
|
||||||
|
break;
|
||||||
|
case HEX:
|
||||||
|
((Property<Integer>) prop).setValue(value.getAsInt());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void load() {
|
public static void load() {
|
||||||
try {
|
try {
|
||||||
SaturnClient.LOGGER.info("Starting to load config...");
|
SaturnClient.LOGGER.info("Starting to load config...");
|
||||||
@@ -58,7 +97,6 @@ public class ConfigManager {
|
|||||||
new String(Files.readAllBytes(configFile.toPath()))).getAsJsonObject();
|
new String(Files.readAllBytes(configFile.toPath()))).getAsJsonObject();
|
||||||
|
|
||||||
for (String namespace : properties.keySet()) {
|
for (String namespace : properties.keySet()) {
|
||||||
SaturnClient.LOGGER.info("Loading namespace: " + namespace);
|
|
||||||
JsonElement configElement = jsonObject.get(namespace);
|
JsonElement configElement = jsonObject.get(namespace);
|
||||||
|
|
||||||
if (configElement == null)
|
if (configElement == null)
|
||||||
@@ -80,8 +118,6 @@ public class ConfigManager {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static void loadProperties(JsonObject config, Map<String, Property<?>> propertyMap) {
|
private static void loadProperties(JsonObject config, Map<String, Property<?>> propertyMap) {
|
||||||
SaturnClient.LOGGER.info("Loading properties: " + propertyMap);
|
|
||||||
|
|
||||||
for (String propertyName : propertyMap.keySet()) {
|
for (String propertyName : propertyMap.keySet()) {
|
||||||
JsonElement c = config.get(propertyName);
|
JsonElement c = config.get(propertyName);
|
||||||
|
|
||||||
@@ -97,25 +133,17 @@ public class ConfigManager {
|
|||||||
Map<String, Property<?>> nestedProperties = p.getNamespaceValue();
|
Map<String, Property<?>> nestedProperties = p.getNamespaceValue();
|
||||||
loadProperties(nestedConfig, nestedProperties);
|
loadProperties(nestedConfig, nestedProperties);
|
||||||
} else {
|
} else {
|
||||||
// Handle regular properties
|
if (p.value instanceof Integer) {
|
||||||
switch (p.getType()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
((Property<Boolean>) p).value = c.getAsBoolean();
|
|
||||||
break;
|
|
||||||
case INTEGER:
|
|
||||||
((Property<Integer>) p).value = c.getAsInt();
|
((Property<Integer>) p).value = c.getAsInt();
|
||||||
break;
|
} else if (p.value instanceof String) {
|
||||||
case FLOAT:
|
|
||||||
((Property<Float>) p).value = c.getAsFloat();
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
((Property<String>) p).value = c.getAsString();
|
((Property<String>) p).value = c.getAsString();
|
||||||
break;
|
} else if (p.value instanceof Float) {
|
||||||
case HEX:
|
((Property<Float>) p).value = c.getAsFloat();
|
||||||
((Property<Integer>) p).value = c.getAsInt();
|
} else if (p.value instanceof Boolean) {
|
||||||
break;
|
((Property<Boolean>) p).value = c.getAsBoolean();
|
||||||
default:
|
} else {
|
||||||
break;
|
SaturnClient.LOGGER.warn(
|
||||||
|
"Unknown property type for: " + propertyName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -161,36 +189,29 @@ public class ConfigManager {
|
|||||||
for (String propertyName : propertyMap.keySet()) {
|
for (String propertyName : propertyMap.keySet()) {
|
||||||
Property<?> property = propertyMap.get(propertyName);
|
Property<?> property = propertyMap.get(propertyName);
|
||||||
JsonElement propertyValue = null;
|
JsonElement propertyValue = null;
|
||||||
|
// Convert the property value based on its type
|
||||||
if (property.getType() == Property.PropertyType.NAMESPACE) {
|
switch (property.getType()) {
|
||||||
|
case NAMESPACE:
|
||||||
// Handle nested namespace
|
// Handle nested namespace
|
||||||
JsonObject nestedConfig = new JsonObject();
|
JsonObject nestedConfig = new JsonObject();
|
||||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
||||||
saveProperties(nestedConfig, nestedProperties);
|
saveProperties(nestedConfig, nestedProperties);
|
||||||
propertyValue = nestedConfig;
|
propertyValue = nestedConfig;
|
||||||
} else {
|
|
||||||
// Convert the property value based on its type
|
|
||||||
switch (property.getType()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
propertyValue = new JsonPrimitive((Boolean) property.value);
|
|
||||||
break;
|
|
||||||
case INTEGER:
|
|
||||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
|
||||||
break;
|
|
||||||
case FLOAT:
|
|
||||||
propertyValue = new JsonPrimitive((Float) property.value);
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
propertyValue = new JsonPrimitive((String) property.value);
|
|
||||||
break;
|
|
||||||
case HEX:
|
|
||||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (property.value instanceof Integer) {
|
||||||
|
propertyValue = new JsonPrimitive((Integer) property.value);
|
||||||
|
} else if (property.value instanceof String) {
|
||||||
|
propertyValue = new JsonPrimitive((String) property.value);
|
||||||
|
} else if (property.value instanceof Float) {
|
||||||
|
propertyValue = new JsonPrimitive((Float) property.value);
|
||||||
|
} else if (property.value instanceof Boolean) {
|
||||||
|
propertyValue = new JsonPrimitive((Boolean) property.value);
|
||||||
|
} else {
|
||||||
SaturnClient.LOGGER.warn(
|
SaturnClient.LOGGER.warn(
|
||||||
"Unknown property type for: " + propertyName);
|
"Unknown property type for: " + propertyName);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyValue != null) {
|
if (propertyValue != null) {
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package org.saturnclient.saturnclient.config;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
|
||||||
@@ -13,62 +16,108 @@ public class Property<T> {
|
|||||||
FLOAT,
|
FLOAT,
|
||||||
STRING,
|
STRING,
|
||||||
HEX,
|
HEX,
|
||||||
NAMESPACE
|
NAMESPACE,
|
||||||
|
SELECT,
|
||||||
|
KEYBINDING,
|
||||||
}
|
}
|
||||||
|
|
||||||
public T value;
|
public T value;
|
||||||
public boolean isReset = false;
|
public boolean isReset = false;
|
||||||
private T defaultValue;
|
private T defaultValue;
|
||||||
|
private String[] availableValues;
|
||||||
private PropertyType type;
|
private PropertyType type;
|
||||||
|
private boolean wasPressedLastTick = false;
|
||||||
|
|
||||||
public Property(T value) {
|
private Property(T value, PropertyType type) {
|
||||||
this.value = value;
|
|
||||||
this.defaultValue = value;
|
|
||||||
if (value instanceof Boolean) {
|
|
||||||
type = PropertyType.BOOLEAN;
|
|
||||||
} else if (value instanceof Integer) {
|
|
||||||
type = PropertyType.INTEGER;
|
|
||||||
} else if (value instanceof Float) {
|
|
||||||
type = PropertyType.FLOAT;
|
|
||||||
} else if (value instanceof String) {
|
|
||||||
type = PropertyType.STRING;
|
|
||||||
} else if (valueIsNamespace(value)) {
|
|
||||||
type = PropertyType.NAMESPACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Property(T value, PropertyType type) {
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.defaultValue = value;
|
this.defaultValue = value;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getBool() {
|
public static <T> Property<T> from(T value) {
|
||||||
if (value instanceof Boolean) {
|
if (value instanceof Boolean) {
|
||||||
return (boolean) value;
|
return new Property<>(value, PropertyType.BOOLEAN);
|
||||||
|
} else if (value instanceof Integer) {
|
||||||
|
return new Property<>(value, PropertyType.INTEGER);
|
||||||
|
} else if (value instanceof Float) {
|
||||||
|
return new Property<>(value, PropertyType.FLOAT);
|
||||||
|
} else if (value instanceof String) {
|
||||||
|
return new Property<>(value, PropertyType.STRING);
|
||||||
|
} else if (valueIsNamespace(value)) {
|
||||||
|
return new Property<>(value, PropertyType.NAMESPACE);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Property does not contain a boolean");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInt() {
|
public Property<T> copy() {
|
||||||
if (value instanceof Integer) {
|
return new Property<>(this.value, this.type);
|
||||||
return (int) value;
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Property does not contain an int");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getFloat() {
|
public static Property<Integer> font(int value) {
|
||||||
if (value instanceof Float) {
|
return select(value, "Default", "Inter", "Inter bold");
|
||||||
return (float) value;
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Property does not contain a float");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString() {
|
public static Property<Integer> select(Integer value, String... availableValues) {
|
||||||
if (value instanceof String) {
|
Property<Integer> property = new Property<>(value, PropertyType.SELECT);
|
||||||
return (String) value;
|
property.availableValues = availableValues;
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Property<Map<String, Property<?>>> namespace(Map<String, Property<?>> value) {
|
||||||
|
return new Property<>(value, PropertyType.NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Property<Boolean> bool(boolean value) {
|
||||||
|
return new Property<>(value, PropertyType.BOOLEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Property<Integer> integer(int value) {
|
||||||
|
return new Property<>(value, PropertyType.INTEGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Property<Float> floatProp(float value) {
|
||||||
|
return new Property<>(value, PropertyType.FLOAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Property<String> string(String value) {
|
||||||
|
return new Property<>(value, PropertyType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Property<Integer> color(int value) {
|
||||||
|
return new Property<>(value, PropertyType.HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Property<Integer> keybinding(int value) {
|
||||||
|
return new Property<>(value, PropertyType.KEYBINDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void next() {
|
||||||
|
if ((Integer) value < availableValues.length - 1)
|
||||||
|
setValue((Integer) value + 1);
|
||||||
|
else
|
||||||
|
setValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void prev() {
|
||||||
|
if ((Integer) value > 0)
|
||||||
|
setValue((Integer) value - 1);
|
||||||
|
else
|
||||||
|
setValue(availableValues.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelection(int selection) {
|
||||||
|
if (selection >= 0 && selection < availableValues.length && type == PropertyType.SELECT) {
|
||||||
|
setValue(selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSelection() {
|
||||||
|
if (type == PropertyType.SELECT) {
|
||||||
|
return availableValues[(Integer) value];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Property does not contain a string");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
@@ -115,12 +164,8 @@ public class Property<T> {
|
|||||||
return true;
|
return true;
|
||||||
if (value instanceof String && primitive.isString())
|
if (value instanceof String && primitive.isString())
|
||||||
return true;
|
return true;
|
||||||
|
if (type == PropertyType.HEX && primitive.isString())
|
||||||
// Check if JSON string represents a valid hex integer
|
return true;
|
||||||
if (value instanceof String && primitive.isString()) {
|
|
||||||
String str = primitive.getAsString();
|
|
||||||
return str.matches("0x[0-9A-Fa-f]+");
|
|
||||||
}
|
|
||||||
} else if (element.isJsonObject()) {
|
} else if (element.isJsonObject()) {
|
||||||
return isNamespace(value);
|
return isNamespace(value);
|
||||||
}
|
}
|
||||||
@@ -154,4 +199,60 @@ public class Property<T> {
|
|||||||
public NamedProperty<T> named(String name) {
|
public NamedProperty<T> named(String name) {
|
||||||
return new NamedProperty<>(name, this);
|
return new NamedProperty<>(name, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isKeyPressed() {
|
||||||
|
return (Integer) value == -1 ? false
|
||||||
|
: GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(),
|
||||||
|
(Integer) (Object) value) == GLFW.GLFW_PRESS && SaturnClient.client.currentScreen == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean wasKeyPressed() {
|
||||||
|
boolean isPressed = this.isKeyPressed();
|
||||||
|
wasPressedLastTick = isPressed && !wasPressedLastTick;
|
||||||
|
return wasPressedLastTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void load(String name, JsonElement element) {
|
||||||
|
if (element != null && element.isJsonObject()) {
|
||||||
|
JsonElement value = element.getAsJsonObject().get(name);
|
||||||
|
if (value != null) {
|
||||||
|
switch (this.getType()) {
|
||||||
|
case BOOLEAN:
|
||||||
|
((Property<Boolean>) this).setValue(value.getAsBoolean());
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
JsonPrimitive primitive = value.getAsJsonPrimitive();
|
||||||
|
if (primitive.isNumber())
|
||||||
|
((Property<Integer>) this).setValue(value.getAsInt());
|
||||||
|
else if (primitive.isString())
|
||||||
|
((Property<Integer>) this).setValue(parseHexToInt(value.getAsString()));
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
((Property<Float>) this).setValue(value.getAsFloat());
|
||||||
|
break;
|
||||||
|
case STRING:
|
||||||
|
((Property<String>) this).setValue(value.getAsString());
|
||||||
|
break;
|
||||||
|
case HEX:
|
||||||
|
((Property<Integer>) this).setValue(parseHexToInt(value.getAsString()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int parseHexToInt(String hex) {
|
||||||
|
hex = hex.replaceAll("#", "");
|
||||||
|
|
||||||
|
if (hex.length() == 6) {
|
||||||
|
hex = "FF" + hex;
|
||||||
|
} else if (hex.length() != 8) {
|
||||||
|
throw new IllegalArgumentException("Hex string must be 6 or 8 characters long");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) Long.parseLong(hex, 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,73 +3,75 @@ package org.saturnclient.saturnclient.config;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
|
|
||||||
public class ThemeManager {
|
public class ThemeManager {
|
||||||
|
|
||||||
private static File themeFile = new File(
|
private static File themeFile = new File(
|
||||||
SaturnClient.client.runDirectory,
|
SaturnClient.client.runDirectory,
|
||||||
"saturn.theme.json");
|
"saturn.theme.json");
|
||||||
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
private static List<ThemeManager> theme = new ArrayList<>();
|
||||||
|
private static JsonObject cachedThemeJson = null;
|
||||||
|
|
||||||
// private Map<String, Map<String, Property<?>>> states;
|
private Map<String, Map<String, Object>> states;
|
||||||
private Map<String, Property<?>> currentStyling;
|
private Map<String, Property<?>> currentStyling;
|
||||||
private String state;
|
|
||||||
private String[] states;
|
|
||||||
private String namespace;
|
private String namespace;
|
||||||
|
|
||||||
public ThemeManager(String namespace, String... states) {
|
public ThemeManager(String namespace, String... states) {
|
||||||
// this.states = new LinkedHashMap<>();
|
|
||||||
this.namespace = namespace;
|
this.namespace = namespace;
|
||||||
this.states = states;
|
this.states = new LinkedHashMap<>();
|
||||||
currentStyling = new LinkedHashMap<>();
|
this.currentStyling = new LinkedHashMap<>();
|
||||||
|
this.states.put(null, new LinkedHashMap<>());
|
||||||
properties.put(namespace, new LinkedHashMap<>());
|
|
||||||
|
|
||||||
for (String s : states) {
|
for (String s : states) {
|
||||||
properties.put(namespace+"@"+s, new LinkedHashMap<>());
|
this.states.put(s, new LinkedHashMap<>());
|
||||||
}
|
}
|
||||||
|
theme.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setState(String state) {
|
public void setState(String state) {
|
||||||
this.state = state;
|
for (Map.Entry<String, Object> tProp : states.get(state).entrySet()) {
|
||||||
|
currentStyling.get(tProp.getKey()).setValue(tProp.getValue());
|
||||||
if (this.state != null) {
|
|
||||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace+"@"+state).entrySet()) {
|
|
||||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace).entrySet()) {
|
|
||||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void applyState(String state) {
|
||||||
|
for (Map.Entry<String, Object> tProp : states.get(state).entrySet()) {
|
||||||
|
if (!states.get(null).get(tProp.getKey()).equals(tProp.getValue()))
|
||||||
|
currentStyling.get(tProp.getKey()).setValue(tProp.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic method to store any type of property
|
|
||||||
public <T> Property<T> property(String name, Property<T> prop) {
|
public <T> Property<T> property(String name, Property<T> prop) {
|
||||||
for (String state : states) {
|
for (Map.Entry<String, Map<String, Object>> state : this.states.entrySet()) {
|
||||||
properties.get(namespace+"@"+state).put(name, new Property<T>(prop.value));
|
Property<?> property = prop.copy();
|
||||||
|
if (cachedThemeJson == null) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
String stateName = state.getKey();
|
||||||
|
property.load(name, cachedThemeJson.get(stateName != null ? namespace + "@" + stateName : namespace));
|
||||||
|
state.getValue().put(name, property.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
properties.get(namespace).put(name, new Property<T>(prop.value));
|
|
||||||
currentStyling.put(name, prop);
|
currentStyling.put(name, prop);
|
||||||
|
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void propertyStateDefault(String state, String name, T value) {
|
public <T> void propertyStateDefault(String state, String name, T value) {
|
||||||
properties.get(namespace+"@"+state).get(name).setValue(value, value); // sets the current and default value
|
Property<?> prop = currentStyling.get(name).copy();
|
||||||
|
prop.setValue(value, value);
|
||||||
|
if (cachedThemeJson == null) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
prop.load(name, cachedThemeJson.get(state != null ? namespace + "@" + state : namespace));
|
||||||
|
states.get(state).put(name, prop.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void load() {
|
public static void load() {
|
||||||
@@ -80,145 +82,12 @@ public class ThemeManager {
|
|||||||
Files.write(themeFile.toPath(), "{}".getBytes());
|
Files.write(themeFile.toPath(), "{}".getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject jsonObject = JsonParser.parseString(
|
cachedThemeJson = JsonParser.parseString(
|
||||||
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
|
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
|
||||||
|
|
||||||
for (String namespace : properties.keySet()) {
|
SaturnClient.LOGGER.info("Theme loaded");
|
||||||
JsonElement themeElement = jsonObject.get(namespace);
|
|
||||||
|
|
||||||
if (themeElement == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
JsonObject theme = jsonObject.get(namespace).getAsJsonObject();
|
|
||||||
|
|
||||||
if (theme == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Property<?>> propertyMap = properties.get(namespace);
|
|
||||||
loadProperties(theme, propertyMap);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
SaturnClient.LOGGER.error("Error reading the theme file", e);
|
SaturnClient.LOGGER.error("Error reading the theme file", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static void loadProperties(JsonObject theme, Map<String, Property<?>> propertyMap) {
|
|
||||||
for (String propertyName : propertyMap.keySet()) {
|
|
||||||
JsonElement c = theme.get(propertyName);
|
|
||||||
|
|
||||||
if (c == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Property<?> p = propertyMap.get(propertyName);
|
|
||||||
if (p.matchesJson(c)) {
|
|
||||||
if (p.getType() == Property.PropertyType.NAMESPACE) {
|
|
||||||
// Handle nested namespace
|
|
||||||
JsonObject nestedTheme = c.getAsJsonObject();
|
|
||||||
Map<String, Property<?>> nestedProperties = p.getNamespaceValue();
|
|
||||||
loadProperties(nestedTheme, nestedProperties);
|
|
||||||
} else {
|
|
||||||
// Handle regular properties
|
|
||||||
switch (p.getType()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
((Property<Boolean>) p).value = c.getAsBoolean();
|
|
||||||
break;
|
|
||||||
case INTEGER:
|
|
||||||
((Property<Integer>) p).value = c.getAsInt();
|
|
||||||
break;
|
|
||||||
case FLOAT:
|
|
||||||
((Property<Float>) p).value = c.getAsFloat();
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
((Property<String>) p).value = c.getAsString();
|
|
||||||
break;
|
|
||||||
case HEX:
|
|
||||||
((Property<Integer>) p).value = c.getAsInt();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SaturnClient.LOGGER.warn(
|
|
||||||
"Property does not match JSON: " + propertyName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void save() {
|
|
||||||
try {
|
|
||||||
SaturnClient.LOGGER.info("Starting to save theme...");
|
|
||||||
|
|
||||||
JsonObject jsonObject = new JsonObject();
|
|
||||||
|
|
||||||
// Iterate through all namespaces and their properties
|
|
||||||
for (String namespace : properties.keySet()) {
|
|
||||||
JsonObject namespaceTheme = new JsonObject();
|
|
||||||
Map<String, Property<?>> propertyMap = properties.get(namespace);
|
|
||||||
|
|
||||||
// Save properties for this namespace
|
|
||||||
saveProperties(namespaceTheme, propertyMap);
|
|
||||||
|
|
||||||
// Add the namespace theme to the main JSON object
|
|
||||||
jsonObject.add(namespace, namespaceTheme);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the json so it can easily be edited
|
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
|
||||||
String formattedJson = gson.toJson(jsonObject);
|
|
||||||
|
|
||||||
// Write the JSON object to the theme file
|
|
||||||
Files.write(themeFile.toPath(), formattedJson.getBytes());
|
|
||||||
SaturnClient.LOGGER.info("Theme saved successfully.");
|
|
||||||
} catch (IOException e) {
|
|
||||||
SaturnClient.LOGGER.error("Error saving the theme file", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static void saveProperties(JsonObject theme, Map<String, Property<?>> propertyMap) {
|
|
||||||
// Iterate through each property in the namespace
|
|
||||||
for (String propertyName : propertyMap.keySet()) {
|
|
||||||
Property<?> property = propertyMap.get(propertyName);
|
|
||||||
JsonElement propertyValue = null;
|
|
||||||
|
|
||||||
if (property.getType() == Property.PropertyType.NAMESPACE) {
|
|
||||||
// Handle nested namespace
|
|
||||||
JsonObject nestedTheme = new JsonObject();
|
|
||||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
|
||||||
saveProperties(nestedTheme, nestedProperties);
|
|
||||||
propertyValue = nestedTheme;
|
|
||||||
} else {
|
|
||||||
// Convert the property value based on its type
|
|
||||||
switch (property.getType()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
propertyValue = new JsonPrimitive((Boolean) property.value);
|
|
||||||
break;
|
|
||||||
case INTEGER:
|
|
||||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
|
||||||
break;
|
|
||||||
case FLOAT:
|
|
||||||
propertyValue = new JsonPrimitive((Float) property.value);
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
propertyValue = new JsonPrimitive((String) property.value);
|
|
||||||
break;
|
|
||||||
case HEX:
|
|
||||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SaturnClient.LOGGER.warn(
|
|
||||||
"Unknown property type for: " + propertyName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyValue != null) {
|
|
||||||
theme.add(propertyName, propertyValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package org.saturnclient.saturnclient.cosmetics;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Emotes {
|
||||||
|
public static List<String> availableEmotes = new ArrayList<>();
|
||||||
|
|
||||||
|
public static void initialize() {
|
||||||
|
availableEmotes.add("tpose");
|
||||||
|
availableEmotes.add("back_flip");
|
||||||
|
availableEmotes.add("facepalm");
|
||||||
|
availableEmotes.add("cry");
|
||||||
|
availableEmotes.add("giga_chad");
|
||||||
|
availableEmotes.add("front_flip");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState,
|
|||||||
PlayerEntityRenderState state, float limbAngle, float limbDistance) {
|
PlayerEntityRenderState state, float limbAngle, float limbDistance) {
|
||||||
ItemStack headItem = state.equippedHeadStack;
|
ItemStack headItem = state.equippedHeadStack;
|
||||||
String uuid = Auth.playerNames.get(state.name);
|
String uuid = Auth.playerNames.get(state.name);
|
||||||
if (headItem.isEmpty() && uuid != null) {
|
if (headItem.isEmpty() && uuid != null && !state.invisible) {
|
||||||
SaturnPlayer player = Auth.players.get(uuid);
|
SaturnPlayer player = Auth.players.get(uuid);
|
||||||
if (player == null || player.hat == null || player.hat.isEmpty()) {
|
if (player == null || player.hat == null || player.hat.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
|||||||
import org.saturnclient.saturnclient.auth.Auth;
|
import org.saturnclient.saturnclient.auth.Auth;
|
||||||
|
|
||||||
public class Hats {
|
public class Hats {
|
||||||
|
public static final String[] ALL_HATS = { "horns_black", "horns_white", "halo", "halo_black" };
|
||||||
public static List<String> availableHats = new ArrayList<>();
|
public static List<String> availableHats = new ArrayList<>();
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
@@ -15,7 +16,6 @@ public class Hats {
|
|||||||
public static void setHat(String uuid, String hatName) {
|
public static void setHat(String uuid, String hatName) {
|
||||||
setHatSilent(uuid, hatName);
|
setHatSilent(uuid, hatName);
|
||||||
Auth.setHat(hatName);
|
Auth.setHat(hatName);
|
||||||
Auth.sendReload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setHatSilent(String uuid, String hatName) {
|
public static void setHatSilent(String uuid, String hatName) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.saturnclient.saturnclient.SaturnClient;
|
|||||||
* Originally created by IIpho3nix and modified for Saturn Client by leo.
|
* Originally created by IIpho3nix and modified for Saturn Client by leo.
|
||||||
*/
|
*/
|
||||||
public class Cloaks {
|
public class Cloaks {
|
||||||
|
public static final String[] ALL_CLOAKS = { "glitch", "mercedes_flow", "crimson_mark", "bmw", "amg", "amg_petronas", "ferrari", "redbull" };
|
||||||
private static final String[] ANIMATED_CLOAKS = { "glitch" };
|
private static final String[] ANIMATED_CLOAKS = { "glitch" };
|
||||||
|
|
||||||
private static final String CLOAKS_RESOURCE_PATH = "assets/saturnclient/textures/cloaks/";
|
private static final String CLOAKS_RESOURCE_PATH = "assets/saturnclient/textures/cloaks/";
|
||||||
@@ -44,10 +45,20 @@ public class Cloaks {
|
|||||||
public static void setCloak(String uuid, String cloakName) {
|
public static void setCloak(String uuid, String cloakName) {
|
||||||
Auth.setCloak(cloakName);
|
Auth.setCloak(cloakName);
|
||||||
setCloakSilent(uuid, cloakName);
|
setCloakSilent(uuid, cloakName);
|
||||||
Auth.sendReload();
|
|
||||||
SaturnClient.LOGGER.info("Cloak set to " + cloakName);
|
SaturnClient.LOGGER.info("Cloak set to " + cloakName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets cloak of the current player
|
||||||
|
*
|
||||||
|
* @param cloakName Name of the cloak file to load
|
||||||
|
*/
|
||||||
|
public static void setCloak(String cloakName) {
|
||||||
|
if (availableCloaks.contains(cloakName)) {
|
||||||
|
setCloak(Auth.uuid, cloakName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles loading and caching of a new cloak texture, without connecting to the
|
* Handles loading and caching of a new cloak texture, without connecting to the
|
||||||
* server.
|
* server.
|
||||||
@@ -101,20 +112,25 @@ public class Cloaks {
|
|||||||
List<AnimatedCloakData> animatedFrames = new ArrayList<>();
|
List<AnimatedCloakData> animatedFrames = new ArrayList<>();
|
||||||
for (int i = 0; i < frameCount; i++) {
|
for (int i = 0; i < frameCount; i++) {
|
||||||
String frameId = fileName.replace(".gif", "") + "_frame_" + i;
|
String frameId = fileName.replace(".gif", "") + "_frame_" + i;
|
||||||
Identifier frameIdentifier = Identifier.of(SaturnClient.MOD_ID, "cloaks_" + frameId);
|
Identifier frameIdentifier = Identifier.of(SaturnClient.MOD_ID,
|
||||||
IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frames.get(i));
|
"cloaks_" + frameId);
|
||||||
|
IdentifierUtils.registerBufferedImageTexture(frameIdentifier,
|
||||||
|
frames.get(i));
|
||||||
animatedFrames.add(new AnimatedCloakData(frameIdentifier, delays.get(i)));
|
animatedFrames.add(new AnimatedCloakData(frameIdentifier, delays.get(i)));
|
||||||
}
|
}
|
||||||
animatedCloaks.put(uuid, animatedFrames);
|
animatedCloaks.put(uuid, animatedFrames);
|
||||||
lastFrameTime.put(uuid, System.currentTimeMillis());
|
lastFrameTime.put(uuid, System.currentTimeMillis());
|
||||||
SaturnClient.LOGGER.info("Loaded " + frames.size() + " frames for animated cloak: " + fileName);
|
SaturnClient.LOGGER.info(
|
||||||
|
"Loaded " + frames.size() + " frames for animated cloak: " + fileName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
SaturnClient.LOGGER.error("Failed to register animated cloak textures: " + fileName, e);
|
SaturnClient.LOGGER
|
||||||
|
.error("Failed to register animated cloak textures: " + fileName, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
SaturnClient.LOGGER.error("Failed to load animated cloak from resources: " + player.cloak + ".gif", e);
|
SaturnClient.LOGGER
|
||||||
|
.error("Failed to load animated cloak from resources: " + player.cloak + ".gif", e);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3,12 +3,17 @@ package org.saturnclient.saturnclient.event;
|
|||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||||
import net.minecraft.client.option.KeyBinding;
|
import net.minecraft.client.option.KeyBinding;
|
||||||
// import net.minecraft.client.option.Perspective;
|
|
||||||
import net.minecraft.client.util.InputUtil;
|
import net.minecraft.client.util.InputUtil;
|
||||||
|
|
||||||
// import org.saturnclient.modules.mods.FreeLook;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.menus.ModMenu;
|
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||||
// import org.saturnclient.saturnclient.menus.SaturnMenu;
|
import org.saturnclient.saturnclient.auth.Auth;
|
||||||
|
import org.saturnclient.ui2.screens.EmoteWheel;
|
||||||
|
import org.saturnclient.ui2.screens.ShiftMenu;
|
||||||
|
|
||||||
|
import dev.kosmx.playerAnim.api.layered.AnimationStack;
|
||||||
|
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,55 +26,30 @@ public class KeyInputHandler {
|
|||||||
private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT;
|
private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT;
|
||||||
private static KeyBinding mainMenuKeyBinding;
|
private static KeyBinding mainMenuKeyBinding;
|
||||||
|
|
||||||
// private static final String FREELOOK_KEY_ID = "key.saturnclient.freelook";
|
|
||||||
// private static final int FREELOOK_KEY = GLFW.GLFW_KEY_M;
|
|
||||||
// private static KeyBinding freelookKeyBinding;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers all keybindings and their associated event handlers.
|
|
||||||
* Should be called during mod initialization.
|
|
||||||
*/
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
// Register the main menu key binding
|
|
||||||
mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||||
MAIN_MENU_KEY_ID,
|
MAIN_MENU_KEY_ID,
|
||||||
InputUtil.Type.KEYSYM,
|
InputUtil.Type.KEYSYM,
|
||||||
DEFAULT_MENU_KEY,
|
DEFAULT_MENU_KEY,
|
||||||
KEY_CATEGORY));
|
KEY_CATEGORY));
|
||||||
|
|
||||||
// freelookKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
|
||||||
// FREELOOK_KEY_ID,
|
|
||||||
// InputUtil.Type.KEYSYM,
|
|
||||||
// FREELOOK_KEY,
|
|
||||||
// KEY_CATEGORY));
|
|
||||||
|
|
||||||
// Register the event handler for the main menu key
|
// Register the event handler for the main menu key
|
||||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||||
if (mainMenuKeyBinding.wasPressed()) {
|
if (mainMenuKeyBinding.wasPressed()) {
|
||||||
client.setScreen(new ModMenu());
|
client.setScreen(new ShiftMenu());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SaturnClientConfig.openEmoteWheel.wasKeyPressed() && client.currentScreen == null) {
|
||||||
|
client.setScreen(new EmoteWheel());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking()) {
|
||||||
|
AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(SaturnClient.client.player);
|
||||||
|
if (animationStack.isActive() && animationStack.getPriority() == 1000) {
|
||||||
|
animationStack.removeLayer(1000);
|
||||||
|
Auth.emote("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// else if (freelookKeyBinding.wasPressed() && FreeLook.enabled.value && FreeLook.toggle.value) {
|
|
||||||
// FreeLook.isFreeLooking = !FreeLook.isFreeLooking;
|
|
||||||
// if (FreeLook.isFreeLooking) {
|
|
||||||
// FreeLook.lastPerspective = client.options.getPerspective();
|
|
||||||
// client.options.setPerspective(Perspective.THIRD_PERSON_BACK);
|
|
||||||
// } else if (FreeLook.lastPerspective != null) {
|
|
||||||
// client.options.setPerspective(FreeLook.lastPerspective);
|
|
||||||
// FreeLook.lastPerspective = null;
|
|
||||||
// }
|
|
||||||
// } else if (FreeLook.enabled.value && !FreeLook.toggle.value) {
|
|
||||||
// if (freelookKeyBinding.isPressed()) {
|
|
||||||
// if (!FreeLook.isFreeLooking) {
|
|
||||||
// FreeLook.lastPerspective = client.options.getPerspective();
|
|
||||||
// client.options.setPerspective(Perspective.THIRD_PERSON_BACK);
|
|
||||||
// FreeLook.isFreeLooking = true;
|
|
||||||
// }
|
|
||||||
// } else if (FreeLook.isFreeLooking && FreeLook.lastPerspective != null) {
|
|
||||||
// client.options.setPerspective(FreeLook.lastPerspective);
|
|
||||||
// FreeLook.isFreeLooking = false;
|
|
||||||
// FreeLook.lastPerspective = null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,158 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.menus;
|
|
||||||
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.auth.Auth;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import org.saturnclient.ui.components.SkinPreview;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnClickableSprite;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnImage;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnInputBox;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
|
||||||
|
|
||||||
public class CloaksMenu extends SaturnUi {
|
|
||||||
|
|
||||||
private SaturnScroll scroll;
|
|
||||||
private Property<String> search = new Property<>("");
|
|
||||||
|
|
||||||
public CloaksMenu() {
|
|
||||||
super(Text.of("Cloaks Menu"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
int rectWidth = 330;
|
|
||||||
int rectHeight = 228;
|
|
||||||
int rectX = (width - rectWidth) / 2;
|
|
||||||
int rectY = (height - rectHeight + 15) / 2;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.SETTINGS_BG)
|
|
||||||
.setX(rectX)
|
|
||||||
.setY(rectY)
|
|
||||||
.setWidth(rectWidth)
|
|
||||||
.setHeight(rectHeight)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int tabsX = (width - 43) / 2;
|
|
||||||
int tabsY = rectY - 17;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.RECT)
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY)
|
|
||||||
.setWidth(43)
|
|
||||||
.setHeight(15)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnInputBox(search, rectX + rectWidth - 72, tabsY, 70).onUpdate(() -> {
|
|
||||||
scroll.clear();
|
|
||||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
|
||||||
})
|
|
||||||
.setHeight(15)
|
|
||||||
.setWidth(72)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int tabSize = 9;
|
|
||||||
tabsX = (width - tabSize) / 2;
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.HAT, () -> {
|
|
||||||
client.setScreen(new HatsMenu());
|
|
||||||
})
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY + 4)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(7)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.CLOAK, () -> {
|
|
||||||
})
|
|
||||||
.setSelected(true)
|
|
||||||
.setX(tabsX - 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
|
||||||
System.out.println("Pressed");
|
|
||||||
})
|
|
||||||
.setX(tabsX + 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
scroll = new SaturnScroll();
|
|
||||||
|
|
||||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
|
||||||
|
|
||||||
draw(scroll
|
|
||||||
.setX(rectX + 17)
|
|
||||||
.setY(rectY + 10)
|
|
||||||
.setWidth(rectWidth - 17)
|
|
||||||
.setHeight(rectHeight - 10)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(new SkinPreview()
|
|
||||||
.setScale(3.0f)
|
|
||||||
.setX((rectX + rectWidth) - 180)
|
|
||||||
.setY(rectY + 8)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
super.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawItems(int rectX, int rectY, int rectWidth, int rectHeight) {
|
|
||||||
int cloakWidth = 28;
|
|
||||||
int cloakHeight = 61;
|
|
||||||
|
|
||||||
int modX = 0;
|
|
||||||
int modY = 0;
|
|
||||||
int col = 0;
|
|
||||||
|
|
||||||
String[] searchTokens = search.value.toLowerCase().split("\\ ");
|
|
||||||
|
|
||||||
outer: for (String cloak : Cloaks.availableCloaks) {
|
|
||||||
for (String searchToken : searchTokens) {
|
|
||||||
if (!cloak.contains(searchToken)) {
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scroll.draw(
|
|
||||||
new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> {
|
|
||||||
Cloaks.setCloak(Auth.uuid, cloak);
|
|
||||||
})
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setWidth(cloakWidth + 6)
|
|
||||||
.setHeight(cloakHeight + 6));
|
|
||||||
|
|
||||||
scroll.draw(
|
|
||||||
new SaturnImage(Textures.getCloakPreview(cloak))
|
|
||||||
.setX(modX + 3)
|
|
||||||
.setY(modY + 3)
|
|
||||||
.setWidth(cloakWidth)
|
|
||||||
.setHeight(cloakHeight));
|
|
||||||
|
|
||||||
col++;
|
|
||||||
|
|
||||||
if (col < 4) {
|
|
||||||
modX += cloakWidth + 21;
|
|
||||||
} else {
|
|
||||||
modX = 0;
|
|
||||||
modY += cloakHeight + 20;
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,234 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.menus;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import org.saturnclient.ui.components.SaturnFloat;
|
|
||||||
import org.saturnclient.ui.components.SaturnHex;
|
|
||||||
import org.saturnclient.ui.components.SaturnInteger;
|
|
||||||
import org.saturnclient.ui.components.SaturnString;
|
|
||||||
import org.saturnclient.ui.components.SaturnToggle;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnImageButton;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnText;
|
|
||||||
|
|
||||||
public class ConfigEditor extends SaturnUi {
|
|
||||||
|
|
||||||
private ConfigManager config;
|
|
||||||
|
|
||||||
public ConfigEditor(ConfigManager config) {
|
|
||||||
super(Text.of("Config editor"));
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
int rectWidth = 330;
|
|
||||||
int rectHeight = 228;
|
|
||||||
int rectX = (width - rectWidth) / 2;
|
|
||||||
int rectY = (height - rectHeight + 15) / 2;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.SETTINGS_BG)
|
|
||||||
.setX(rectX)
|
|
||||||
.setY(rectY)
|
|
||||||
.setWidth(rectWidth)
|
|
||||||
.setHeight(rectHeight)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnImageButton(Textures.CLOSE, 9, 9, () -> {
|
|
||||||
this.close();
|
|
||||||
})
|
|
||||||
.setX(rectX)
|
|
||||||
.setY(rectY - 15)
|
|
||||||
.setWidth(13)
|
|
||||||
.setHeight(13)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
SaturnScroll configScroll = new SaturnScroll();
|
|
||||||
|
|
||||||
int row = 0;
|
|
||||||
int col = 0;
|
|
||||||
|
|
||||||
drawProperties(configScroll, config.getProperties(), rectWidth, row, col);
|
|
||||||
|
|
||||||
draw(
|
|
||||||
configScroll
|
|
||||||
.setX(rectX + 17)
|
|
||||||
.setY(rectY + 10)
|
|
||||||
.setWidth(rectWidth - 17)
|
|
||||||
.setHeight(rectHeight - 10)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
super.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private int drawProperties(SaturnScroll configScroll, Map<String, Property<?>> properties, int rectWidth,
|
|
||||||
int row, int col) {
|
|
||||||
int totalRows = row;
|
|
||||||
for (Map.Entry<String, Property<?>> propEntry : properties.entrySet()) {
|
|
||||||
Property<?> prop = propEntry.getValue();
|
|
||||||
String propName = propEntry.getKey();
|
|
||||||
|
|
||||||
boolean full = isFull(prop);
|
|
||||||
|
|
||||||
if (full && col > 0) {
|
|
||||||
col = 0;
|
|
||||||
totalRows++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int modX = ((rectWidth / 2) - 17) * col;
|
|
||||||
int modY = 14 * totalRows;
|
|
||||||
|
|
||||||
switch (prop.getType()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnToggle((Property<Boolean>) prop)
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY));
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnText(
|
|
||||||
propName.substring(0, 1).toUpperCase() +
|
|
||||||
propName.substring(1))
|
|
||||||
.setX(modX + 18)
|
|
||||||
.setY(modY)
|
|
||||||
.setScale(0.8f));
|
|
||||||
break;
|
|
||||||
case INTEGER:
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnText(
|
|
||||||
propName.substring(0, 1).toUpperCase() +
|
|
||||||
propName.substring(1))
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setScale(0.8f));
|
|
||||||
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnInteger(
|
|
||||||
(Property<Integer>) prop,
|
|
||||||
(rectWidth / 2) - 17,
|
|
||||||
modY,
|
|
||||||
70));
|
|
||||||
|
|
||||||
configScroll.draw(resetButton(prop, modX, modY));
|
|
||||||
break;
|
|
||||||
case FLOAT:
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnText(
|
|
||||||
propName.substring(0, 1).toUpperCase() +
|
|
||||||
propName.substring(1))
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setScale(0.8f));
|
|
||||||
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnFloat(
|
|
||||||
(Property<Float>) prop,
|
|
||||||
(rectWidth / 2) - 17,
|
|
||||||
modY,
|
|
||||||
70));
|
|
||||||
|
|
||||||
configScroll.draw(resetButton(prop, modX, modY));
|
|
||||||
break;
|
|
||||||
case STRING:
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnText(
|
|
||||||
propName.substring(0, 1).toUpperCase() +
|
|
||||||
propName.substring(1))
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setScale(0.8f));
|
|
||||||
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnString(
|
|
||||||
(Property<String>) prop,
|
|
||||||
(rectWidth / 2) - 17,
|
|
||||||
modY,
|
|
||||||
70));
|
|
||||||
|
|
||||||
configScroll.draw(resetButton(prop, modX, modY));
|
|
||||||
break;
|
|
||||||
case HEX:
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnText(
|
|
||||||
propName.substring(0, 1).toUpperCase() +
|
|
||||||
propName.substring(1))
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setScale(0.8f));
|
|
||||||
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnHex(
|
|
||||||
(Property<Integer>) prop,
|
|
||||||
(rectWidth / 2) - 17,
|
|
||||||
modY,
|
|
||||||
70));
|
|
||||||
|
|
||||||
configScroll.draw(resetButton(prop, modX, modY));
|
|
||||||
break;
|
|
||||||
case NAMESPACE:
|
|
||||||
configScroll.draw(
|
|
||||||
new SaturnText(
|
|
||||||
propName.substring(0, 1).toUpperCase() +
|
|
||||||
propName.substring(1))
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setScale(0.8f));
|
|
||||||
|
|
||||||
// Recursively draw nested properties and update total rows
|
|
||||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) prop.value;
|
|
||||||
totalRows = drawProperties(configScroll, nestedProperties, rectWidth,
|
|
||||||
totalRows + 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (full) {
|
|
||||||
totalRows++;
|
|
||||||
} else {
|
|
||||||
col++;
|
|
||||||
if (col > 1) {
|
|
||||||
col = 0;
|
|
||||||
totalRows++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalRows;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFull(Property<?> prop) {
|
|
||||||
switch (prop.getType()) {
|
|
||||||
case BOOLEAN:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
ConfigManager.save();
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget resetButton(Property<?> prop, int modX, int modY) {
|
|
||||||
int size = textRenderer.fontHeight - 1;
|
|
||||||
return new SaturnImageButton(
|
|
||||||
Textures.RESET,
|
|
||||||
size,
|
|
||||||
size,
|
|
||||||
() -> {
|
|
||||||
prop.reset();
|
|
||||||
})
|
|
||||||
.setX(modX + 209)
|
|
||||||
.setY(modY)
|
|
||||||
.setWidth(size + 3)
|
|
||||||
.setHeight(size + 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.menus;
|
|
||||||
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.auth.Auth;
|
|
||||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import org.saturnclient.ui.components.SkinPreview;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnClickableSprite;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnImage;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
|
||||||
|
|
||||||
public class HatsMenu extends SaturnUi {
|
|
||||||
|
|
||||||
public HatsMenu() {
|
|
||||||
super(Text.of("Hats Menu"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
int rectWidth = 330;
|
|
||||||
int rectHeight = 228;
|
|
||||||
int rectX = (width - rectWidth) / 2;
|
|
||||||
int rectY = (height - rectHeight + 15) / 2;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.SETTINGS_BG)
|
|
||||||
.setX(rectX)
|
|
||||||
.setY(rectY)
|
|
||||||
.setWidth(rectWidth)
|
|
||||||
.setHeight(rectHeight)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int tabsX = (width - 43) / 2;
|
|
||||||
int tabsY = rectY - 17;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.RECT)
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY)
|
|
||||||
.setWidth(43)
|
|
||||||
.setHeight(15)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int tabSize = 9;
|
|
||||||
tabsX = (width - tabSize) / 2;
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.HAT, () -> {
|
|
||||||
client.setScreen(new HatsMenu());
|
|
||||||
})
|
|
||||||
.setSelected(true)
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY + 4)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(7)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.CLOAK, () -> {
|
|
||||||
client.setScreen(new CloaksMenu());
|
|
||||||
})
|
|
||||||
.setX(tabsX - 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
|
||||||
System.out.println("Pressed");
|
|
||||||
})
|
|
||||||
.setX(tabsX + 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int hatSize = 28;
|
|
||||||
|
|
||||||
int modX = 0;
|
|
||||||
int modY = 0;
|
|
||||||
int col = 0;
|
|
||||||
|
|
||||||
SaturnScroll modsScroll = new SaturnScroll();
|
|
||||||
|
|
||||||
for (String hat : Hats.availableHats) {
|
|
||||||
modsScroll.draw(
|
|
||||||
new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> {
|
|
||||||
Hats.setHat(Auth.uuid, hat);
|
|
||||||
})
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setWidth(hatSize + 6)
|
|
||||||
.setHeight(hatSize + 6));
|
|
||||||
|
|
||||||
modsScroll.draw(
|
|
||||||
new SaturnImage(Textures.getHatPreview(hat))
|
|
||||||
.setX(modX + 3)
|
|
||||||
.setY(modY + 3)
|
|
||||||
.setWidth(hatSize)
|
|
||||||
.setHeight(hatSize));
|
|
||||||
|
|
||||||
col++;
|
|
||||||
|
|
||||||
if (col < 4) {
|
|
||||||
modX += hatSize + 21;
|
|
||||||
} else {
|
|
||||||
modX = 0;
|
|
||||||
modY += hatSize + 20;
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw(
|
|
||||||
modsScroll
|
|
||||||
.setX(rectX + 17)
|
|
||||||
.setY(rectY + 10)
|
|
||||||
.setWidth(rectWidth - 17)
|
|
||||||
.setHeight(rectHeight - 10)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(new SkinPreview()
|
|
||||||
.setScale(3.0f)
|
|
||||||
.setX((rectX + rectWidth) - 180)
|
|
||||||
.setY(rectY + 8)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
super.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,9 @@ import org.saturnclient.modules.ModDimensions;
|
|||||||
import org.saturnclient.modules.ModManager;
|
import org.saturnclient.modules.ModManager;
|
||||||
import org.saturnclient.modules.Module;
|
import org.saturnclient.modules.Module;
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
import org.saturnclient.ui.SaturnUi;
|
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -90,9 +92,11 @@ public class HudEditor extends Screen {
|
|||||||
@Override
|
@Override
|
||||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||||
if (client.world == null && client.getCurrentServerEntry() == null) {
|
if (client.world == null && client.getCurrentServerEntry() == null) {
|
||||||
SaturnUi.ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta);
|
SaturnScreen.ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderScope scope = new RenderScope(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers());
|
||||||
|
|
||||||
for (HudMod mod : hudMods) {
|
for (HudMod mod : hudMods) {
|
||||||
ModDimensions dim = mod.getDimensions();
|
ModDimensions dim = mod.getDimensions();
|
||||||
MatrixStack matrices = context.getMatrices();
|
MatrixStack matrices = context.getMatrices();
|
||||||
@@ -102,7 +106,7 @@ public class HudEditor extends Screen {
|
|||||||
matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
||||||
|
|
||||||
// Render the mod
|
// Render the mod
|
||||||
mod.renderDummy(context);
|
mod.renderDummy(scope);
|
||||||
|
|
||||||
matrices.pop();
|
matrices.pop();
|
||||||
|
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.menus;
|
|
||||||
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.ModManager;
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import org.saturnclient.ui.components.SaturnModComp;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnInputBox;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
|
||||||
|
|
||||||
public class ModMenu extends SaturnUi {
|
|
||||||
|
|
||||||
private SaturnScroll scroll;
|
|
||||||
private Property<String> search = new Property<>("");
|
|
||||||
|
|
||||||
public ModMenu() {
|
|
||||||
super(Text.literal("Mods"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
int rectWidth = 330;
|
|
||||||
int rectHeight = 228;
|
|
||||||
int rectX = (width - rectWidth) / 2;
|
|
||||||
int rectY = (height - rectHeight + 15) / 2;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.SETTINGS_BG)
|
|
||||||
.setX(rectX)
|
|
||||||
.setY(rectY)
|
|
||||||
.setWidth(rectWidth)
|
|
||||||
.setHeight(rectHeight)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int tabsX = (width - 43) / 2;
|
|
||||||
int tabsY = rectY - 17;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.RECT)
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY)
|
|
||||||
.setWidth(43)
|
|
||||||
.setHeight(15)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnInputBox(search, rectX + rectWidth - 72, tabsY, 70).onUpdate(() -> {
|
|
||||||
scroll.clear();
|
|
||||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
|
||||||
})
|
|
||||||
.setHeight(15)
|
|
||||||
.setWidth(72)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int tabSize = 9;
|
|
||||||
tabsX = (width - tabSize) / 2;
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.SETTINGS, () -> {
|
|
||||||
client.setScreen(new SaturnConfigEditor());
|
|
||||||
})
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.MODS_TAB, () -> {
|
|
||||||
})
|
|
||||||
.setSelected(true)
|
|
||||||
.setX(tabsX - 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
|
||||||
System.out.println("Pressed");
|
|
||||||
})
|
|
||||||
.setX(tabsX + 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
scroll = new SaturnScroll();
|
|
||||||
|
|
||||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
|
||||||
|
|
||||||
draw(scroll
|
|
||||||
.setX(rectX + 17)
|
|
||||||
.setY(rectY + 10)
|
|
||||||
.setWidth(rectWidth - 17)
|
|
||||||
.setHeight(rectHeight - 20)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
super.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
ConfigManager.save();
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawItems(int rectX, int rectY, int rectWidth, int rectHeight) {
|
|
||||||
int modX = 0;
|
|
||||||
int modY = 0;
|
|
||||||
int col = 0;
|
|
||||||
|
|
||||||
String[] searchTokens = search.value.toLowerCase().split("\\ ");
|
|
||||||
|
|
||||||
outer: for (Module mod : ModManager.MODS) {
|
|
||||||
String modName = mod.getName().toLowerCase();
|
|
||||||
for (String searchToken : searchTokens) {
|
|
||||||
if (!modName.contains(searchToken)) {
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scroll.draw(
|
|
||||||
new SaturnModComp(mod)
|
|
||||||
.setX(modX)
|
|
||||||
.setY(modY)
|
|
||||||
.setWidth(86)
|
|
||||||
.setHeight(20));
|
|
||||||
|
|
||||||
col++;
|
|
||||||
|
|
||||||
if (col < 3) {
|
|
||||||
modX += 86 + 18;
|
|
||||||
} else {
|
|
||||||
modX = 0;
|
|
||||||
modY += 20 + 20;
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.menus;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
|
||||||
|
|
||||||
public class SaturnConfigEditor extends ConfigEditor {
|
|
||||||
|
|
||||||
public SaturnConfigEditor() {
|
|
||||||
super(SaturnClientConfig.config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
int rectHeight = 228;
|
|
||||||
int rectY = (height - rectHeight + 15) / 2;
|
|
||||||
|
|
||||||
int tabsX = (width - 43) / 2;
|
|
||||||
int tabsY = rectY - 17;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnSprite(Textures.RECT)
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY)
|
|
||||||
.setWidth(43)
|
|
||||||
.setHeight(15)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
int tabSize = 9;
|
|
||||||
tabsX = (width - tabSize) / 2;
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.SETTINGS, () -> {
|
|
||||||
})
|
|
||||||
.setSelected(true)
|
|
||||||
.setX(tabsX)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.MODS_TAB, () -> {
|
|
||||||
client.setScreen(new ModMenu());
|
|
||||||
})
|
|
||||||
.setX(tabsX - 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
|
||||||
System.out.println("Pressed");
|
|
||||||
})
|
|
||||||
.setX(tabsX + 12)
|
|
||||||
.setY(tabsY + 3)
|
|
||||||
.setWidth(tabSize)
|
|
||||||
.setHeight(tabSize)
|
|
||||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
|
||||||
|
|
||||||
super.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.menus;
|
|
||||||
|
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
|
||||||
|
|
||||||
public class SaturnMenu extends SaturnScreen {
|
|
||||||
public SaturnMenu() {
|
|
||||||
super("Saturn Client");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ui() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.menus;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import org.saturnclient.ui.animations.FadeIn;
|
|
||||||
import org.saturnclient.ui.animations.Slide;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnButton;
|
|
||||||
import org.saturnclient.ui.widgets.SaturnImage;
|
|
||||||
import org.saturnclient.ui2.screens.ShiftMenu;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
|
||||||
import net.minecraft.client.gui.screen.option.OptionsScreen;
|
|
||||||
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
|
|
||||||
public class SaturnTitleScreen extends SaturnUi {
|
|
||||||
public SaturnTitleScreen() {
|
|
||||||
super(Text.literal("Title Screen"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
blur = false;
|
|
||||||
|
|
||||||
int logoSize = 49;
|
|
||||||
int bX = (width - 150) / 2;
|
|
||||||
int bY = height / 2 - logoSize - 27;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnImage(SaturnClientConfig.getLogo())
|
|
||||||
.setX((width - logoSize) / 2)
|
|
||||||
.setY(bY)
|
|
||||||
.setWidth(logoSize)
|
|
||||||
.setHeight(logoSize)
|
|
||||||
.setAnimations(new Slide(3, 14)));
|
|
||||||
|
|
||||||
bY += 44;
|
|
||||||
|
|
||||||
draw(
|
|
||||||
new SaturnImage(Textures.LOGO_TEXT)
|
|
||||||
.setX((width - logoSize) / 2)
|
|
||||||
.setY(bY)
|
|
||||||
.setWidth(logoSize)
|
|
||||||
.setHeight(8)
|
|
||||||
.setAnimations(new FadeIn(3)));
|
|
||||||
|
|
||||||
bY += 15;
|
|
||||||
|
|
||||||
draw(new SaturnButton("SINGLEPLAYER", () -> {
|
|
||||||
client.setScreen(new SelectWorldScreen(new SaturnTitleScreen()));
|
|
||||||
}).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
|
||||||
|
|
||||||
bY += 20;
|
|
||||||
|
|
||||||
draw(new SaturnButton("MULTIPLAYER", () -> {
|
|
||||||
client.setScreen(new MultiplayerScreen(new SaturnTitleScreen()));
|
|
||||||
}).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
|
||||||
|
|
||||||
bY += 20;
|
|
||||||
|
|
||||||
draw(new SaturnButton("OPTIONS", () -> {
|
|
||||||
client.setScreen(new OptionsScreen(new SaturnTitleScreen(), this.client.options));
|
|
||||||
}).setBold(true).setWidth(103).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
|
||||||
|
|
||||||
draw(new SaturnButton("QUIT", () -> {
|
|
||||||
client.scheduleStop();
|
|
||||||
}).setBold(true).setWidth(103).setHeight(26).setX(bX + 74).setY(bY).setScale(0.69f));
|
|
||||||
|
|
||||||
bY += 20;
|
|
||||||
|
|
||||||
draw(new SaturnButton("SATURN OPTIONS", () -> {
|
|
||||||
client.setScreen(new ShiftMenu());
|
|
||||||
}).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
|
||||||
|
|
||||||
super.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.mixin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.saturnclient.saturnclient.auth.Auth;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.hud.ChatHud;
|
|
||||||
import net.minecraft.client.gui.hud.MessageIndicator;
|
|
||||||
import net.minecraft.network.message.MessageSignatureData;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
|
|
||||||
@Mixin(ChatHud.class)
|
|
||||||
public class SaturnReload {
|
|
||||||
@Inject(method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", at = @At("HEAD"), cancellable = true)
|
|
||||||
public void onAddMessage(Text message, @Nullable MessageSignatureData signatureData,
|
|
||||||
@Nullable MessageIndicator indicator, CallbackInfo ci) {
|
|
||||||
String msg = message.toString();
|
|
||||||
if (msg.contains("$SATURN_RELOAD")) {
|
|
||||||
for (Map.Entry<String, String> player : Auth.playerNames.entrySet()) {
|
|
||||||
String name = player.getKey();
|
|
||||||
if (msg.contains(name)) {
|
|
||||||
Auth.player(name, player.getValue());
|
|
||||||
}
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.saturnclient.saturnclient.mixin;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||||
|
import org.saturnclient.ui2.screens.TitleMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screen.TitleScreen;
|
||||||
|
|
||||||
|
@Mixin(TitleScreen.class)
|
||||||
|
public class TitleScreenMixin {
|
||||||
|
@Inject(method = "init", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onInit(CallbackInfo ci) {
|
||||||
|
if (SaturnClientConfig.saturnTitleScreen.value) {
|
||||||
|
SaturnClient.client.setScreen(new TitleMenu());
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
public class SaturnAnimation {
|
|
||||||
|
|
||||||
public int delay = 0;
|
|
||||||
public int lastTick = 0;
|
|
||||||
|
|
||||||
public void init(SaturnWidget widget) {}
|
|
||||||
|
|
||||||
public boolean run(SaturnWidget widget, int tick) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,322 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.gl.PostEffectProcessor;
|
|
||||||
import net.minecraft.client.gui.CubeMapRenderer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.client.gui.RotatingCubeMapRenderer;
|
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
|
||||||
import net.minecraft.client.render.DefaultFramebufferSet;
|
|
||||||
import net.minecraft.client.render.RenderLayer;
|
|
||||||
import net.minecraft.client.util.Pool;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
import net.minecraft.text.MutableText;
|
|
||||||
import net.minecraft.text.Style;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
|
|
||||||
public class SaturnUi extends Screen {
|
|
||||||
|
|
||||||
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
|
||||||
|
|
||||||
private final Pool pool = new Pool(3);
|
|
||||||
private float f = 0.0f;
|
|
||||||
public boolean blur = true;
|
|
||||||
public boolean titleBackground = false;
|
|
||||||
public List<SaturnWidget> widgets = new ArrayList<>();
|
|
||||||
private int tick = 0;
|
|
||||||
|
|
||||||
protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(
|
|
||||||
Identifier.of("saturnclient", "textures/gui/title/background/panorama"));
|
|
||||||
|
|
||||||
public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER;
|
|
||||||
|
|
||||||
static {
|
|
||||||
ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MutableText text(String text) {
|
|
||||||
return Text.literal(text).setStyle(
|
|
||||||
Style.EMPTY.withFont(Identifier.of("saturnclient:panton")));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MutableText textBold(String text) {
|
|
||||||
return Text.literal(text).setStyle(
|
|
||||||
Style.EMPTY.withFont(Identifier.of("saturnclient:panton_bold")));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void drawHighResTexture(DrawContext context, Identifier t, int x, int y, int w, int h) {
|
|
||||||
MatrixStack matricies = context.getMatrices();
|
|
||||||
matricies.push();
|
|
||||||
matricies.translate(x, y, 0);
|
|
||||||
matricies.scale(.25f, .25f, 1.0f);
|
|
||||||
|
|
||||||
context.drawTexture(RenderLayer::getGuiTextured, t, 0, 0, 0, 0,
|
|
||||||
w * 4, h * 4, w * 4, h * 4);
|
|
||||||
|
|
||||||
matricies.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void drawHighResTexture(DrawContext context, Identifier t, int x, int y, int w, int h, int c) {
|
|
||||||
MatrixStack matricies = context.getMatrices();
|
|
||||||
matricies.push();
|
|
||||||
matricies.translate(x, y, 0);
|
|
||||||
matricies.scale(.25f, .25f, 1.0f);
|
|
||||||
|
|
||||||
context.drawTexture(RenderLayer::getGuiTextured, t, 0, 0, 0, 0,
|
|
||||||
w * 4, h * 4, w * 4, h * 4, c);
|
|
||||||
|
|
||||||
matricies.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void drawHighResGuiTexture(DrawContext context, Identifier t, int x, int y, int w, int h, int c) {
|
|
||||||
MatrixStack matricies = context.getMatrices();
|
|
||||||
matricies.push();
|
|
||||||
matricies.translate(x, y, 0);
|
|
||||||
matricies.scale(.25f, .25f, 1.0f);
|
|
||||||
|
|
||||||
context.drawGuiTexture(
|
|
||||||
RenderLayer::getGuiTextured,
|
|
||||||
t,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
w * 4,
|
|
||||||
h * 4,
|
|
||||||
c);
|
|
||||||
|
|
||||||
matricies.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getAlpha(int color, float alpha) {
|
|
||||||
return ((int) (alpha * 255) << 24) |
|
|
||||||
(color & 0x00FFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnUi(Text title) {
|
|
||||||
super(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
scheduler.scheduleAtFixedRate(
|
|
||||||
this::saturnTick,
|
|
||||||
0,
|
|
||||||
7,
|
|
||||||
TimeUnit.MILLISECONDS);
|
|
||||||
super.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(SaturnWidget widget) {
|
|
||||||
synchronized (widgets) {
|
|
||||||
widget.init();
|
|
||||||
widgets.add(widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh() {
|
|
||||||
synchronized (widgets) {
|
|
||||||
widgets.clear();
|
|
||||||
|
|
||||||
f = 0.0f;
|
|
||||||
tick = 0;
|
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY,
|
|
||||||
float delta) {
|
|
||||||
|
|
||||||
if (client.world == null && client.getCurrentServerEntry() == null) {
|
|
||||||
ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blur
|
|
||||||
if (!(f < 1.0F) && blur) {
|
|
||||||
PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect(
|
|
||||||
Identifier.ofVanilla("blur"),
|
|
||||||
DefaultFramebufferSet.MAIN_ONLY);
|
|
||||||
if (postEffectProcessor != null) {
|
|
||||||
postEffectProcessor.setUniforms("Radius", f);
|
|
||||||
postEffectProcessor.render(this.client.getFramebuffer(), this.pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
|
||||||
if (!widget.visible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
double adjustedMouseX = mouseX - widget.x;
|
|
||||||
double adjustedMouseY = mouseY - widget.y;
|
|
||||||
boolean isMouseInside = adjustedMouseX >= 0 &&
|
|
||||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
|
||||||
adjustedMouseY >= 0 &&
|
|
||||||
adjustedMouseY <= (widget.height * widget.scale);
|
|
||||||
|
|
||||||
MatrixStack matrices = context.getMatrices();
|
|
||||||
matrices.push();
|
|
||||||
matrices.translate(widget.x, widget.y, 0);
|
|
||||||
matrices.scale(widget.scale, widget.scale, 1.0f);
|
|
||||||
widget.render(
|
|
||||||
context,
|
|
||||||
isMouseInside,
|
|
||||||
(int) (adjustedMouseX / widget.scale),
|
|
||||||
(int) (adjustedMouseY / widget.scale));
|
|
||||||
matrices.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
|
||||||
if (button == 0) {
|
|
||||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
|
||||||
widget.focused = false;
|
|
||||||
if (!widget.visible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
double adjustedMouseX = mouseX - widget.x;
|
|
||||||
double adjustedMouseY = mouseY - widget.y;
|
|
||||||
boolean isMouseInside = adjustedMouseX >= 0 &&
|
|
||||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
|
||||||
adjustedMouseY >= 0 &&
|
|
||||||
adjustedMouseY <= (widget.height * widget.scale);
|
|
||||||
|
|
||||||
if (isMouseInside) {
|
|
||||||
widget.focused = true;
|
|
||||||
widget.click(
|
|
||||||
(int) (adjustedMouseX / widget.scale),
|
|
||||||
(int) (adjustedMouseY / widget.scale));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
|
||||||
if (!widget.visible && !widget.focused)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
widget.keyPressed(keyCode, scanCode, modifiers);
|
|
||||||
|
|
||||||
char typedChar = getCharFromKey(keyCode, modifiers);
|
|
||||||
if (typedChar != '\0') {
|
|
||||||
widget.charTyped(typedChar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mouseScrolled(
|
|
||||||
double mouseX,
|
|
||||||
double mouseY,
|
|
||||||
double horizontalAmount,
|
|
||||||
double verticalAmount) {
|
|
||||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
|
||||||
double adjustedMouseX = mouseX - widget.x;
|
|
||||||
double adjustedMouseY = mouseY - widget.y;
|
|
||||||
boolean isMouseInside = adjustedMouseX >= 0 &&
|
|
||||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
|
||||||
adjustedMouseY >= 0 &&
|
|
||||||
adjustedMouseY <= (widget.height * widget.scale);
|
|
||||||
|
|
||||||
if (isMouseInside) {
|
|
||||||
widget.mouseScrolled(
|
|
||||||
(int) (adjustedMouseX / widget.scale),
|
|
||||||
(int) (adjustedMouseY / widget.scale),
|
|
||||||
horizontalAmount,
|
|
||||||
verticalAmount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.mouseScrolled(
|
|
||||||
mouseX,
|
|
||||||
mouseY,
|
|
||||||
horizontalAmount,
|
|
||||||
verticalAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private char getCharFromKey(int keyCode, int modifiers) {
|
|
||||||
boolean shift = (modifiers & GLFW.GLFW_MOD_SHIFT) != 0;
|
|
||||||
|
|
||||||
// A-Z
|
|
||||||
if (keyCode >= GLFW.GLFW_KEY_A && keyCode <= GLFW.GLFW_KEY_Z) {
|
|
||||||
return (char) (shift
|
|
||||||
? 'A' + (keyCode - GLFW.GLFW_KEY_A)
|
|
||||||
: 'a' + (keyCode - GLFW.GLFW_KEY_A));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0-9
|
|
||||||
if (keyCode >= GLFW.GLFW_KEY_0 && keyCode <= GLFW.GLFW_KEY_9) {
|
|
||||||
return shift
|
|
||||||
? ")!@#$%^&*(".charAt(keyCode - GLFW.GLFW_KEY_0)
|
|
||||||
: (char) ('0' + (keyCode - GLFW.GLFW_KEY_0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special characters
|
|
||||||
return switch (keyCode) {
|
|
||||||
case GLFW.GLFW_KEY_SPACE -> ' ';
|
|
||||||
case GLFW.GLFW_KEY_PERIOD -> shift ? '>' : '.';
|
|
||||||
case GLFW.GLFW_KEY_COMMA -> shift ? '<' : ',';
|
|
||||||
case GLFW.GLFW_KEY_MINUS -> shift ? '_' : '-';
|
|
||||||
case GLFW.GLFW_KEY_EQUAL -> shift ? '+' : '=';
|
|
||||||
case GLFW.GLFW_KEY_SEMICOLON -> shift ? ':' : ';';
|
|
||||||
case GLFW.GLFW_KEY_APOSTROPHE -> shift ? '"' : '\'';
|
|
||||||
case GLFW.GLFW_KEY_SLASH -> shift ? '?' : '/';
|
|
||||||
case GLFW.GLFW_KEY_BACKSLASH -> shift ? '|' : '\\';
|
|
||||||
case GLFW.GLFW_KEY_LEFT_BRACKET -> shift ? '{' : '[';
|
|
||||||
case GLFW.GLFW_KEY_RIGHT_BRACKET -> shift ? '}' : ']';
|
|
||||||
case GLFW.GLFW_KEY_GRAVE_ACCENT -> shift ? '~' : '`';
|
|
||||||
default -> '\0';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saturnTick() {
|
|
||||||
synchronized (scheduler) {
|
|
||||||
if (f < 15.0f) {
|
|
||||||
f += 0.25f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
synchronized (widgets) {
|
|
||||||
for (SaturnWidget widget : widgets) {
|
|
||||||
if (widget.visible && widget.animations != null) {
|
|
||||||
for (SaturnAnimation animation : widget.animations) {
|
|
||||||
if (animation != null &&
|
|
||||||
tick - animation.lastTick == animation.delay) {
|
|
||||||
if (animation.run(widget, tick)) {
|
|
||||||
animation = null;
|
|
||||||
} else {
|
|
||||||
animation.lastTick = tick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.tick();
|
|
||||||
}
|
|
||||||
tick++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resize(MinecraftClient client, int width, int height) {
|
|
||||||
super.resize(client, width, height);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
|
|
||||||
public class SaturnWidget {
|
|
||||||
|
|
||||||
public int x = 0;
|
|
||||||
public int y = 0;
|
|
||||||
public int width = 0;
|
|
||||||
public int height = 0;
|
|
||||||
public float alpha = 1.0f;
|
|
||||||
public float scale = 1.0f;
|
|
||||||
public SaturnAnimation[] animations = null;
|
|
||||||
public boolean visible = true;
|
|
||||||
public boolean focused = false;
|
|
||||||
|
|
||||||
public void init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void charTyped(char typedChar) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseScrolled(
|
|
||||||
int mouseX,
|
|
||||||
int mouseY,
|
|
||||||
double horizontalAmount,
|
|
||||||
double verticalAmount) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setX(int x) {
|
|
||||||
this.x = x;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setY(int y) {
|
|
||||||
this.y = y;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setWidth(int width) {
|
|
||||||
this.width = width;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setHeight(int height) {
|
|
||||||
this.height = height;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setAlpha(float alpha) {
|
|
||||||
this.alpha = alpha;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setAnimations(SaturnAnimation... animations) {
|
|
||||||
this.animations = animations;
|
|
||||||
for (SaturnAnimation anim : this.animations) {
|
|
||||||
anim.init(this);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setVisible(boolean visible) {
|
|
||||||
this.visible = visible;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setScale(float scale) {
|
|
||||||
this.scale = scale;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package org.saturnclient.ui;
|
|
||||||
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
public class Textures {
|
|
||||||
public static final Identifier COSMETICS = Identifier.of("saturnclient", "textures/gui/components/cosmetics.png");
|
|
||||||
public static final Identifier HUD_ICON = Identifier.of("saturnclient", "textures/gui/components/hud.png");
|
|
||||||
public static final Identifier SEARCH = Identifier.of("saturnclient", "textures/gui/components/search.png");
|
|
||||||
public static final Identifier CLOSE = Identifier.of("saturnclient", "textures/gui/components/close.png");
|
|
||||||
public static final Identifier MODS_TAB = Identifier.of("saturnclient", "textures/gui/components/mods_tab.png");
|
|
||||||
public static final Identifier SETTINGS = Identifier.of("saturnclient", "textures/gui/components/settings.png");
|
|
||||||
public static final Identifier CLOAK = Identifier.of("saturnclient", "textures/gui/components/cloak.png");
|
|
||||||
public static final Identifier HAT = Identifier.of("saturnclient", "textures/gui/components/hat.png");
|
|
||||||
public static final Identifier RESET = Identifier.of("saturnclient", "textures/gui/components/reset.png");
|
|
||||||
public static final Identifier TOGGLE_INDICATOR = Identifier.of("saturnclient",
|
|
||||||
"textures/gui/components/toggle_indicator.png");
|
|
||||||
public static final Identifier TOGGLE_BG = Identifier.of("saturnclient", "textures/gui/components/toggle_bg.png");
|
|
||||||
|
|
||||||
public static final Identifier LOGO = Identifier.of("saturnclient", "textures/logo/logo.png");
|
|
||||||
public static final Identifier REALISTIC_LOGO = Identifier.of("saturnclient", "textures/logo/realistic.png");
|
|
||||||
public static final Identifier LOGO_TEXT = Identifier.of("saturnclient", "textures/logo/text.png");
|
|
||||||
|
|
||||||
// Widgets
|
|
||||||
public static final Identifier BUTTON_BORDER = Identifier.of("saturnclient", "button_border");
|
|
||||||
public static final Identifier BUTTON = Identifier.of("saturnclient", "button");
|
|
||||||
public static final Identifier BUTTON_OP = Identifier.of("saturnclient", "button_op");
|
|
||||||
public static final Identifier SETTINGS_BG = Identifier.of("saturnclient", "settings_bg");
|
|
||||||
public static final Identifier RECT = Identifier.of("saturnclient", "rect");
|
|
||||||
public static final Identifier RECT_BORDER = Identifier.of("saturnclient", "rect_border");
|
|
||||||
public static final Identifier MOD = Identifier.of("saturnclient", "textures/gui/components/mod.png");
|
|
||||||
public static final Identifier MOD_BG = Identifier.of("saturnclient", "textures/gui/components/mod_bg.png");
|
|
||||||
|
|
||||||
public static Identifier getCloakPreview(String cloak) {
|
|
||||||
return Identifier.of("saturnclient", "textures/gui/cloak/" + (cloak.isEmpty() ? "none" : cloak) + ".png");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Identifier getHatPreview(String hat) {
|
|
||||||
return Identifier.of("saturnclient", "textures/gui/hat/" + (hat.isEmpty() ? "none" : hat) + ".png");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Identifier getModIcon(String modId) {
|
|
||||||
return Identifier.of("saturnclient", "textures/gui/mod/" + modId + ".png");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.saturnclient.ui.animations;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.SaturnAnimation;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class FadeIn extends SaturnAnimation {
|
|
||||||
public FadeIn(int delay) {
|
|
||||||
this.delay = delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(SaturnWidget widget) {
|
|
||||||
widget.alpha = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean run(SaturnWidget widget, int tick) {
|
|
||||||
widget.alpha += 0.05f;
|
|
||||||
|
|
||||||
return widget.alpha > 0.9f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package org.saturnclient.ui.animations;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.SaturnAnimation;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class Slide extends SaturnAnimation {
|
|
||||||
private int offset;
|
|
||||||
|
|
||||||
public Slide(int delay, int offset) {
|
|
||||||
this.delay = delay;
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(SaturnWidget widget) {
|
|
||||||
widget.y += offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean run(SaturnWidget widget, int tick) {
|
|
||||||
widget.y--;
|
|
||||||
offset--;
|
|
||||||
|
|
||||||
return offset == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import net.minecraft.client.font.TextRenderer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
public class SaturnFloat extends SaturnWidget {
|
|
||||||
|
|
||||||
String text = "";
|
|
||||||
public Property<Float> prop;
|
|
||||||
public int cursorPosition = 0;
|
|
||||||
private TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
|
||||||
|
|
||||||
public SaturnFloat(Property<Float> prop, int x, int y, int width) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.width = width;
|
|
||||||
this.prop = prop;
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
this.height = textRenderer.fontHeight + 4;
|
|
||||||
this.scale = 0.8f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = text.substring(scrollOffset);
|
|
||||||
|
|
||||||
int newCursorPos = scrollOffset;
|
|
||||||
int textWidth = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < visibleText.length(); i++) {
|
|
||||||
textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1));
|
|
||||||
|
|
||||||
if (textWidth > mouseX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCursorPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorPosition = newCursorPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char chr) {
|
|
||||||
if ((Character.isDigit(chr) || chr == '.') && text.length() < 10) {
|
|
||||||
if (text.equals("0") && cursorPosition == 1) {
|
|
||||||
text = "" + chr;
|
|
||||||
} else {
|
|
||||||
text = text.substring(0, cursorPosition) +
|
|
||||||
chr +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
|
|
||||||
prop.value = text.isEmpty() ? 0 : Float.parseFloat(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
text = text.substring(0, cursorPosition - 1) +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
cursorPosition--;
|
|
||||||
if (text.length() == 0) {
|
|
||||||
text = "0";
|
|
||||||
cursorPosition = 1;
|
|
||||||
}
|
|
||||||
prop.value = Float.parseFloat(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
}
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
cursorPosition--;
|
|
||||||
}
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
|
||||||
if (cursorPosition < text.length()) {
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
if (prop.isReset) {
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
this.cursorPosition = 0;
|
|
||||||
prop.isReset = false;
|
|
||||||
}
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON_BORDER,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
focused
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha));
|
|
||||||
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = getVisibleText(scrollOffset);
|
|
||||||
|
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
|
||||||
context.drawText(
|
|
||||||
textRenderer,
|
|
||||||
SaturnUi.text(visibleText),
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
textColor,
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (focused) {
|
|
||||||
int cursorX = 2 +
|
|
||||||
textRenderer.getWidth(
|
|
||||||
SaturnUi.text(
|
|
||||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
|
||||||
context.fill(
|
|
||||||
cursorX,
|
|
||||||
2,
|
|
||||||
cursorX + 1,
|
|
||||||
textRenderer.fontHeight + 4,
|
|
||||||
0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearText() {
|
|
||||||
text = "0";
|
|
||||||
cursorPosition = 1;
|
|
||||||
prop.value = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getScrollOffset() {
|
|
||||||
if (text.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int maxWidth = width - 4; // Available width for text
|
|
||||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
|
||||||
String visibleText = text.substring(offset, cursorPosition);
|
|
||||||
if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
|
||||||
offset++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getVisibleText(int scrollOffset) {
|
|
||||||
String visibleText = text.substring(scrollOffset);
|
|
||||||
|
|
||||||
// Ensure text does not overflow past the available width
|
|
||||||
for (int i = 1; i <= visibleText.length(); i++) {
|
|
||||||
if (textRenderer.getWidth(
|
|
||||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
|
||||||
return visibleText.substring(0, i - 1); // Trim overflow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return visibleText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import net.minecraft.client.font.TextRenderer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
public class SaturnHex extends SaturnWidget {
|
|
||||||
|
|
||||||
private String text = "#"; // Always starts with '#'
|
|
||||||
public Property<Integer> prop;
|
|
||||||
public int cursorPosition = 1; // After '#'
|
|
||||||
private final TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
|
||||||
|
|
||||||
public SaturnHex(Property<Integer> prop, int x, int y, int width) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.width = width;
|
|
||||||
this.prop = prop;
|
|
||||||
this.text = intToHex(prop.value);
|
|
||||||
this.height = textRenderer.fontHeight + 4;
|
|
||||||
this.scale = 0.8f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
cursorPosition = Math.min(7, text.length()); // Keep cursor inside hex length
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char chr) {
|
|
||||||
if (isHexChar(chr) && text.length() < 7) { // Limit to 6 hex digits + '#'
|
|
||||||
text = text.substring(0, cursorPosition) +
|
|
||||||
chr +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
cursorPosition++;
|
|
||||||
|
|
||||||
if (text.length() == 7) { // Only update value when full hex is entered
|
|
||||||
prop.value = hexToInt(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE && cursorPosition > 1) { // Prevent deleting '#'
|
|
||||||
text = text.substring(0, cursorPosition - 1) +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
cursorPosition--;
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT && cursorPosition > 1) {
|
|
||||||
cursorPosition--;
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT && cursorPosition < text.length()) {
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.length() == 1) { // Reset if empty (keep '#')
|
|
||||||
text = "#";
|
|
||||||
cursorPosition = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.length() == 7) { // Update only when valid hex
|
|
||||||
prop.value = hexToInt(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
if (prop.isReset) {
|
|
||||||
this.text = intToHex(prop.value);
|
|
||||||
this.cursorPosition = 0;
|
|
||||||
prop.isReset = false;
|
|
||||||
}
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON_BORDER,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
focused
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha));
|
|
||||||
|
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
|
||||||
context.drawText(
|
|
||||||
textRenderer,
|
|
||||||
SaturnUi.text(text),
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
textColor,
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (focused) {
|
|
||||||
int cursorX = 2 +
|
|
||||||
textRenderer.getWidth(
|
|
||||||
SaturnUi.text(text.substring(0, cursorPosition)));
|
|
||||||
context.fill(
|
|
||||||
cursorX,
|
|
||||||
2,
|
|
||||||
cursorX + 1,
|
|
||||||
textRenderer.fontHeight + 4,
|
|
||||||
0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearText() {
|
|
||||||
text = "#";
|
|
||||||
cursorPosition = 1;
|
|
||||||
prop.value = 0xFFFFFFFF; // Default white
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isHexChar(char chr) {
|
|
||||||
return ((chr >= '0' && chr <= '9') ||
|
|
||||||
(chr >= 'A' && chr <= 'F') ||
|
|
||||||
(chr >= 'a' && chr <= 'f'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hexToInt(String hex) {
|
|
||||||
hex = hex.replace("#", "");
|
|
||||||
int rgb = Integer.parseInt(hex, 16);
|
|
||||||
return (0xFF << 24) | rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String intToHex(int color) {
|
|
||||||
int rgb = color & 0xFFFFFF;
|
|
||||||
return String.format("#%06X", rgb).toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
public class SaturnInteger extends SaturnWidget {
|
|
||||||
|
|
||||||
String text = "";
|
|
||||||
public Property<Integer> prop;
|
|
||||||
public int cursorPosition = 0;
|
|
||||||
|
|
||||||
public SaturnInteger(Property<Integer> prop, int x, int y, int width) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.width = width;
|
|
||||||
this.prop = prop;
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
this.height = SaturnClient.client.textRenderer.fontHeight + 4;
|
|
||||||
this.scale = 0.8f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = text.substring(scrollOffset);
|
|
||||||
|
|
||||||
int newCursorPos = scrollOffset;
|
|
||||||
int textWidth = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < visibleText.length(); i++) {
|
|
||||||
textWidth = SaturnClient.client.textRenderer.getWidth(visibleText.substring(0, i + 1));
|
|
||||||
|
|
||||||
if (textWidth > mouseX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCursorPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorPosition = newCursorPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char chr) {
|
|
||||||
if (Character.isDigit(chr) && text.length() < 10) {
|
|
||||||
if (text.equals("0") && cursorPosition == 1) {
|
|
||||||
text = "" + chr;
|
|
||||||
} else {
|
|
||||||
text = text.substring(0, cursorPosition) +
|
|
||||||
chr +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
|
|
||||||
prop.value = text.isEmpty() ? 0 : Integer.parseInt(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
text = text.substring(0, cursorPosition - 1) +
|
|
||||||
text.substring(cursorPosition);
|
|
||||||
cursorPosition--;
|
|
||||||
if (text.length() == 0) {
|
|
||||||
text = "0";
|
|
||||||
cursorPosition = 1;
|
|
||||||
}
|
|
||||||
prop.value = Integer.parseInt(text);
|
|
||||||
ConfigManager.save();
|
|
||||||
}
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
cursorPosition--;
|
|
||||||
}
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
|
||||||
if (cursorPosition < text.length()) {
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
if (prop.isReset) {
|
|
||||||
this.text = String.valueOf(prop.value);
|
|
||||||
this.cursorPosition = 0;
|
|
||||||
prop.isReset = false;
|
|
||||||
}
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON_BORDER,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
focused
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha));
|
|
||||||
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = getVisibleText(scrollOffset);
|
|
||||||
|
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
|
||||||
context.drawText(
|
|
||||||
SaturnClient.client.textRenderer,
|
|
||||||
SaturnUi.text(visibleText),
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
textColor,
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (focused) {
|
|
||||||
int cursorX = 2 +
|
|
||||||
SaturnClient.client.textRenderer.getWidth(
|
|
||||||
SaturnUi.text(
|
|
||||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
|
||||||
context.fill(
|
|
||||||
cursorX,
|
|
||||||
2,
|
|
||||||
cursorX + 1,
|
|
||||||
SaturnClient.client.textRenderer.fontHeight + 4,
|
|
||||||
0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearText() {
|
|
||||||
text = "0";
|
|
||||||
cursorPosition = 1;
|
|
||||||
prop.value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getScrollOffset() {
|
|
||||||
if (text.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int maxWidth = width - 4; // Available width for text
|
|
||||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
|
||||||
String visibleText = text.substring(offset, cursorPosition);
|
|
||||||
if (SaturnClient.client.textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
|
||||||
offset++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getVisibleText(int scrollOffset) {
|
|
||||||
String visibleText = text.substring(scrollOffset);
|
|
||||||
|
|
||||||
// Ensure text does not overflow past the available width
|
|
||||||
for (int i = 1; i <= visibleText.length(); i++) {
|
|
||||||
if (SaturnClient.client.textRenderer.getWidth(
|
|
||||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
|
||||||
return visibleText.substring(0, i - 1); // Trim overflow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return visibleText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.menus.ConfigEditor;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
public class SaturnModComp extends SaturnWidget {
|
|
||||||
|
|
||||||
Module mod;
|
|
||||||
|
|
||||||
public SaturnModComp(Module mod) {
|
|
||||||
this.mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
boolean enabled = mod.isEnabled();
|
|
||||||
|
|
||||||
boolean hovering_settings = settingsHovering(mouseX, mouseY);
|
|
||||||
|
|
||||||
int color = !hovering_settings && (enabled || hovering)
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(alpha);
|
|
||||||
|
|
||||||
int size = 12;
|
|
||||||
|
|
||||||
if (enabled) {
|
|
||||||
SaturnUi.drawHighResTexture(
|
|
||||||
context,
|
|
||||||
Textures.MOD_BG,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
86,
|
|
||||||
20,
|
|
||||||
SaturnClientConfig.color.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
SaturnUi.drawHighResTexture(
|
|
||||||
context,
|
|
||||||
Textures.MOD,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
86,
|
|
||||||
20,
|
|
||||||
color);
|
|
||||||
|
|
||||||
SaturnUi.drawHighResTexture(
|
|
||||||
context,
|
|
||||||
mod.getIconTexture(),
|
|
||||||
4,
|
|
||||||
4,
|
|
||||||
size,
|
|
||||||
size,
|
|
||||||
color);
|
|
||||||
|
|
||||||
context.drawText(
|
|
||||||
SaturnClient.client.textRenderer,
|
|
||||||
SaturnUi.text(mod.getName()),
|
|
||||||
20,
|
|
||||||
(21 - SaturnClient.client.textRenderer.fontHeight) / 2,
|
|
||||||
color,
|
|
||||||
false);
|
|
||||||
|
|
||||||
SaturnUi.drawHighResTexture(
|
|
||||||
context,
|
|
||||||
Textures.SETTINGS,
|
|
||||||
77,
|
|
||||||
11,
|
|
||||||
7,
|
|
||||||
7,
|
|
||||||
hovering_settings
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
if (settingsHovering(mouseX, mouseY)) {
|
|
||||||
SaturnClient.client
|
|
||||||
.setScreen(new ConfigEditor(mod.getConfig()));
|
|
||||||
} else {
|
|
||||||
mod.setEnabled(!mod.isEnabled());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean settingsHovering(int mouseX, int mouseY) {
|
|
||||||
int sX = 77;
|
|
||||||
int sY = 11;
|
|
||||||
int size = 7;
|
|
||||||
|
|
||||||
return (sX < mouseX &&
|
|
||||||
sX + size > mouseX &&
|
|
||||||
sY < mouseY &&
|
|
||||||
sY + size > mouseY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import net.minecraft.client.font.TextRenderer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
public class SaturnString extends SaturnWidget {
|
|
||||||
|
|
||||||
public Property<String> prop;
|
|
||||||
public int cursorPosition = 0;
|
|
||||||
private TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
|
||||||
|
|
||||||
public SaturnString(Property<String> prop, int x, int y, int width) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.width = width;
|
|
||||||
this.prop = prop;
|
|
||||||
this.height = textRenderer.fontHeight + 4;
|
|
||||||
this.scale = 0.8f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = prop.value.substring(scrollOffset);
|
|
||||||
|
|
||||||
int newCursorPos = scrollOffset;
|
|
||||||
int textWidth = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < visibleText.length(); i++) {
|
|
||||||
textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1));
|
|
||||||
|
|
||||||
if (textWidth > mouseX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCursorPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorPosition = newCursorPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char chr) {
|
|
||||||
prop.value = prop.value.substring(0, cursorPosition) +
|
|
||||||
chr +
|
|
||||||
prop.value.substring(cursorPosition);
|
|
||||||
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
prop.value = prop.value.substring(0, cursorPosition - 1) +
|
|
||||||
prop.value.substring(cursorPosition);
|
|
||||||
cursorPosition--;
|
|
||||||
}
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
cursorPosition--;
|
|
||||||
}
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
|
||||||
if (cursorPosition < prop.value.length()) {
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON_BORDER,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
focused
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha));
|
|
||||||
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = getVisibleText(scrollOffset);
|
|
||||||
|
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
|
||||||
context.drawText(
|
|
||||||
textRenderer,
|
|
||||||
SaturnUi.text(visibleText),
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
textColor,
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (focused) {
|
|
||||||
int cursorX = 2 +
|
|
||||||
textRenderer.getWidth(
|
|
||||||
SaturnUi.text(
|
|
||||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
|
||||||
context.fill(
|
|
||||||
cursorX,
|
|
||||||
2,
|
|
||||||
cursorX + 1,
|
|
||||||
textRenderer.fontHeight + 3,
|
|
||||||
0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearText() {
|
|
||||||
prop.value = "";
|
|
||||||
cursorPosition = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getScrollOffset() {
|
|
||||||
if (prop.value.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int maxWidth = width - 4; // Available width for prop.value
|
|
||||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
|
||||||
String visibleText = prop.value.substring(offset, cursorPosition);
|
|
||||||
if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
|
||||||
offset++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getVisibleText(int scrollOffset) {
|
|
||||||
String visibleText = prop.value.substring(scrollOffset);
|
|
||||||
|
|
||||||
// Ensure prop.value does not overflow past the available width
|
|
||||||
for (int i = 1; i <= visibleText.length(); i++) {
|
|
||||||
if (textRenderer.getWidth(
|
|
||||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
|
||||||
return visibleText.substring(0, i - 1); // Trim overflow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return visibleText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package org.saturnclient.ui.components;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.client.render.RenderLayer;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
public class SaturnToggle extends SaturnWidget {
|
|
||||||
|
|
||||||
Property<Boolean> prop;
|
|
||||||
|
|
||||||
public SaturnToggle(Property<Boolean> prop) {
|
|
||||||
this.prop = prop;
|
|
||||||
width = 16;
|
|
||||||
height = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
int color = prop.value
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(alpha);
|
|
||||||
int w = 13;
|
|
||||||
int h = 6;
|
|
||||||
int s = 8;
|
|
||||||
|
|
||||||
context.drawTexture(
|
|
||||||
RenderLayer::getGuiTextured,
|
|
||||||
Textures.TOGGLE_BG,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
w,
|
|
||||||
h,
|
|
||||||
w,
|
|
||||||
h,
|
|
||||||
color);
|
|
||||||
|
|
||||||
context.drawTexture(
|
|
||||||
RenderLayer::getGuiTextured,
|
|
||||||
Textures.TOGGLE_INDICATOR,
|
|
||||||
prop.value ? 5 : 0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
s,
|
|
||||||
s,
|
|
||||||
s,
|
|
||||||
s,
|
|
||||||
color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
prop.value = !prop.value;
|
|
||||||
ConfigManager.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
|
|
||||||
|
|
||||||
public class SaturnButton extends SaturnWidget {
|
|
||||||
|
|
||||||
public boolean active = true;
|
|
||||||
public String text;
|
|
||||||
public Consumer<SaturnButton> onPress;
|
|
||||||
public boolean background = true;
|
|
||||||
public boolean bold = false;
|
|
||||||
private float hoverAlpha = 0.0f;
|
|
||||||
|
|
||||||
public SaturnButton(String text, Consumer<SaturnButton> onPress) {
|
|
||||||
this.text = text;
|
|
||||||
this.onPress = onPress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnButton(String text, Runnable onPress) {
|
|
||||||
this(text, b -> {
|
|
||||||
onPress.run();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
MinecraftClient minecraftClient = SaturnClient.client;
|
|
||||||
|
|
||||||
if (background) {
|
|
||||||
RenderSystem.setShaderTexture(0, Textures.BUTTON);
|
|
||||||
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha));
|
|
||||||
|
|
||||||
if (hovering) {
|
|
||||||
if (hoverAlpha == 0.0f)
|
|
||||||
hoverAlpha = 0.1f;
|
|
||||||
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON_BORDER,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha));
|
|
||||||
} else {
|
|
||||||
hoverAlpha = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alpha != 0.0f) {
|
|
||||||
Text t = bold ? SaturnUi.textBold(text) : SaturnUi.text(text);
|
|
||||||
context.drawText(
|
|
||||||
minecraftClient.textRenderer,
|
|
||||||
t,
|
|
||||||
((this.width -
|
|
||||||
minecraftClient.textRenderer.getWidth(t))
|
|
||||||
/
|
|
||||||
2),
|
|
||||||
((this.height - minecraftClient.textRenderer.fontHeight + 1) /
|
|
||||||
2),
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
this.onPress.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
if (hoverAlpha > 0.0f && hoverAlpha < 0.9f)
|
|
||||||
hoverAlpha += 0.03f;
|
|
||||||
else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f)
|
|
||||||
hoverAlpha = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnWidget setBold(boolean bold) {
|
|
||||||
this.bold = bold;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class SaturnClickableImage extends SaturnWidget {
|
|
||||||
|
|
||||||
public Identifier texture;
|
|
||||||
public boolean selected = false;
|
|
||||||
public Consumer<SaturnClickableImage> onPress;
|
|
||||||
private float hoverAlpha = 0.0f;
|
|
||||||
|
|
||||||
public SaturnClickableImage(
|
|
||||||
Identifier texture,
|
|
||||||
Consumer<SaturnClickableImage> onPress) {
|
|
||||||
this.texture = texture;
|
|
||||||
this.onPress = onPress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnClickableImage(Identifier texture, Runnable onPress) {
|
|
||||||
this(texture, _o -> {
|
|
||||||
onPress.run();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
if (hovering) {
|
|
||||||
if (hoverAlpha == 0.0f)
|
|
||||||
hoverAlpha = 0.1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
SaturnUi.drawHighResTexture(
|
|
||||||
context,
|
|
||||||
texture,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
SaturnClientConfig.getColor(hovering || selected, alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
this.onPress.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnClickableImage setSelected(boolean selected) {
|
|
||||||
this.selected = selected;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
if (hoverAlpha > 0.0f && hoverAlpha < 0.9f)
|
|
||||||
hoverAlpha += 0.03f;
|
|
||||||
else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f)
|
|
||||||
hoverAlpha = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class SaturnClickableSprite extends SaturnWidget {
|
|
||||||
|
|
||||||
public Identifier sprite;
|
|
||||||
public boolean selected = false;
|
|
||||||
public Consumer<SaturnClickableSprite> onPress;
|
|
||||||
|
|
||||||
public SaturnClickableSprite(
|
|
||||||
Identifier sprite,
|
|
||||||
Consumer<SaturnClickableSprite> onPress) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
this.onPress = onPress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnClickableSprite(Identifier sprite, Runnable onPress) {
|
|
||||||
this(sprite, _o -> {
|
|
||||||
onPress.run();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
sprite,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
this.onPress.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnClickableSprite setSelected(boolean selected) {
|
|
||||||
this.selected = selected;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.ColorHelper;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class SaturnImage extends SaturnWidget {
|
|
||||||
|
|
||||||
private final Identifier sprite;
|
|
||||||
|
|
||||||
public SaturnImage(Identifier sprite) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
SaturnUi.drawHighResTexture(
|
|
||||||
context,
|
|
||||||
sprite,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
ColorHelper.getWhite(alpha));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.client.render.RenderLayer;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
public class SaturnImageButton extends SaturnWidget {
|
|
||||||
|
|
||||||
public Identifier sprite;
|
|
||||||
public int imageWidth;
|
|
||||||
public int imageHeight;
|
|
||||||
public Consumer<SaturnImageButton> onPress;
|
|
||||||
private float hoverAlpha = 0.0f;
|
|
||||||
|
|
||||||
public SaturnImageButton(
|
|
||||||
Identifier sprite,
|
|
||||||
int imageWidth,
|
|
||||||
int imageHeight,
|
|
||||||
Consumer<SaturnImageButton> onPress) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
this.imageWidth = imageWidth;
|
|
||||||
this.imageHeight = imageHeight;
|
|
||||||
this.onPress = onPress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnImageButton(
|
|
||||||
Identifier sprite,
|
|
||||||
int imageWidth,
|
|
||||||
int imageHeight,
|
|
||||||
Runnable onPress) {
|
|
||||||
this(sprite, imageWidth, imageHeight, _o -> {
|
|
||||||
onPress.run();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
if (hovering) {
|
|
||||||
if (hoverAlpha == 0.0f)
|
|
||||||
hoverAlpha = 0.1f;
|
|
||||||
}
|
|
||||||
RenderSystem.setShaderTexture(0, Textures.BUTTON);
|
|
||||||
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha));
|
|
||||||
|
|
||||||
if (hovering) {
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON_BORDER,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
context.drawTexture(
|
|
||||||
RenderLayer::getGuiTextured,
|
|
||||||
sprite,
|
|
||||||
((width - imageWidth) / 2),
|
|
||||||
((height - imageHeight) / 2),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
imageWidth,
|
|
||||||
imageHeight,
|
|
||||||
imageWidth,
|
|
||||||
imageHeight,
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
this.onPress.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
if (hoverAlpha > 0.0f && hoverAlpha < 0.9f)
|
|
||||||
hoverAlpha += 0.03f;
|
|
||||||
else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f)
|
|
||||||
hoverAlpha = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import net.minecraft.client.font.TextRenderer;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.Textures;
|
|
||||||
|
|
||||||
public class SaturnInputBox extends SaturnWidget {
|
|
||||||
|
|
||||||
private TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
|
||||||
private int tick = 0;
|
|
||||||
private boolean cursorVisible = true;
|
|
||||||
|
|
||||||
public Property<String> prop;
|
|
||||||
public int cursorPosition = 0;
|
|
||||||
public Runnable onUpdate;
|
|
||||||
|
|
||||||
public SaturnInputBox(Property<String> prop, int x, int y, int width) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.width = width;
|
|
||||||
this.prop = prop;
|
|
||||||
this.height = textRenderer.fontHeight + 4;
|
|
||||||
this.scale = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = prop.value.substring(scrollOffset);
|
|
||||||
|
|
||||||
int newCursorPos = scrollOffset;
|
|
||||||
int textWidth = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < visibleText.length(); i++) {
|
|
||||||
textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1));
|
|
||||||
|
|
||||||
if (textWidth > mouseX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCursorPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorPosition = newCursorPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char chr) {
|
|
||||||
prop.value = prop.value.substring(0, cursorPosition) +
|
|
||||||
chr +
|
|
||||||
prop.value.substring(cursorPosition);
|
|
||||||
|
|
||||||
cursorPosition++;
|
|
||||||
|
|
||||||
onUpdate.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
prop.value = prop.value.substring(0, cursorPosition - 1) +
|
|
||||||
prop.value.substring(cursorPosition);
|
|
||||||
cursorPosition--;
|
|
||||||
}
|
|
||||||
onUpdate.run();
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
|
||||||
if (cursorPosition > 0) {
|
|
||||||
cursorPosition--;
|
|
||||||
}
|
|
||||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
|
||||||
if (cursorPosition < prop.value.length()) {
|
|
||||||
cursorPosition++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
focused
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha));
|
|
||||||
|
|
||||||
if (hovering || focused) {
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
Textures.BUTTON_BORDER,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
hovering
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha));
|
|
||||||
}
|
|
||||||
|
|
||||||
MatrixStack matrices = context.getMatrices();
|
|
||||||
matrices.push();
|
|
||||||
|
|
||||||
if (prop.value.isEmpty() && !focused) {
|
|
||||||
SaturnUi.drawHighResTexture(
|
|
||||||
context,
|
|
||||||
Textures.SEARCH,
|
|
||||||
3,
|
|
||||||
3,
|
|
||||||
9,
|
|
||||||
9,
|
|
||||||
hovering
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha));
|
|
||||||
|
|
||||||
matrices.scale(0.9f, 0.9f, 1.0f);
|
|
||||||
|
|
||||||
context.drawText(
|
|
||||||
textRenderer,
|
|
||||||
SaturnUi.text("Search"),
|
|
||||||
14,
|
|
||||||
textRenderer.fontHeight / 2 + 1,
|
|
||||||
hovering
|
|
||||||
? SaturnClientConfig.color.value
|
|
||||||
: SaturnClientConfig.getWhite(this.alpha),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
matrices.pop();
|
|
||||||
|
|
||||||
matrices.push();
|
|
||||||
|
|
||||||
matrices.scale(0.9f, 0.9f, 1.0f);
|
|
||||||
|
|
||||||
int scrollOffset = getScrollOffset();
|
|
||||||
String visibleText = getVisibleText(scrollOffset);
|
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
|
||||||
context.drawText(
|
|
||||||
textRenderer,
|
|
||||||
SaturnUi.text(visibleText),
|
|
||||||
3,
|
|
||||||
textRenderer.fontHeight / 2,
|
|
||||||
textColor,
|
|
||||||
false);
|
|
||||||
|
|
||||||
if (focused && cursorVisible) {
|
|
||||||
int cursorX = 2 +
|
|
||||||
textRenderer.getWidth(
|
|
||||||
SaturnUi.text(
|
|
||||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
|
||||||
matrices.translate(cursorX, 0, 0);
|
|
||||||
context.fill(
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
textRenderer.fontHeight + 3,
|
|
||||||
0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
matrices.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearText() {
|
|
||||||
prop.value = "";
|
|
||||||
cursorPosition = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getScrollOffset() {
|
|
||||||
if (prop.value.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int maxWidth = width - 4; // Available width for prop.value
|
|
||||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
|
||||||
String visibleText = prop.value.substring(offset, cursorPosition);
|
|
||||||
if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
|
||||||
offset++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getVisibleText(int scrollOffset) {
|
|
||||||
String visibleText = prop.value.substring(scrollOffset);
|
|
||||||
|
|
||||||
// Ensure prop.value does not overflow past the available width
|
|
||||||
for (int i = 1; i <= visibleText.length(); i++) {
|
|
||||||
if (textRenderer.getWidth(
|
|
||||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
|
||||||
return visibleText.substring(0, i - 1); // Trim overflow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return visibleText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnInputBox onUpdate(Runnable onUpdate) {
|
|
||||||
this.onUpdate = onUpdate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
if (focused) {
|
|
||||||
if (tick < 45 || tick < 60 && cursorVisible) {
|
|
||||||
tick++;
|
|
||||||
} else {
|
|
||||||
tick = 0;
|
|
||||||
cursorVisible = !cursorVisible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class SaturnScroll extends SaturnWidget {
|
|
||||||
|
|
||||||
private int scroll = 0;
|
|
||||||
private int maxScroll = 0;
|
|
||||||
private List<SaturnWidget> children = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseScrolled(
|
|
||||||
int mouseX,
|
|
||||||
int mouseY,
|
|
||||||
double horizontalAmount,
|
|
||||||
double verticalAmount
|
|
||||||
) {
|
|
||||||
verticalAmount *= 2;
|
|
||||||
|
|
||||||
if (scroll - verticalAmount <= 0) {
|
|
||||||
scroll = 0;
|
|
||||||
} else if (scroll - verticalAmount >= maxScroll) {
|
|
||||||
scroll = maxScroll;
|
|
||||||
} else {
|
|
||||||
scroll -= verticalAmount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY
|
|
||||||
) {
|
|
||||||
context.enableScissor(0, 0, width, height);
|
|
||||||
|
|
||||||
for (SaturnWidget widget : children) {
|
|
||||||
if (!widget.visible) continue;
|
|
||||||
|
|
||||||
double adjustedMouseX = (mouseX - widget.x);
|
|
||||||
double adjustedMouseY = (mouseY - widget.y + scroll);
|
|
||||||
boolean isMouseInside =
|
|
||||||
adjustedMouseX >= 0 &&
|
|
||||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
|
||||||
adjustedMouseY >= 0 &&
|
|
||||||
adjustedMouseY <= (widget.height * widget.scale);
|
|
||||||
|
|
||||||
if (
|
|
||||||
widget.y - scroll < height && widget.y + widget.height > scroll
|
|
||||||
) {
|
|
||||||
MatrixStack matrices = context.getMatrices();
|
|
||||||
matrices.push();
|
|
||||||
matrices.translate(widget.x, widget.y - scroll, 0);
|
|
||||||
matrices.scale(widget.scale, widget.scale, 1.0f);
|
|
||||||
|
|
||||||
widget.render(
|
|
||||||
context,
|
|
||||||
isMouseInside,
|
|
||||||
(int) (adjustedMouseX / widget.scale),
|
|
||||||
(int) (adjustedMouseY / widget.scale)
|
|
||||||
);
|
|
||||||
matrices.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
context.disableScissor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init() {
|
|
||||||
maxScroll = 0;
|
|
||||||
for (SaturnWidget child : children) {
|
|
||||||
maxScroll = Math.max(maxScroll, child.y + child.height - height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(SaturnWidget widget) {
|
|
||||||
synchronized (children) {
|
|
||||||
widget.init();
|
|
||||||
children.add(widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isScrollable() {
|
|
||||||
for (SaturnWidget widget : children) {
|
|
||||||
if (widget.y + widget.height > height) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
for (SaturnWidget widget : children) {
|
|
||||||
if (!widget.visible || !widget.focused) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.keyPressed(keyCode, scanCode, modifiers);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void charTyped(char typedChar) {
|
|
||||||
for (SaturnWidget widget : children) {
|
|
||||||
if (!widget.visible || !widget.focused) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.charTyped(typedChar);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
for (SaturnWidget widget : children) {
|
|
||||||
widget.focused = false;
|
|
||||||
if (!widget.visible) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
double adjustedMouseX = (mouseX - widget.x);
|
|
||||||
double adjustedMouseY = (mouseY - (widget.y - scroll));
|
|
||||||
boolean isMouseInside =
|
|
||||||
adjustedMouseX >= 0 &&
|
|
||||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
|
||||||
adjustedMouseY >= 0 &&
|
|
||||||
adjustedMouseY <= (widget.height * widget.scale);
|
|
||||||
|
|
||||||
if (isMouseInside) {
|
|
||||||
widget.focused = true;
|
|
||||||
widget.click(
|
|
||||||
(int) (adjustedMouseX / widget.scale),
|
|
||||||
(int) (adjustedMouseY / widget.scale)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
children.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.ColorHelper;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class SaturnSprite extends SaturnWidget {
|
|
||||||
|
|
||||||
private final Identifier sprite;
|
|
||||||
|
|
||||||
public SaturnSprite(Identifier sprite) {
|
|
||||||
this.sprite = sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
SaturnUi.drawHighResGuiTexture(
|
|
||||||
context,
|
|
||||||
sprite,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
ColorHelper.getWhite(this.alpha));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package org.saturnclient.ui.widgets;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.ui.SaturnUi;
|
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
|
|
||||||
public class SaturnText extends SaturnWidget {
|
|
||||||
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
public SaturnText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
this.width = SaturnClient.client.textRenderer.getWidth(SaturnUi.text(text));
|
|
||||||
this.height = SaturnClient.client.textRenderer.fontHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaturnText(String text, int color) {
|
|
||||||
this(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(
|
|
||||||
DrawContext context,
|
|
||||||
boolean hovering,
|
|
||||||
int mouseX,
|
|
||||||
int mouseY) {
|
|
||||||
context.drawText(
|
|
||||||
SaturnClient.client.textRenderer,
|
|
||||||
SaturnUi.text(text),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
SaturnClientConfig.getColor(hovering, alpha),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +1,83 @@
|
|||||||
package org.saturnclient.ui2;
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
public class Element {
|
import java.util.function.Function;
|
||||||
protected int x;
|
|
||||||
protected int y;
|
|
||||||
protected int width;
|
|
||||||
protected int height;
|
|
||||||
public boolean focused;
|
|
||||||
|
|
||||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
import org.saturnclient.ui2.anim.Animation;
|
||||||
|
import org.saturnclient.ui2.anim.Curve;
|
||||||
|
|
||||||
|
public class Element {
|
||||||
|
public int x;
|
||||||
|
public int y;
|
||||||
|
public int width;
|
||||||
|
public int height;
|
||||||
|
public float opacity = 1.0f;
|
||||||
|
public boolean focused;
|
||||||
|
public Animation animation;
|
||||||
|
public float scale = 1.0f;
|
||||||
|
public Function<Double, Double> curve = Curve::easeInOutCubic;
|
||||||
|
public Integer duration = null; // Element duration, will fade out if not null
|
||||||
|
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void click(int mouseX, int mouseY) {
|
public void click(int mouseX, int mouseY) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void dimensions(int width, int height) {
|
public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void charTyped(char typedChar) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element dimensions(int width, int height) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void position(int x, int y) {
|
public Element position(int x, int y) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
|
||||||
|
|
||||||
public final Element center(int w, int h) {
|
|
||||||
this.x = (w - width) / 2;
|
|
||||||
this.y = (h - height) / 2;
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Element centerOffset(int w, int h, int offsetX, int offsetY) {
|
public Element centerHorizontal(int w, int h, int offsetX, int offsetY) {
|
||||||
this.x = (w - width) / 2 + offsetX;
|
this.x = (w - (int) (width * scale)) / 2 + offsetX;
|
||||||
this.y = (h - height) / 2 + offsetY;
|
this.y = offsetY;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Element center(int w, int h) {
|
||||||
|
this.centerOffset(w, h, 0, 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element centerOffset(int w, int h, int offsetX, int offsetY) {
|
||||||
|
this.x = (w - (int) (width * scale)) / 2 + offsetX;
|
||||||
|
this.y = (h - (int) (height * scale)) / 2 + offsetY;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element animation(Animation animation) {
|
||||||
|
this.animation = animation;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element animation(Animation animation, Function<Double, Double> curve) {
|
||||||
|
this.animation = animation;
|
||||||
|
this.curve = curve;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element scale(float scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
|
public class ElementContext {
|
||||||
|
public int mouseX, mouseY;
|
||||||
|
public int elementWidth, elementHeight;
|
||||||
|
public float elementScale;
|
||||||
|
|
||||||
|
public ElementContext(int mouseX, int mouseY, Element e) {
|
||||||
|
this.mouseX = mouseX - e.x;
|
||||||
|
this.mouseY = mouseY - e.y;
|
||||||
|
this.elementWidth = e.width;
|
||||||
|
this.elementHeight = e.height;
|
||||||
|
this.elementScale = e.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHovering() {
|
||||||
|
return Utils.isHovering(mouseX, mouseY, elementWidth, elementHeight, elementScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHovering(int x, int y, int width, int height) {
|
||||||
|
return Utils.isHovering(mouseX - x, mouseY - y, width, height, elementScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package org.saturnclient.ui2;
|
|
||||||
|
|
||||||
public class RenderContext {
|
|
||||||
public int mouseX, mouseY;
|
|
||||||
public int elementX, elementY;
|
|
||||||
public int elementWidth, elementHeight;
|
|
||||||
|
|
||||||
public RenderContext(int mouseX, int mouseY, Element e) {
|
|
||||||
this.mouseX = mouseX;
|
|
||||||
this.mouseY = mouseY;
|
|
||||||
this.elementX = e.x;
|
|
||||||
this.elementY = e.y;
|
|
||||||
this.elementWidth = e.width;
|
|
||||||
this.elementHeight = e.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHovering() {
|
|
||||||
return mouseX >= elementX &&
|
|
||||||
mouseX <= elementX + elementWidth &&
|
|
||||||
mouseY >= elementY &&
|
|
||||||
mouseY <= elementY + elementHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
package org.saturnclient.ui2;
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.saturnclient.ui2.resources.Fonts;
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
@@ -9,21 +14,39 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
|||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import net.minecraft.client.font.TextRenderer;
|
import net.minecraft.client.font.TextRenderer;
|
||||||
import net.minecraft.client.font.TextRenderer.TextLayerType;
|
import net.minecraft.client.font.TextRenderer.TextLayerType;
|
||||||
|
import net.minecraft.client.gui.ScreenRect;
|
||||||
|
import net.minecraft.client.render.DiffuseLighting;
|
||||||
|
import net.minecraft.client.render.OverlayTexture;
|
||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
import net.minecraft.client.render.VertexConsumerProvider;
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.item.ItemRenderState;
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.client.util.Window;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ModelTransformationMode;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.crash.CrashException;
|
||||||
|
import net.minecraft.util.crash.CrashReport;
|
||||||
|
import net.minecraft.util.crash.CrashReportSection;
|
||||||
import net.minecraft.util.math.RotationAxis;
|
import net.minecraft.util.math.RotationAxis;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class RenderScope {
|
public class RenderScope {
|
||||||
public MatrixStack matrices;
|
public MatrixStack matrices;
|
||||||
public VertexConsumerProvider.Immediate vertexConsumers;
|
public VertexConsumerProvider.Immediate vertexConsumers;
|
||||||
|
// private Function<Identifier, RenderLayer> renderLayers;
|
||||||
|
private ScissorStack scissorStack = new ScissorStack();
|
||||||
private int opacity = 255 << 24;
|
private int opacity = 255 << 24;
|
||||||
|
private final ItemRenderState itemRenderState;
|
||||||
|
|
||||||
public RenderScope(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) {
|
public RenderScope(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) {
|
||||||
this.matrices = matrices;
|
this.matrices = matrices;
|
||||||
this.vertexConsumers = vertexConsumers;
|
this.vertexConsumers = vertexConsumers;
|
||||||
|
this.scissorStack = new ScissorStack();
|
||||||
|
this.itemRenderState = new ItemRenderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOpacity(float alpha) {
|
public void setOpacity(float alpha) {
|
||||||
@@ -31,7 +54,14 @@ public class RenderScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getColor(int color) {
|
public int getColor(int color) {
|
||||||
return opacity | (color & 0x00FFFFFF);
|
int originalAlpha = (color >>> 24) & 0xFF;
|
||||||
|
int newAlpha = (opacity >>> 24) & 0xFF;
|
||||||
|
int mixedAlpha = (originalAlpha * newAlpha) / 255;
|
||||||
|
return (mixedAlpha << 24) | (color & 0x00FFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRenderLayer(Function<Identifier, RenderLayer> renderLayers) {
|
||||||
|
// this.renderLayers = renderLayers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRect(int x, int y, int width, int height, int color) {
|
public void drawRect(int x, int y, int width, int height, int color) {
|
||||||
@@ -63,17 +93,29 @@ public class RenderScope {
|
|||||||
vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color);
|
vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawText(String text, int x, int y, boolean bold, int color) {
|
public void drawText(String text, int x, int y, int font, int color) {
|
||||||
color = getColor(color);
|
drawText(1.0f, text, x, y, font, color);
|
||||||
|
|
||||||
Identifier font = bold ? Fonts.PANTON_BOLD : Fonts.PANTON;
|
|
||||||
|
|
||||||
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
|
||||||
textRenderer.draw(Fonts.setFont(text, font), (float) x, (float) y, color, false, this.matrices.peek().getPositionMatrix(),
|
|
||||||
this.vertexConsumers, TextLayerType.NORMAL, 0, 15728880);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawRoundedCorner(int width, int height, int radius, int color) {
|
public void drawText(float scale, String text, int x, int y, int font, int color) {
|
||||||
|
if (font == 0) {
|
||||||
|
scale *= 2;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
for (String line : text.split("\n")) {
|
||||||
|
color = getColor(color);
|
||||||
|
matrices.push();
|
||||||
|
matrices.translate(x, y + (i * Fonts.getHeight()), 0);
|
||||||
|
matrices.scale(scale, scale, 1.0f);
|
||||||
|
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||||
|
textRenderer.draw(Fonts.setFont(line, Fonts.getFont(font)), 0, font == 0 ? 1: 7, color, false, this.matrices.peek().getPositionMatrix(),
|
||||||
|
this.vertexConsumers, TextLayerType.NORMAL, 0, 15728880);
|
||||||
|
matrices.pop();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawRoundedCorner(int width, int height, int radius, int color) {
|
||||||
int w = width * 20;
|
int w = width * 20;
|
||||||
int h = height * 20;
|
int h = height * 20;
|
||||||
|
|
||||||
@@ -117,6 +159,7 @@ public class RenderScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) {
|
public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) {
|
||||||
|
radius = Math.min(radius, Math.min(width, height));
|
||||||
int cornerWidth = width / 2;
|
int cornerWidth = width / 2;
|
||||||
int cornerHeight = height / 2;
|
int cornerHeight = height / 2;
|
||||||
|
|
||||||
@@ -144,32 +187,184 @@ public class RenderScope {
|
|||||||
public int getScaledWindowHeight() {
|
public int getScaledWindowHeight() {
|
||||||
return SaturnClient.client.getWindow().getScaledHeight();
|
return SaturnClient.client.getWindow().getScaledHeight();
|
||||||
}
|
}
|
||||||
|
public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int color) {
|
||||||
public void drawTexture(Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight, int color) {
|
this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color);
|
||||||
this.drawTexture(renderLayers, sprite, x, y, u, v, width, height, width, height, textureWidth, textureHeight, color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawTexture(Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight) {
|
public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height) {
|
||||||
this.drawTexture(renderLayers, sprite, x, y, u, v, width, height, width, height, textureWidth, textureHeight);
|
this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawTexture(Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWith, int regionHeight, int textureWidth, int textureHeight) {
|
public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWith, int regionHeight, int textureWidth, int textureHeight) {
|
||||||
this.drawTexture(renderLayers, sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1);
|
this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawTexture(Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) {
|
public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) {
|
||||||
this.drawTexturedQuad(renderLayers, sprite, x, x + width, y, y + height, (u + 0.0F) / (float)textureWidth, (u + (float)regionWidth) / (float)textureWidth, (v + 0.0F) / (float)textureHeight, (v + (float)regionHeight) / (float)textureHeight, color);
|
this.drawTexturedQuad(sprite, x, x + width, y, y + height, (u + 0.0F) / (float)textureWidth, (u + (float)regionWidth) / (float)textureWidth, (v + 0.0F) / (float)textureHeight, (v + (float)regionHeight) / (float)textureHeight, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawTexturedQuad(Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, float v2, int color) {
|
private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, float v2, int color) {
|
||||||
|
x1 *= 4;
|
||||||
|
x2 *= 4;
|
||||||
|
y1 *= 4;
|
||||||
|
y2 *= 4;
|
||||||
|
color = getColor(color);
|
||||||
|
|
||||||
|
matrices.push();
|
||||||
|
matrices.scale(0.25f, 0.25f, 1.0f);
|
||||||
RenderSystem.setShaderTexture(0, sprite);
|
RenderSystem.setShaderTexture(0, sprite);
|
||||||
|
RenderLayer renderLayer = (RenderLayer)RenderLayer.getGuiTextured(sprite);
|
||||||
RenderLayer renderLayer = (RenderLayer)renderLayers.apply(sprite);
|
|
||||||
Matrix4f matrix4f = this.matrices.peek().getPositionMatrix();
|
Matrix4f matrix4f = this.matrices.peek().getPositionMatrix();
|
||||||
VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(renderLayer);
|
VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(renderLayer);
|
||||||
vertexConsumer.vertex(matrix4f, (float)x1, (float)y1, 0.0F).texture(u1, v1).color(color);
|
vertexConsumer.vertex(matrix4f, (float)x1, (float)y1, 0.0F).texture(u1, v1).color(color);
|
||||||
vertexConsumer.vertex(matrix4f, (float)x1, (float)y2, 0.0F).texture(u1, v2).color(color);
|
vertexConsumer.vertex(matrix4f, (float)x1, (float)y2, 0.0F).texture(u1, v2).color(color);
|
||||||
vertexConsumer.vertex(matrix4f, (float)x2, (float)y2, 0.0F).texture(u2, v2).color(color);
|
vertexConsumer.vertex(matrix4f, (float)x2, (float)y2, 0.0F).texture(u2, v2).color(color);
|
||||||
vertexConsumer.vertex(matrix4f, (float)x2, (float)y1, 0.0F).texture(u2, v1).color(color);
|
vertexConsumer.vertex(matrix4f, (float)x2, (float)y1, 0.0F).texture(u2, v1).color(color);
|
||||||
|
matrices.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableScissor(int x1, int y1, int x2, int y2) {
|
||||||
|
ScreenRect screenRect = (new ScreenRect(x1, y1, x2 - x1, y2 - y1)).transform(this.matrices.peek().getPositionMatrix());
|
||||||
|
this.setScissor(this.scissorStack.push(screenRect));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableScissor() {
|
||||||
|
this.setScissor(this.scissorStack.pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean scissorContains(int x, int y) {
|
||||||
|
return this.scissorStack.containsPoint(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setScissor(@Nullable ScreenRect rect) {
|
||||||
|
this.draw();
|
||||||
|
if (rect != null) {
|
||||||
|
Window window = SaturnClient.client.getWindow();
|
||||||
|
int i = window.getFramebufferHeight();
|
||||||
|
double d = window.getScaleFactor();
|
||||||
|
double e = (double)rect.getLeft() * d;
|
||||||
|
double f = (double)i - (double)rect.getBottom() * d;
|
||||||
|
double g = (double)rect.width() * d;
|
||||||
|
double h = (double)rect.height() * d;
|
||||||
|
RenderSystem.enableScissor((int)e, (int)f, Math.max(0, (int)g), Math.max(0, (int)h));
|
||||||
|
} else {
|
||||||
|
RenderSystem.disableScissor();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw() {
|
||||||
|
this.vertexConsumers.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Consumer<VertexConsumerProvider> drawer) {
|
||||||
|
drawer.accept(this.vertexConsumers);
|
||||||
|
this.vertexConsumers.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ScissorStack {
|
||||||
|
private final Deque<ScreenRect> stack = new ArrayDeque<>();
|
||||||
|
|
||||||
|
public ScreenRect push(ScreenRect p_281812_) {
|
||||||
|
ScreenRect screenrectangle = this.stack.peekLast();
|
||||||
|
if (screenrectangle != null) {
|
||||||
|
ScreenRect screenrectangle1 = Objects.requireNonNullElse(p_281812_.intersection(screenrectangle), ScreenRect.empty());
|
||||||
|
this.stack.addLast(screenrectangle1);
|
||||||
|
return screenrectangle1;
|
||||||
|
} else {
|
||||||
|
this.stack.addLast(p_281812_);
|
||||||
|
return p_281812_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ScreenRect pop() {
|
||||||
|
if (this.stack.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Scissor stack underflow");
|
||||||
|
} else {
|
||||||
|
this.stack.removeLast();
|
||||||
|
return this.stack.peekLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsPoint(int p_329411_, int p_333404_) {
|
||||||
|
return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawItem(ItemStack item, int x, int y) {
|
||||||
|
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawItem(ItemStack stack, int x, int y, int seed) {
|
||||||
|
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, stack, x, y, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawItem(ItemStack stack, int x, int y, int seed, int z) {
|
||||||
|
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, stack, x, y, seed, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawItemWithoutEntity(ItemStack stack, int x, int y) {
|
||||||
|
this.drawItemWithoutEntity(stack, x, y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawItemWithoutEntity(ItemStack stack, int x, int y, int seed) {
|
||||||
|
this.drawItem((LivingEntity)null, SaturnClient.client.world, stack, x, y, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawItem(LivingEntity entity, ItemStack stack, int x, int y, int seed) {
|
||||||
|
this.drawItem(entity, entity.getWorld(), stack, x, y, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed) {
|
||||||
|
this.drawItem(entity, world, stack, x, y, seed, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, int z) {
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
SaturnClient.client.getItemModelManager().update(this.itemRenderState, stack, ModelTransformationMode.GUI, false, world, entity, seed);
|
||||||
|
this.matrices.push();
|
||||||
|
this.matrices.translate((float)(x + 8), (float)(y + 8), (float)(150 + (this.itemRenderState.hasDepth() ? z : 0)));
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.matrices.scale(16.0F, -16.0F, 16.0F);
|
||||||
|
boolean bl = !this.itemRenderState.isSideLit();
|
||||||
|
if (bl) {
|
||||||
|
this.draw();
|
||||||
|
DiffuseLighting.disableGuiDepthLighting();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV);
|
||||||
|
this.draw();
|
||||||
|
if (bl) {
|
||||||
|
DiffuseLighting.enableGuiDepthLighting();
|
||||||
|
}
|
||||||
|
} catch (Throwable var11) {
|
||||||
|
CrashReport crashReport = CrashReport.create(var11, "Rendering item");
|
||||||
|
CrashReportSection crashReportSection = crashReport.addElement("Item being rendered");
|
||||||
|
crashReportSection.add("Item Type", () -> {
|
||||||
|
return String.valueOf(stack.getItem());
|
||||||
|
});
|
||||||
|
crashReportSection.add("Item Components", () -> {
|
||||||
|
return String.valueOf(stack.getComponents());
|
||||||
|
});
|
||||||
|
crashReportSection.add("Item Foil", () -> {
|
||||||
|
return String.valueOf(stack.hasGlint());
|
||||||
|
});
|
||||||
|
throw new CrashException(crashReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.matrices.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawSpriteStretched(Sprite sprite, int x, int y, int width, int height) {
|
||||||
|
this.drawSpriteStretched(sprite, x, y, width, height, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawSpriteStretched(Sprite sprite, int x, int y, int width, int height, int color) {
|
||||||
|
if (width != 0 && height != 0) {
|
||||||
|
this.drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV(), color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,37 +3,107 @@ package org.saturnclient.ui2;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||||
|
import org.saturnclient.ui2.anim.Animation;
|
||||||
|
import org.saturnclient.ui2.anim.SlideXAbsolute;
|
||||||
|
import org.saturnclient.ui2.components.ElementRenderer;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gl.PostEffectProcessor;
|
||||||
|
import net.minecraft.client.gui.CubeMapRenderer;
|
||||||
import net.minecraft.client.gui.DrawContext;
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
import net.minecraft.client.gui.RotatingCubeMapRenderer;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.client.render.DefaultFramebufferSet;
|
||||||
|
import net.minecraft.client.util.Pool;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class SaturnScreen extends Screen {
|
public abstract class SaturnScreen extends Screen {
|
||||||
|
private final Pool pool = new Pool(3);
|
||||||
protected List<Element> elements = new ArrayList<>();
|
protected List<Element> elements = new ArrayList<>();
|
||||||
|
public int blurDuration = 700;
|
||||||
|
public float blurProgress = 0.0f;
|
||||||
|
public int backgroundBlur = 10;
|
||||||
|
|
||||||
|
protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(
|
||||||
|
Identifier.of("saturnclient", "textures/gui/title/background/panorama"));
|
||||||
|
|
||||||
|
public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER);
|
||||||
|
}
|
||||||
|
|
||||||
public SaturnScreen(String title) {
|
public SaturnScreen(String title) {
|
||||||
super(Text.literal(title));
|
super(Text.literal(title));
|
||||||
ThemeManager.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(Element element) {
|
public void draw(Element element) {
|
||||||
synchronized (elements) {
|
synchronized (elements) {
|
||||||
elements.add(element);
|
elements.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element.animation != null) {
|
||||||
|
element.animation.init(element);
|
||||||
|
|
||||||
|
Animation.execute((Float progress) -> {
|
||||||
|
element.animation.tick(progress, element);
|
||||||
|
}, element.animation.duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.duration != null) {
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
Animation fadeOut = new SlideXAbsolute(700, -(width - element.x));
|
||||||
|
Thread.sleep(element.duration);
|
||||||
|
fadeOut.init(element);
|
||||||
|
Animation.executeSync((Float progress) -> {
|
||||||
|
fadeOut.tick(progress, element);
|
||||||
|
}, fadeOut.duration);
|
||||||
|
synchronized (elements) {
|
||||||
|
elements.remove(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void init() {
|
protected void init() {
|
||||||
|
elements.clear();
|
||||||
|
width *= 2;
|
||||||
|
height *= 2;
|
||||||
ui(); // abstraction to render the saturn ui and also render extra stuff here
|
ui(); // abstraction to render the saturn ui and also render extra stuff here
|
||||||
|
|
||||||
|
Animation.execute((Float progress) -> {
|
||||||
|
blurProgress = progress;
|
||||||
|
}, blurDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ui() {
|
public abstract void ui();
|
||||||
}
|
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||||
|
mouseX *= 2;
|
||||||
|
mouseY *= 2;
|
||||||
|
|
||||||
|
if (client.world == null && client.getCurrentServerEntry() == null) {
|
||||||
|
ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect(
|
||||||
|
Identifier.ofVanilla("blur"),
|
||||||
|
DefaultFramebufferSet.MAIN_ONLY);
|
||||||
|
if (postEffectProcessor != null) {
|
||||||
|
postEffectProcessor.setUniforms("Radius", backgroundBlur * blurProgress);
|
||||||
|
postEffectProcessor.render(this.client.getFramebuffer(), this.pool);
|
||||||
|
}
|
||||||
|
|
||||||
// We are using a Abstracted RenderScope because older minecraft versions don't
|
// We are using a Abstracted RenderScope because older minecraft versions don't
|
||||||
// use DrawContext
|
// use DrawContext
|
||||||
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||||
@@ -41,32 +111,51 @@ public class SaturnScreen extends Screen {
|
|||||||
|
|
||||||
renderScope.matrices.push();
|
renderScope.matrices.push();
|
||||||
|
|
||||||
for (Element element : elements) {
|
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
||||||
renderScope.matrices.push();
|
|
||||||
renderScope.matrices.translate(element.x, element.y, 0);
|
ElementRenderer.render(new ArrayList<>(elements), renderScope, mouseX, mouseY);
|
||||||
element.render(renderScope, new RenderContext(mouseX, mouseY, element));
|
|
||||||
renderScope.matrices.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderScope.matrices.pop();
|
renderScope.matrices.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
if (button == 0) {
|
mouseX *= 2;
|
||||||
for (Element element : new ArrayList<>(elements)) {
|
mouseY *= 2;
|
||||||
element.focused = false;
|
|
||||||
|
|
||||||
int adjustedMouseX = (int) mouseX - element.x;
|
ElementRenderer.mouseClicked(elements, mouseX, mouseY, button);
|
||||||
int adjustedMouseY = (int) mouseY - element.y;
|
|
||||||
|
|
||||||
if (Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width, element.height)) {
|
|
||||||
element.focused = true;
|
|
||||||
element.click(adjustedMouseX, adjustedMouseY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseScrolled(
|
||||||
|
double mouseX,
|
||||||
|
double mouseY,
|
||||||
|
double horizontalAmount,
|
||||||
|
double verticalAmount) {
|
||||||
|
mouseX *= 2;
|
||||||
|
mouseY *= 2;
|
||||||
|
|
||||||
|
ElementRenderer.mouseScrolled(elements, mouseX, mouseY, horizontalAmount, verticalAmount);
|
||||||
|
|
||||||
|
return super.mouseScrolled(
|
||||||
|
mouseX,
|
||||||
|
mouseY,
|
||||||
|
horizontalAmount,
|
||||||
|
verticalAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resize(MinecraftClient client, int width, int height) {
|
||||||
|
elements.clear();
|
||||||
|
super.resize(client, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
ElementRenderer.keyPressed(elements, keyCode, scanCode, modifiers);
|
||||||
|
|
||||||
|
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,55 @@
|
|||||||
package org.saturnclient.ui2;
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
public static boolean isHovering(int mouseX, int mouseY, int elementWidth, int elementHeight) {
|
public static boolean isHovering(int mouseX, int mouseY, int elementWidth, int elementHeight, float elementScale) {
|
||||||
return mouseX >= 0 &&
|
return mouseX >= 0 &&
|
||||||
mouseX <= elementWidth &&
|
mouseX <= (elementWidth * elementScale) &&
|
||||||
mouseY >= 0 &&
|
mouseY >= 0 &&
|
||||||
mouseY <= elementHeight;
|
mouseY <= (elementHeight * elementScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char getCharFromKey(int keyCode, int modifiers) {
|
||||||
|
boolean shift = (modifiers & GLFW.GLFW_MOD_SHIFT) != 0;
|
||||||
|
|
||||||
|
// A-Z
|
||||||
|
if (keyCode >= GLFW.GLFW_KEY_A && keyCode <= GLFW.GLFW_KEY_Z) {
|
||||||
|
return (char) (shift
|
||||||
|
? 'A' + (keyCode - GLFW.GLFW_KEY_A)
|
||||||
|
: 'a' + (keyCode - GLFW.GLFW_KEY_A));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0-9
|
||||||
|
if (keyCode >= GLFW.GLFW_KEY_0 && keyCode <= GLFW.GLFW_KEY_9) {
|
||||||
|
return shift
|
||||||
|
? ")!@#$%^&*(".charAt(keyCode - GLFW.GLFW_KEY_0)
|
||||||
|
: (char) ('0' + (keyCode - GLFW.GLFW_KEY_0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special characters
|
||||||
|
return switch (keyCode) {
|
||||||
|
case GLFW.GLFW_KEY_SPACE -> ' ';
|
||||||
|
case GLFW.GLFW_KEY_PERIOD -> shift ? '>' : '.';
|
||||||
|
case GLFW.GLFW_KEY_COMMA -> shift ? '<' : ',';
|
||||||
|
case GLFW.GLFW_KEY_MINUS -> shift ? '_' : '-';
|
||||||
|
case GLFW.GLFW_KEY_EQUAL -> shift ? '+' : '=';
|
||||||
|
case GLFW.GLFW_KEY_SEMICOLON -> shift ? ':' : ';';
|
||||||
|
case GLFW.GLFW_KEY_APOSTROPHE -> shift ? '"' : '\'';
|
||||||
|
case GLFW.GLFW_KEY_SLASH -> shift ? '?' : '/';
|
||||||
|
case GLFW.GLFW_KEY_BACKSLASH -> shift ? '|' : '\\';
|
||||||
|
case GLFW.GLFW_KEY_LEFT_BRACKET -> shift ? '{' : '[';
|
||||||
|
case GLFW.GLFW_KEY_RIGHT_BRACKET -> shift ? '}' : ']';
|
||||||
|
case GLFW.GLFW_KEY_GRAVE_ACCENT -> shift ? '~' : '`';
|
||||||
|
default -> '\0';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getOrNull(List<T> list, int index) {
|
||||||
|
SaturnClient.LOGGER.info("Accessing index {} in list of size {}", index, list.size());
|
||||||
|
return (index >= 0 && index < list.size()) ? list.get(index) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public abstract class Animation {
|
||||||
|
public int duration;
|
||||||
|
|
||||||
|
Animation(int duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void tick(float progress, Element element);
|
||||||
|
public abstract void init(Element element);
|
||||||
|
|
||||||
|
public static void execute(Consumer<Float> tick, int duration) {
|
||||||
|
new Thread(() -> {
|
||||||
|
Function<Double, Double> curveFunction = Curve::easeInOutCubic;
|
||||||
|
float progress = 0.0f;
|
||||||
|
double incremental = (1000 - duration) / 10000.0;
|
||||||
|
|
||||||
|
for (int i = 0; i <= 100; i++) {
|
||||||
|
float newProgress = (float) (double) curveFunction.apply(i / 100.0);
|
||||||
|
|
||||||
|
while (Math.abs(newProgress - progress) > 1e-6) {
|
||||||
|
if (progress < newProgress) {
|
||||||
|
progress += incremental;
|
||||||
|
if (progress > newProgress) progress = newProgress;
|
||||||
|
} else {
|
||||||
|
progress -= incremental;
|
||||||
|
if (progress < newProgress) progress = newProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
tick.accept(newProgress);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(duration / 100);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void executeSync(Consumer<Float> tick, int duration) {
|
||||||
|
Function<Double, Double> curveFunction = Curve::easeInOutCubic;
|
||||||
|
float progress = 0.0f;
|
||||||
|
double incremental = (1000 - duration) / 10000.0;
|
||||||
|
|
||||||
|
for (int i = 0; i <= 100; i++) {
|
||||||
|
float newProgress = (float) (double) curveFunction.apply(i / 100.0);
|
||||||
|
|
||||||
|
while (Math.abs(newProgress - progress) > 1e-6) {
|
||||||
|
if (progress < newProgress) {
|
||||||
|
progress += incremental;
|
||||||
|
if (progress > newProgress) progress = newProgress;
|
||||||
|
} else {
|
||||||
|
progress -= incremental;
|
||||||
|
if (progress < newProgress) progress = newProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
tick.accept(newProgress);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(duration / 100);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
public class Curve {
|
||||||
|
public static double easeOutCubic(double x) {
|
||||||
|
return 1 - Math.pow(1 - x, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double easeInOutCubic(double x) {
|
||||||
|
return (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double easeInOutCubicReverse(double x) {
|
||||||
|
return -(x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double easeInOutBack(double x) {
|
||||||
|
double c1 = 1.70158;
|
||||||
|
double c2 = c1 * 1.525;
|
||||||
|
|
||||||
|
if (x < 0.5) {
|
||||||
|
return (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2;
|
||||||
|
} else {
|
||||||
|
return (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (2 * x - 2) + c2) + 2) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public class Fade extends Animation {
|
||||||
|
float targetOpacity;
|
||||||
|
|
||||||
|
public Fade(int duration) {
|
||||||
|
super(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(float progress, Element element) {
|
||||||
|
element.opacity = targetOpacity * progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Element element) {
|
||||||
|
targetOpacity = element.opacity;
|
||||||
|
element.opacity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public class FadeOut extends Animation {
|
||||||
|
float targetOpacity;
|
||||||
|
|
||||||
|
public FadeOut(int duration) {
|
||||||
|
super(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(float progress, Element element) {
|
||||||
|
element.opacity = targetOpacity - progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Element element) {
|
||||||
|
targetOpacity = element.opacity;
|
||||||
|
// element.opacity = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public class SlideX extends Animation {
|
||||||
|
int offset = 20;
|
||||||
|
int maxOffset = 20;
|
||||||
|
int elementX;
|
||||||
|
|
||||||
|
public SlideX(int duration) {
|
||||||
|
super(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlideX(int duration, int offset) {
|
||||||
|
super(duration);
|
||||||
|
this.offset = offset;
|
||||||
|
this.maxOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlideX(int duration, int offset, int maxOffset) {
|
||||||
|
super(duration);
|
||||||
|
this.offset = offset;
|
||||||
|
this.maxOffset = maxOffset; // ✅ fixed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(float progress, Element element) {
|
||||||
|
element.x = elementX + (int) (offset * progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Element element) {
|
||||||
|
element.x -= offset;
|
||||||
|
elementX = element.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public class SlideXAbsolute extends Animation {
|
||||||
|
int offset = 20;
|
||||||
|
int maxOffset = 20;
|
||||||
|
int elementX;
|
||||||
|
|
||||||
|
public SlideXAbsolute(int duration) {
|
||||||
|
super(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlideXAbsolute(int duration, int offset) {
|
||||||
|
super(duration);
|
||||||
|
this.offset = offset;
|
||||||
|
this.maxOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlideXAbsolute(int duration, int offset, int maxOffset) {
|
||||||
|
super(duration);
|
||||||
|
this.offset = offset;
|
||||||
|
this.maxOffset = maxOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(float progress, Element element) {
|
||||||
|
element.x = elementX + (int) (offset * progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Element element) {
|
||||||
|
elementX = element.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public class SlideY extends Animation {
|
||||||
|
int offset = 20;
|
||||||
|
int maxOffset = 20;
|
||||||
|
int elementY;
|
||||||
|
|
||||||
|
public SlideY(int duration) {
|
||||||
|
super(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlideY(int duration, int offset) {
|
||||||
|
super(duration);
|
||||||
|
|
||||||
|
this.offset = offset;
|
||||||
|
this.maxOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlideY(int duration, int offset, int maxOffset) {
|
||||||
|
super(duration);
|
||||||
|
|
||||||
|
this.offset = offset;
|
||||||
|
this.maxOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(float progress, Element element) {
|
||||||
|
element.y = elementY + (int) (offset * progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Element element) {
|
||||||
|
element.y -= offset;
|
||||||
|
elementY = element.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package org.saturnclient.ui2.components;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class CosmeticPreview extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("CosmeticPreview", "selected", "hovering");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x89000000));
|
||||||
|
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||||
|
private static Property<Integer> padding = theme.property("padding", Property.integer(14));
|
||||||
|
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||||
|
|
||||||
|
static {}
|
||||||
|
|
||||||
|
Identifier sprite;
|
||||||
|
private Runnable onClick;
|
||||||
|
private boolean isSelected;
|
||||||
|
|
||||||
|
public CosmeticPreview(boolean isSelected, Identifier sprite, Runnable onClick) {
|
||||||
|
this.sprite = sprite;
|
||||||
|
this.onClick = onClick;
|
||||||
|
this.isSelected = isSelected;
|
||||||
|
|
||||||
|
this.width = 50;
|
||||||
|
this.height = 111;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
if (ctx.isHovering()) {
|
||||||
|
theme.setState("hovering");
|
||||||
|
} else if (isSelected) {
|
||||||
|
theme.setState("selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||||
|
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
|
int texWidth = width - padding.value;
|
||||||
|
int texHeight = height - padding.value;
|
||||||
|
|
||||||
|
renderScope.drawTexture(sprite, padding.value / 2, padding.value / 2, 0, 0, texWidth, texHeight, fgColor.value);
|
||||||
|
|
||||||
|
theme.setState(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
if (onClick != null) {
|
||||||
|
onClick.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package org.saturnclient.ui2.components;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.Utils;
|
||||||
|
import org.saturnclient.ui2.anim.Animation;
|
||||||
|
|
||||||
|
public class ElementRenderer {
|
||||||
|
public static void draw(List<Element> elements, Element element) {
|
||||||
|
synchronized (elements) {
|
||||||
|
elements.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.animation != null) {
|
||||||
|
element.animation.init(element);
|
||||||
|
|
||||||
|
Animation.execute((Float progress) -> {
|
||||||
|
element.animation.tick(progress, element);
|
||||||
|
}, element.animation.duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void render(List<Element> elements, RenderScope renderScope, int mouseX, int mouseY) {
|
||||||
|
for (Element element : elements) {
|
||||||
|
renderScope.matrices.push();
|
||||||
|
renderScope.setOpacity(element.opacity);
|
||||||
|
renderScope.matrices.translate(element.x, element.y, 0);
|
||||||
|
renderScope.matrices.scale(element.scale, element.scale, 1.0f);
|
||||||
|
element.render(renderScope, new ElementContext(mouseX, mouseY, element));
|
||||||
|
renderScope.matrices.pop();
|
||||||
|
renderScope.setRenderLayer(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void mouseClicked(List<Element> elements, double mouseX, double mouseY, int button) {
|
||||||
|
if (button == 0) {
|
||||||
|
for (Element element : new ArrayList<>(elements)) {
|
||||||
|
element.focused = false;
|
||||||
|
|
||||||
|
int adjustedMouseX = (int) mouseX - element.x;
|
||||||
|
int adjustedMouseY = (int) mouseY - element.y;
|
||||||
|
|
||||||
|
if (element.opacity > 0 && Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width, element.height, element.scale)) {
|
||||||
|
element.focused = true;
|
||||||
|
element.click((int) (adjustedMouseX * element.scale), (int) (adjustedMouseY * element.scale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void mouseScrolled(
|
||||||
|
List<Element> elements,
|
||||||
|
double mouseX,
|
||||||
|
double mouseY,
|
||||||
|
double horizontalAmount,
|
||||||
|
double verticalAmount) {
|
||||||
|
for (Element element : new ArrayList<>(elements)) {
|
||||||
|
if (Utils.isHovering((int) mouseX - element.x, (int) mouseY - element.y, element.width, element.height, element.scale)) {
|
||||||
|
element.scroll(
|
||||||
|
(int) mouseX - element.x,
|
||||||
|
(int) mouseY - element.y,
|
||||||
|
horizontalAmount,
|
||||||
|
verticalAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void keyPressed(List<Element> elements, int keyCode, int scanCode, int modifiers) {
|
||||||
|
for (Element element : new ArrayList<>(elements)) {
|
||||||
|
if (element.focused && element.opacity > 0) {
|
||||||
|
element.keyPressed(keyCode, scanCode, modifiers);
|
||||||
|
|
||||||
|
char typedChar = Utils.getCharFromKey(keyCode, modifiers);
|
||||||
|
if (typedChar != '\0') {
|
||||||
|
element.charTyped(typedChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package org.saturnclient.ui2.components;
|
||||||
|
|
||||||
|
import org.saturnclient.modules.Module;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.Utils;
|
||||||
|
import org.saturnclient.ui2.screens.ConfigEditor;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
|
||||||
|
public class SaturnModule extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Module", "enabled", "hovering");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg", Property.color(0xFF1d202d));
|
||||||
|
private static Property<Integer> fgColor = theme.property("fg", Property.color(0xFFA1A2B8));
|
||||||
|
private static Property<Integer> iconFg = theme.property("icon-fg", Property.color(0xFFA1A2B8));
|
||||||
|
private static Property<Integer> iconBg = theme.property("icon-bg", Property.color(0xFF2e3248));
|
||||||
|
private static Property<Integer> tagBg = theme.property("tag-bg", Property.color(0xFF2e3248));
|
||||||
|
private static Property<Integer> iconRadius = theme.property("icon-radius", Property.color(10));
|
||||||
|
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||||
|
private static Property<Integer> radius = theme.property("radius", Property.color(10));
|
||||||
|
|
||||||
|
static {
|
||||||
|
theme.propertyStateDefault("enabled", "bg", 0xFF1d202d);
|
||||||
|
theme.propertyStateDefault("enabled", "icon-bg", 0xFF845eee);
|
||||||
|
theme.propertyStateDefault("hovering", "fg", 0xFF845eee);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Module mod;
|
||||||
|
|
||||||
|
public SaturnModule(Module mod) {
|
||||||
|
this.mod = mod;
|
||||||
|
this.width = 160;
|
||||||
|
this.height = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
int p = 10;
|
||||||
|
int s = 14;
|
||||||
|
boolean settingsHover = false;
|
||||||
|
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
|
if (mod.isEnabled()) {
|
||||||
|
theme.setState("enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.isHovering(width - s - p - 5, height - s - p - 5, s + 10, s + 10)) {
|
||||||
|
settingsHover = true;
|
||||||
|
} else if (ctx.isHovering()) {
|
||||||
|
theme.applyState("hovering");
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, radius.value, bgColor.value);
|
||||||
|
|
||||||
|
int h = height-(p * 2);
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(p, p, h, h, iconRadius.value, iconBg.value);
|
||||||
|
|
||||||
|
renderScope.drawTexture(mod.getIconTexture(), p + (p / 2), p + (p / 2), 0, 0, h - p, h - p, iconFg.value);
|
||||||
|
|
||||||
|
renderScope.drawText(0.6f, mod.getName(), p+h+4, p + 1, font.value, fgColor.value);
|
||||||
|
|
||||||
|
renderScope.drawText(0.35f, mod.getVersion(), width - p - (int) (Fonts.getWidth(mod.getVersion(), font.value) * 0.35f), p + 1, font.value, fgColor.value);
|
||||||
|
|
||||||
|
int xt = p + h + 4;
|
||||||
|
for (String tag : mod.getTags()) {
|
||||||
|
int xtb = (int) (Fonts.getWidth(tag, font.value) * 0.4f);
|
||||||
|
renderScope.drawRoundedRectangle(xt, p + (h/2), xtb + 6, 12, 5, tagBg.value);
|
||||||
|
renderScope.drawText(0.4f, tag, xt+2, p + (h/2) + 3, font.value, fgColor.value);
|
||||||
|
xt += xtb + 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsHover) {
|
||||||
|
theme.setState("hovering");
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.drawTexture(Textures.SETTINGS, width - s - p, height - s - p, 0, 0, s, s, fgColor.value);
|
||||||
|
|
||||||
|
theme.setState(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
int p = 10;
|
||||||
|
int s = 14;
|
||||||
|
|
||||||
|
if (Utils.isHovering(mouseX - (width - s - p - 5), mouseY - (height - s - p - 5), s + 10, s + 10, 1.0f)) {
|
||||||
|
SaturnClient.client.setScreen(new ConfigEditor(mod.getConfig()));
|
||||||
|
} else {
|
||||||
|
mod.setEnabled(!mod.isEnabled());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
package org.saturnclient.ui2.components;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.Utils;
|
||||||
|
import org.saturnclient.ui2.screens.ConfigEditor;
|
||||||
|
import org.saturnclient.ui2.screens.ModMenu;
|
||||||
|
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||||
|
import org.saturnclient.ui2.screens.store.CloakStore;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class Sidebar extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("SideBar", "hovering");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
||||||
|
private static Property<Integer> iconFg = theme.property("icon-fg", Property.color(0xFFFFFFFF));
|
||||||
|
private static Property<Integer> iconBg = theme.property("icon-bg", Property.color(0x00000000));
|
||||||
|
|
||||||
|
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||||
|
private static Property<Integer> iconRadius = theme.property("icon-radius", Property.integer(10));
|
||||||
|
private static Property<Integer> padding = theme.property("padding", Property.integer(10));
|
||||||
|
|
||||||
|
static {
|
||||||
|
theme.propertyStateDefault("hovering", "icon-bg", -7643914);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SidebarComponent {
|
||||||
|
Runnable onClick;
|
||||||
|
boolean end;
|
||||||
|
Identifier sprite;
|
||||||
|
|
||||||
|
public SidebarComponent(Identifier sprite, Runnable onClick, boolean end) {
|
||||||
|
this.onClick = onClick;
|
||||||
|
this.end = end;
|
||||||
|
this.sprite = sprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Runnable onClose;
|
||||||
|
SidebarComponent[] components = {
|
||||||
|
new Sidebar.SidebarComponent(Textures.MODS_TAB, () -> {
|
||||||
|
SaturnClient.client.setScreen(new ModMenu());
|
||||||
|
}, false),
|
||||||
|
new Sidebar.SidebarComponent(Textures.SETTINGS, () -> {
|
||||||
|
SaturnClient.client.setScreen(new ConfigEditor(SaturnClientConfig.config));
|
||||||
|
}, false),
|
||||||
|
|
||||||
|
new Sidebar.SidebarComponent(Textures.SHIRT, () -> {
|
||||||
|
SaturnClient.client.setScreen(new CloakMenu());
|
||||||
|
}, false),
|
||||||
|
|
||||||
|
new Sidebar.SidebarComponent(Textures.CLOSE, () -> {
|
||||||
|
onClose.run();
|
||||||
|
}, true),
|
||||||
|
|
||||||
|
new Sidebar.SidebarComponent(Textures.STORE, () -> {
|
||||||
|
SaturnClient.client.setScreen(new CloakStore());
|
||||||
|
}, true),
|
||||||
|
};
|
||||||
|
int active = 0;
|
||||||
|
|
||||||
|
public Sidebar(int active, Runnable onClose) {
|
||||||
|
this.width = 30;
|
||||||
|
this.height = 350;
|
||||||
|
this.active = active;
|
||||||
|
this.onClose = onClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
int topRow = 0;
|
||||||
|
int bottomRow = 0;
|
||||||
|
|
||||||
|
int gap = 5; // 5px gap between icons
|
||||||
|
int sp = 30 - padding.value + gap;
|
||||||
|
int s = 30 - (padding.value * 2);
|
||||||
|
int s2 = s + padding.value;
|
||||||
|
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (SidebarComponent component : components) {
|
||||||
|
if (component.end) {
|
||||||
|
int y = (height - (sp * bottomRow)) - (s * 2);
|
||||||
|
if (ctx.isHovering(0, y - (padding.value / 2), s2, s2) || active == i) {
|
||||||
|
theme.setState("hovering");
|
||||||
|
} else {
|
||||||
|
theme.setState(null);
|
||||||
|
}
|
||||||
|
renderScope.drawRoundedRectangle(padding.value / 2, y - (padding.value / 2), s + padding.value, s + padding.value, iconRadius.value, iconBg.value);
|
||||||
|
renderScope.drawTexture(component.sprite, padding.value, y, 0, 0, s, s, iconFg.value);
|
||||||
|
bottomRow += 1;
|
||||||
|
} else {
|
||||||
|
int y = padding.value + (sp * topRow);
|
||||||
|
if (ctx.isHovering(0, y - (padding.value / 2), s2, s2) || active == i) {
|
||||||
|
theme.setState("hovering");
|
||||||
|
} else {
|
||||||
|
theme.setState(null);
|
||||||
|
}
|
||||||
|
renderScope.drawRoundedRectangle(padding.value / 2, y - (padding.value / 2), s + padding.value, s + padding.value, iconRadius.value, iconBg.value);
|
||||||
|
renderScope.drawTexture(component.sprite, padding.value, y, 0, 0, s, s, iconFg.value);
|
||||||
|
topRow += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
int topRow = 0;
|
||||||
|
int bottomRow = 0;
|
||||||
|
|
||||||
|
int gap = 5; // same 5px gap here
|
||||||
|
int sp = 30 - padding.value + gap;
|
||||||
|
int s = 30 - (padding.value * 2);
|
||||||
|
int s2 = s + padding.value;
|
||||||
|
|
||||||
|
for (SidebarComponent component : components) {
|
||||||
|
if (component.end) {
|
||||||
|
int y = (height - (sp * bottomRow)) - (s * 2);
|
||||||
|
if (Utils.isHovering(mouseX - (padding.value / 2), mouseY - (y - (padding.value / 2)), s2, s2, scale)) {
|
||||||
|
component.onClick.run();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bottomRow += 1;
|
||||||
|
} else {
|
||||||
|
int y = padding.value + (sp * topRow);
|
||||||
|
if (Utils.isHovering(mouseX - (padding.value / 2), mouseY - (y - (padding.value / 2)), s2, s2, scale)) {
|
||||||
|
component.onClick.run();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
topRow += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
-24
@@ -1,23 +1,31 @@
|
|||||||
package org.saturnclient.ui.components;
|
package org.saturnclient.ui2.components;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.saturnclient.ui.SaturnWidget;
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import net.minecraft.client.gui.DrawContext;
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
import net.minecraft.client.render.DiffuseLighting;
|
import net.minecraft.client.render.DiffuseLighting;
|
||||||
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
|
||||||
// If you think this code is bad, it's because it's written by Mojang
|
public class SkinPreview extends Element {
|
||||||
|
private boolean negativeAngle = false;
|
||||||
|
private float angle = 0.0f;
|
||||||
|
|
||||||
public class SkinPreview extends SaturnWidget {
|
public SkinPreview(float angle, boolean negativeAngle) {
|
||||||
public static void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, int size, float f, float mouseX,
|
this.angle = angle;
|
||||||
|
this.negativeAngle = negativeAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float f, float mouseX,
|
||||||
float mouseY, LivingEntity entity, float angle, boolean negativeAngle) {
|
float mouseY, LivingEntity entity, float angle, boolean negativeAngle) {
|
||||||
float g = (float) (x1 + x2) / 2.0F;
|
float g = (float) (x1 + x2) / 2.0F;
|
||||||
float h = (float) (y1 + y2) / 2.0F;
|
float h = (float) (y1 + y2) / 2.0F;
|
||||||
context.enableScissor(0, 6, x2, y2);
|
renderScope.enableScissor(0, 6, x2, y2);
|
||||||
float i = (float) Math.atan((double) ((g - mouseX) / 40.0F));
|
float i = (float) Math.atan((double) ((g - mouseX) / 40.0F));
|
||||||
float j = (float) Math.atan((double) ((h - mouseY) / 40.0F));
|
float j = (float) Math.atan((double) ((h - mouseY) / 40.0F));
|
||||||
Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F);
|
Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F);
|
||||||
@@ -28,15 +36,15 @@ public class SkinPreview extends SaturnWidget {
|
|||||||
float o = entity.headYaw;
|
float o = entity.headYaw;
|
||||||
entity.setYaw(angle);
|
entity.setYaw(angle);
|
||||||
entity.bodyYaw = angle;
|
entity.bodyYaw = angle;
|
||||||
entity.setPitch(-j * 20.0F);
|
entity.setPitch(-(j * 20.0F));
|
||||||
entity.headYaw = negativeAngle ? -i * 40.0F : i * 40.0F;
|
entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F);
|
||||||
entity.prevHeadYaw = entity.getHeadYaw();
|
entity.prevHeadYaw = entity.getHeadYaw();
|
||||||
entity.setCustomNameVisible(false);
|
entity.setCustomNameVisible(false);
|
||||||
|
|
||||||
float p = entity.getScale();
|
float p = entity.getScale();
|
||||||
Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F);
|
Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F);
|
||||||
float q = (float) size / p;
|
float q = (float) size / p;
|
||||||
drawEntity(context, g, h, q, vector3f, quaternionf, null, entity);
|
drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity);
|
||||||
|
|
||||||
entity.setCustomNameVisible(true);
|
entity.setCustomNameVisible(true);
|
||||||
entity.bodyYaw = k;
|
entity.bodyYaw = k;
|
||||||
@@ -44,36 +52,36 @@ public class SkinPreview extends SaturnWidget {
|
|||||||
entity.setPitch(m);
|
entity.setPitch(m);
|
||||||
entity.prevHeadYaw = n;
|
entity.prevHeadYaw = n;
|
||||||
entity.headYaw = o;
|
entity.headYaw = o;
|
||||||
context.disableScissor();
|
renderScope.disableScissor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawEntity(DrawContext context, float x, float y, float size, Vector3f vector3f,
|
public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f,
|
||||||
Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) {
|
Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) {
|
||||||
context.getMatrices().push();
|
renderScope.matrices.push();
|
||||||
context.getMatrices().translate((double) x, (double) y, 50.0);
|
renderScope.matrices.translate((double) x, (double) y, 50.0);
|
||||||
context.getMatrices().scale(size, size, -size);
|
renderScope.matrices.scale(size, size, -size);
|
||||||
context.getMatrices().translate(vector3f.x, vector3f.y, vector3f.z);
|
renderScope.matrices.translate(vector3f.x, vector3f.y, vector3f.z);
|
||||||
context.getMatrices().multiply(quaternionf);
|
renderScope.matrices.multiply(quaternionf);
|
||||||
context.draw();
|
renderScope.draw();
|
||||||
DiffuseLighting.method_34742();
|
DiffuseLighting.method_34742();
|
||||||
EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher();
|
EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher();
|
||||||
|
|
||||||
entityRenderDispatcher.setRenderShadows(false);
|
entityRenderDispatcher.setRenderShadows(false);
|
||||||
context.draw((vertexConsumers) -> {
|
renderScope.draw((vertexConsumers) -> {
|
||||||
entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, context.getMatrices(), vertexConsumers,
|
entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, renderScope.matrices, vertexConsumers,
|
||||||
15728880);
|
15728880);
|
||||||
});
|
});
|
||||||
context.draw();
|
renderScope.draw();
|
||||||
entityRenderDispatcher.setRenderShadows(true);
|
entityRenderDispatcher.setRenderShadows(true);
|
||||||
context.getMatrices().pop();
|
renderScope.matrices.pop();
|
||||||
DiffuseLighting.enableGuiDepthLighting();
|
DiffuseLighting.enableGuiDepthLighting();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(DrawContext context, boolean hovering, int mouseX, int mouseY) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
LivingEntity entity = SaturnClient.client.player;
|
LivingEntity entity = SaturnClient.client.player;
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
drawEntity(context, 0, 0, 75, 78, 30, 0.0625F, mouseX, mouseY, entity, -30.0f, true);
|
drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, negativeAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,246 @@
|
|||||||
|
package org.saturnclient.ui2.components.dialog;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.DrawContext;
|
||||||
|
|
||||||
|
public class ColorDialog extends SaturnScreen {
|
||||||
|
private Property<Integer> prop;
|
||||||
|
private SaturnScreen parent;
|
||||||
|
private static final int PICKER_WIDTH = 200;
|
||||||
|
private static final int PICKER_HEIGHT = 200;
|
||||||
|
private static final int SLIDER_WIDTH = 200;
|
||||||
|
private static final int SLIDER_HEIGHT = 10;
|
||||||
|
private static final int HUE_SLIDER_HEIGHT = 10;
|
||||||
|
private float hue = 0.0f;
|
||||||
|
|
||||||
|
private int selectedX = 0;
|
||||||
|
private int selectedY = 0;
|
||||||
|
|
||||||
|
private float opacity = 1.0f;
|
||||||
|
private boolean dragging = false;
|
||||||
|
|
||||||
|
public ColorDialog(Property<Integer> prop , SaturnScreen parent) {
|
||||||
|
super("Color Dialog");
|
||||||
|
this.prop = prop;
|
||||||
|
this.parent = parent;
|
||||||
|
|
||||||
|
int alpha = (prop.value >> 24) & 0xFF;
|
||||||
|
if (alpha == 0) alpha = 255; // fallback if no alpha specified
|
||||||
|
this.opacity = alpha / 255.0f;
|
||||||
|
syncFromColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ui() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
SaturnClient.client.setScreen(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||||
|
super.render(context, mouseX, mouseY, delta);
|
||||||
|
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||||
|
((DrawContextAccessor) context).getVertexConsumers());
|
||||||
|
|
||||||
|
renderScope.matrices.push();
|
||||||
|
|
||||||
|
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
||||||
|
|
||||||
|
int xStart = (width - PICKER_WIDTH) / 2;
|
||||||
|
int yStart = (height - PICKER_HEIGHT) / 2;
|
||||||
|
|
||||||
|
// Draw the HSV saturation/value square (with current hue)
|
||||||
|
for (int x = 0; x < PICKER_WIDTH; x++) {
|
||||||
|
for (int y = 0; y < PICKER_HEIGHT; y++) {
|
||||||
|
float saturation = x / (float) PICKER_WIDTH;
|
||||||
|
float value = 1.0f - y / (float) PICKER_HEIGHT;
|
||||||
|
int color = Color.HSBtoRGB(hue, saturation, value);
|
||||||
|
context.fill(xStart + x, yStart + y, xStart + x + 1, yStart + y + 1, 0xFF000000 | color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = (xStart + selectedX) - 4;
|
||||||
|
int y = (yStart + selectedY) - 4;
|
||||||
|
context.fill(x, y, x+8, y+8, 0xFF000000 | prop.value);
|
||||||
|
context.drawBorder(x, y, 8, 8, 0xFFffffff);
|
||||||
|
|
||||||
|
renderSlider(context, mouseX, mouseY, delta);
|
||||||
|
renderHueSlider(context);
|
||||||
|
|
||||||
|
renderScope.matrices.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderSlider(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||||
|
int xStart = (width - SLIDER_WIDTH) / 2;
|
||||||
|
int yStart = (height - SLIDER_HEIGHT - PICKER_HEIGHT) / 2 - 10;
|
||||||
|
|
||||||
|
// Draw slider background (left = transparent, right = white)
|
||||||
|
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
||||||
|
float localOpacity = x / (float) SLIDER_WIDTH;
|
||||||
|
int alpha = (int)(localOpacity * 255) & 0xFF;
|
||||||
|
int color = (alpha << 24) | (prop.value & 0xFFFFFF);
|
||||||
|
context.fill(xStart + x, yStart, xStart + x + 1, yStart + SLIDER_HEIGHT, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw current value as a marker (thin black line)
|
||||||
|
int knobX = xStart + (int)(opacity * SLIDER_WIDTH);
|
||||||
|
context.fill(knobX - 1, yStart - 2, knobX + 1, yStart + SLIDER_HEIGHT + 2, 0xFF000000);
|
||||||
|
|
||||||
|
// Draw opacity text
|
||||||
|
// context.drawText(textRenderer, String.format("Opacity: %.2f", opacity), xStart, yStart - 15, 0xFFFFFF, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderHueSlider(DrawContext context) {
|
||||||
|
int xStart = (width - SLIDER_WIDTH) / 2;
|
||||||
|
int yStart = (height + PICKER_HEIGHT) / 2 + 10;
|
||||||
|
|
||||||
|
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
||||||
|
float localHue = x / (float) SLIDER_WIDTH;
|
||||||
|
int color = Color.HSBtoRGB(localHue, 1.0f, 1.0f);
|
||||||
|
context.fill(xStart + x, yStart, xStart + x + 1, yStart + HUE_SLIDER_HEIGHT, 0xFF000000 | color);
|
||||||
|
}
|
||||||
|
|
||||||
|
int knobX = xStart + (int)(hue * SLIDER_WIDTH);
|
||||||
|
context.fill(knobX - 1, yStart - 2, knobX + 1, yStart + HUE_SLIDER_HEIGHT + 2, 0xFF000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
|
mouseX *= 2;
|
||||||
|
mouseY *= 2;
|
||||||
|
|
||||||
|
int xStart = (width - PICKER_WIDTH) / 2;
|
||||||
|
int yStart = (height - PICKER_HEIGHT) / 2;
|
||||||
|
|
||||||
|
int relX = (int) mouseX - xStart;
|
||||||
|
int relY = (int) mouseY - yStart;
|
||||||
|
|
||||||
|
if (relX >= 0 && relX < PICKER_WIDTH && relY >= 0 && relY < PICKER_HEIGHT) {
|
||||||
|
float saturation = relX / (float) PICKER_WIDTH;
|
||||||
|
float value = 1.0f - relY / (float) PICKER_HEIGHT;
|
||||||
|
prop.value = Color.HSBtoRGB(hue, saturation, value);
|
||||||
|
|
||||||
|
int alpha = (int)(opacity * 255) & 0xFF;
|
||||||
|
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
||||||
|
|
||||||
|
selectedX = relX;
|
||||||
|
selectedY = relY;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (isInSlider(mouseX, mouseY)) {
|
||||||
|
updateOpacity(mouseX);
|
||||||
|
dragging = true;
|
||||||
|
return true;
|
||||||
|
} else if (isInHueSlider(mouseX, mouseY)) {
|
||||||
|
updateHue(mouseX);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.mouseClicked(mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||||
|
dragging = false;
|
||||||
|
return super.mouseReleased(mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
||||||
|
mouseX *= 2;
|
||||||
|
mouseY *= 2;
|
||||||
|
|
||||||
|
if (isInHueSlider(mouseX, mouseY)) {
|
||||||
|
updateHue(mouseX);
|
||||||
|
return true;
|
||||||
|
} else if (dragging) {
|
||||||
|
updateOpacity(mouseX);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
int xStart = (width - PICKER_WIDTH) / 2;
|
||||||
|
int yStart = (height - PICKER_HEIGHT) / 2;
|
||||||
|
|
||||||
|
int relX = (int) mouseX - xStart;
|
||||||
|
int relY = (int) mouseY - yStart;
|
||||||
|
|
||||||
|
if (relX >= 0 && relX < PICKER_WIDTH && relY >= 0 && relY < PICKER_HEIGHT) {
|
||||||
|
float saturation = relX / (float) PICKER_WIDTH;
|
||||||
|
float value = 1.0f - relY / (float) PICKER_HEIGHT;
|
||||||
|
prop.value = Color.HSBtoRGB(hue, saturation, value);
|
||||||
|
|
||||||
|
int alpha = (int)(opacity * 255) & 0xFF;
|
||||||
|
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
||||||
|
|
||||||
|
selectedX = relX;
|
||||||
|
selectedY = relY;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInSlider(double mouseX, double mouseY) {
|
||||||
|
int xStart = (width - SLIDER_WIDTH) / 2;
|
||||||
|
int yStart = (height - SLIDER_HEIGHT - PICKER_HEIGHT) / 2 - 10;
|
||||||
|
return mouseX >= xStart && mouseX <= xStart + SLIDER_WIDTH &&
|
||||||
|
mouseY >= yStart && mouseY <= yStart + SLIDER_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInHueSlider(double mouseX, double mouseY) {
|
||||||
|
int xStart = (width - SLIDER_WIDTH) / 2;
|
||||||
|
int yStart = (height + PICKER_HEIGHT) / 2 + 10;
|
||||||
|
return mouseX >= xStart && mouseX <= xStart + SLIDER_WIDTH &&
|
||||||
|
mouseY >= yStart && mouseY <= yStart + HUE_SLIDER_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateOpacity(double mouseX) {
|
||||||
|
int xStart = (width - SLIDER_WIDTH) / 2;
|
||||||
|
float newOpacity = (float)((mouseX - xStart) / SLIDER_WIDTH);
|
||||||
|
opacity = Math.max(0.0f, Math.min(1.0f, newOpacity));
|
||||||
|
|
||||||
|
int alpha = (int)(opacity * 255) & 0xFF;
|
||||||
|
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHue(double mouseX) {
|
||||||
|
int xStart = (width - SLIDER_WIDTH) / 2;
|
||||||
|
float newHue = (float)((mouseX - xStart) / SLIDER_WIDTH);
|
||||||
|
hue = Math.max(0.0f, Math.min(1.0f, newHue));
|
||||||
|
|
||||||
|
float saturation = selectedX / (float) PICKER_WIDTH;
|
||||||
|
float value = 1.0f - selectedY / (float) PICKER_HEIGHT;
|
||||||
|
prop.value = Color.HSBtoRGB(hue, saturation, value);
|
||||||
|
|
||||||
|
int alpha = (int)(opacity * 255) & 0xFF;
|
||||||
|
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncFromColor() {
|
||||||
|
int rgb = prop.value & 0xFFFFFF;
|
||||||
|
float[] hsb = Color.RGBtoHSB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF, null);
|
||||||
|
|
||||||
|
this.hue = hsb[0];
|
||||||
|
|
||||||
|
float saturation = hsb[1];
|
||||||
|
float value = hsb[2];
|
||||||
|
|
||||||
|
this.selectedX = (int)(saturation * PICKER_WIDTH);
|
||||||
|
this.selectedY = (int)((1.0f - value) * PICKER_HEIGHT);
|
||||||
|
|
||||||
|
// Extract alpha and convert to opacity float
|
||||||
|
int alpha = (prop.value >> 24) & 0xFF;
|
||||||
|
if (alpha == 0) alpha = 255;
|
||||||
|
this.opacity = alpha / 255.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
|
public class FloatInput extends Input {
|
||||||
|
public Property<Float> prop;
|
||||||
|
|
||||||
|
public FloatInput(Property<Float> prop) {
|
||||||
|
this.width = 120;
|
||||||
|
this.height = Fonts.getHeight();
|
||||||
|
this.prop = prop;
|
||||||
|
this.text = String.valueOf(prop.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void charTyped(char chr) {
|
||||||
|
if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) {
|
||||||
|
if (text.equals("0") && cursorPosition == 1) {
|
||||||
|
text = "" + chr;
|
||||||
|
} else {
|
||||||
|
text = text.substring(0, cursorPosition) +
|
||||||
|
chr +
|
||||||
|
text.substring(cursorPosition);
|
||||||
|
|
||||||
|
try {
|
||||||
|
prop.value = text.isEmpty() ? 0 : Float.parseFloat(text);
|
||||||
|
cursorPosition++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void backspace() {
|
||||||
|
try {
|
||||||
|
if (text.length() == 0) {
|
||||||
|
text = "0";
|
||||||
|
cursorPosition = 1;
|
||||||
|
}
|
||||||
|
prop.value = Float.parseFloat(text);
|
||||||
|
ConfigManager.save();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkReset() {
|
||||||
|
if (prop.isReset) {
|
||||||
|
this.text = String.valueOf(prop.value);
|
||||||
|
this.cursorPosition = 0;
|
||||||
|
prop.isReset = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
|
import org.saturnclient.ui2.components.dialog.ColorDialog;
|
||||||
|
|
||||||
|
public class HexInput extends Element {
|
||||||
|
public Property<Integer> prop;
|
||||||
|
public SaturnScreen screen;
|
||||||
|
|
||||||
|
public HexInput(Property<Integer> prop, SaturnScreen screen) {
|
||||||
|
this.width = 58;
|
||||||
|
this.height = 20;
|
||||||
|
this.prop = prop;
|
||||||
|
this.scale = 0.8f;
|
||||||
|
this.screen = screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
SaturnClient.client.setScreen(new ColorDialog(prop, screen));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, 17, prop.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
|
public abstract class Input extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Input");
|
||||||
|
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||||
|
|
||||||
|
String text = "";
|
||||||
|
public int cursorPosition = 0;
|
||||||
|
public abstract void checkReset();
|
||||||
|
public abstract void backspace();
|
||||||
|
public boolean validateBackspace() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||||
|
if (cursorPosition > 0 && validateBackspace()) {
|
||||||
|
text = text.substring(0, cursorPosition - 1) +
|
||||||
|
text.substring(cursorPosition);
|
||||||
|
cursorPosition--;
|
||||||
|
backspace();
|
||||||
|
}
|
||||||
|
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
||||||
|
if (cursorPosition > 0) {
|
||||||
|
cursorPosition--;
|
||||||
|
}
|
||||||
|
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
||||||
|
if (cursorPosition < text.length()) {
|
||||||
|
cursorPosition++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
int scrollOffset = getScrollOffset();
|
||||||
|
String visibleText = text.substring(scrollOffset);
|
||||||
|
|
||||||
|
int newCursorPos = scrollOffset;
|
||||||
|
float textWidth = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < visibleText.length(); i++) {
|
||||||
|
textWidth = SaturnClient.client.textRenderer.getWidth(visibleText.substring(0, i + 1)) * 0.6f;
|
||||||
|
|
||||||
|
if (textWidth > mouseX) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
newCursorPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursorPosition = newCursorPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
checkReset();
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
||||||
|
|
||||||
|
int scrollOffset = getScrollOffset();
|
||||||
|
String visibleText = getVisibleText(scrollOffset);
|
||||||
|
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||||
|
renderScope.drawText(0.6f, visibleText, 4, 4, font.value, textColor);
|
||||||
|
|
||||||
|
if (focused) {
|
||||||
|
int cursorX = 4 +
|
||||||
|
(int) (Fonts.getWidth(visibleText.substring(0, cursorPosition - scrollOffset), font.value) * 0.6f);
|
||||||
|
|
||||||
|
renderScope.drawRect(cursorX, 2, 1, height - 4, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getScrollOffset() {
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
int maxWidth = width - 4; // Available width for text
|
||||||
|
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||||
|
String visibleText = text.substring(offset, cursorPosition);
|
||||||
|
if (Fonts.getWidth(visibleText, font.value) > maxWidth) {
|
||||||
|
offset++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getVisibleText(int scrollOffset) {
|
||||||
|
String visibleText = text.substring(scrollOffset);
|
||||||
|
|
||||||
|
// Ensure text does not overflow past the available width
|
||||||
|
for (int i = 1; i <= visibleText.length(); i++) {
|
||||||
|
if (Fonts.getWidth(visibleText.substring(0, i), font.value) > width - 4) {
|
||||||
|
return visibleText.substring(0, i - 1); // Trim overflow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return visibleText;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
|
public class IntInput extends Input {
|
||||||
|
public Property<Integer> prop;
|
||||||
|
|
||||||
|
public IntInput(Property<Integer> prop) {
|
||||||
|
this.width = 120;
|
||||||
|
this.height = Fonts.getHeight();
|
||||||
|
this.prop = prop;
|
||||||
|
this.text = String.valueOf(prop.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void charTyped(char chr) {
|
||||||
|
if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) {
|
||||||
|
if (text.equals("0") && cursorPosition == 1) {
|
||||||
|
text = "" + chr;
|
||||||
|
} else {
|
||||||
|
text = text.substring(0, cursorPosition) +
|
||||||
|
chr +
|
||||||
|
text.substring(cursorPosition);
|
||||||
|
|
||||||
|
try {
|
||||||
|
prop.value = text.isEmpty() ? 0 : Integer.parseInt(text);
|
||||||
|
cursorPosition++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void backspace() {
|
||||||
|
try {
|
||||||
|
if (text.length() == 0) {
|
||||||
|
text = "0";
|
||||||
|
cursorPosition = 1;
|
||||||
|
}
|
||||||
|
prop.value = Integer.parseInt(text);
|
||||||
|
ConfigManager.save();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkReset() {
|
||||||
|
if (prop.isReset) {
|
||||||
|
this.text = String.valueOf(prop.value);
|
||||||
|
this.cursorPosition = 0;
|
||||||
|
prop.isReset = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
|
public class KeybindingSelector extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Input");
|
||||||
|
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||||
|
Property<Integer> prop;
|
||||||
|
|
||||||
|
public KeybindingSelector(Property<Integer> prop) {
|
||||||
|
this.prop = prop;
|
||||||
|
this.width = 120;
|
||||||
|
this.height = Fonts.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
||||||
|
renderScope.drawText(0.6f, prop.value == -1 ? "<NONE>" :
|
||||||
|
GLFW.glfwGetKeyName(prop.value, GLFW.glfwGetKeyScancode(prop.value)).toUpperCase(),
|
||||||
|
4, 4, font.value, textColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||||
|
prop.value = -1;
|
||||||
|
} else {
|
||||||
|
prop.value = keyCode;
|
||||||
|
}
|
||||||
|
focused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.Utils;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
|
||||||
|
public class Select extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Toggle");
|
||||||
|
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xAAAAAA));
|
||||||
|
private static Property<Integer> arrowColor = theme.property("arrow-color", Property.color(0xff8B5CF6));
|
||||||
|
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||||
|
|
||||||
|
private Property<Integer> prop;
|
||||||
|
|
||||||
|
public Select(Property<Integer> prop) {
|
||||||
|
this.prop = prop;
|
||||||
|
this.width = 150;
|
||||||
|
this.height = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
|
renderScope.drawText(0.8f, "<", 0, 0, font.value, arrowColor.value);
|
||||||
|
|
||||||
|
String text = prop.getSelection();
|
||||||
|
|
||||||
|
renderScope.drawText(0.6f, text, (int) (width - ((float) Fonts.getWidth(text, font.value) * 0.6f)) / 2, 1, font.value, fgColor.value);
|
||||||
|
|
||||||
|
renderScope.drawText(0.8f, ">", width - 10, 0, font.value, arrowColor.value);
|
||||||
|
|
||||||
|
theme.setState(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
if (Utils.isHovering(mouseX - (width - 10), mouseY, 10, height, 1.0f)) {
|
||||||
|
prop.next();
|
||||||
|
} else if (Utils.isHovering(mouseX, mouseY, 10, height, 1.0f)) {
|
||||||
|
prop.prev();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
|
public class Toggle extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Toggle", "hovering", "enabled");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF808080));
|
||||||
|
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFF909090));
|
||||||
|
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(30));
|
||||||
|
|
||||||
|
static {
|
||||||
|
theme.propertyStateDefault("enabled", "bg-color", 0xaf8B5CF6);
|
||||||
|
theme.propertyStateDefault("enabled", "fg-color", 0xff8B5CF6);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Property<Boolean> prop;
|
||||||
|
|
||||||
|
public Toggle(Property<Boolean> prop) {
|
||||||
|
this.prop = prop;
|
||||||
|
this.width = 60;
|
||||||
|
this.height = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
theme.setState(null);
|
||||||
|
|
||||||
|
if (prop.value) {
|
||||||
|
theme.setState("enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.isHovering()) {
|
||||||
|
theme.applyState("hovering");
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30, fgColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
prop.value = !prop.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,43 +3,41 @@ package org.saturnclient.ui2.elements;
|
|||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.RenderContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.resources.Fonts;
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
public class Button extends Element {
|
public class Button extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Button", "hovering");
|
private static ThemeManager theme = new ThemeManager("Button", "hovering");
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0xFF000000));
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||||
private static Property<Boolean> bold = theme.property("fg-bold", new Property<Boolean>(false));
|
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||||
|
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||||
|
|
||||||
static {
|
static {
|
||||||
theme.propertyStateDefault("hovering", "fg-color", 0xFFFF0000);
|
theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
private Identifier font;
|
|
||||||
private Runnable onClick;
|
private Runnable onClick;
|
||||||
|
|
||||||
public Button(String text, Runnable onClick) {
|
public Button(String text, Runnable onClick) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.font = Fonts.getFont(bold.value);
|
|
||||||
this.onClick = onClick;
|
this.onClick = onClick;
|
||||||
this.dimensions(Fonts.getWidth(text, font)+ 25 , Fonts.getHeight() + 10);
|
this.dimensions(Fonts.getWidth(text, font.value) + 50, 38);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
if (ctx.isHovering()) {
|
if (ctx.isHovering()) {
|
||||||
theme.setState("hovering");
|
theme.setState("hovering");
|
||||||
} else {
|
} else {
|
||||||
theme.setState(null);
|
theme.setState(null);
|
||||||
}
|
}
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, bgColor.value);
|
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||||
|
|
||||||
renderScope.drawText(text, width / 2 - Fonts.getWidth(text, font) / 2, height / 2 - Fonts.getHeight() / 2, bold.value, fgColor.value);
|
// renderScope.drawText(text, (width - Fonts.getWidth(text, font)) / 2, (height - Fonts.getHeight()) / 2, bold.value, fgColor.value);
|
||||||
|
renderScope.drawText(text, Fonts.centerX(width, text, font.value), Fonts.centerY(height), font.value, fgColor.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class ClickableTexture extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("ClickableTexture", "hovering");
|
||||||
|
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||||
|
|
||||||
|
Identifier sprite;
|
||||||
|
private Runnable onClick;
|
||||||
|
|
||||||
|
public ClickableTexture(Identifier sprite, Runnable onClick) {
|
||||||
|
this.sprite = sprite;
|
||||||
|
this.onClick = onClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
if (ctx.isHovering()) {
|
||||||
|
theme.setState("hovering");
|
||||||
|
} else {
|
||||||
|
theme.setState(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height, fgColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
if (onClick != null) {
|
||||||
|
onClick.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class ImageTexture extends Element {
|
||||||
|
Identifier sprite;
|
||||||
|
|
||||||
|
public ImageTexture(Identifier sprite) {
|
||||||
|
this.sprite = sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.anim.SlideX;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
|
|
||||||
|
public class Notification extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Notification");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
||||||
|
private static Property<Integer> error = theme.property("error", Property.color(0xFFbf212f));
|
||||||
|
private static Property<Integer> info = theme.property("info", Property.color(0xFF264b96));
|
||||||
|
private static Property<Integer> success = theme.property("success", Property.color(0xFF27b376));
|
||||||
|
|
||||||
|
public static enum NotificationKind {
|
||||||
|
Error,
|
||||||
|
Info,
|
||||||
|
Success,
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationKind kind;
|
||||||
|
String text;
|
||||||
|
String title;
|
||||||
|
|
||||||
|
public Notification(int width, int height, NotificationKind kind, String title, String text) {
|
||||||
|
this.kind = kind;
|
||||||
|
this.text = text;
|
||||||
|
this.title = title;
|
||||||
|
this.width = (int) Math.max(Fonts.getWidth(text, 1) * 0.6f, Fonts.getWidth(title, 1)) + 20;
|
||||||
|
this.height = 50;
|
||||||
|
this.x = width - this.width - 15;
|
||||||
|
this.y = height - this.height - 15;
|
||||||
|
this.animation = new SlideX(700, -width);
|
||||||
|
this.duration = 3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, 10, bgColor.value);
|
||||||
|
switch (kind) {
|
||||||
|
case Error:
|
||||||
|
renderScope.drawTexture(Textures.CIRCLE_X, 9, 9, 0, 0, 15, 15, error.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Info:
|
||||||
|
renderScope.drawTexture(Textures.INFO, 9, 9, 0, 0, 15, 15, info.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Success:
|
||||||
|
renderScope.drawTexture(Textures.CHECK, 9, 9, 0, 0, 15, 15, success.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
renderScope.drawText(0.7f, title, 32, 10, 1, -1);
|
||||||
|
renderScope.drawText(0.5f, text, 32, 28, 1, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.components.ElementRenderer;
|
||||||
|
|
||||||
|
public class Scroll extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Scroll");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
||||||
|
private static Property<Integer> scrollBarColor = theme.property("scrollbar-color", Property.color(-7643914));
|
||||||
|
|
||||||
|
private static Property<Integer> scrollBarRadius = theme.property("scrollbar-radius", Property.integer(10));
|
||||||
|
private static Property<Integer> scrollBarWidth = theme.property("scrollbar-width", Property.integer(5));
|
||||||
|
private static Property<Integer> scrollBarPadding = theme.property("scrollbar-padding", Property.integer(5));
|
||||||
|
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||||
|
|
||||||
|
int padding = 0;
|
||||||
|
|
||||||
|
protected List<Element> children = new ArrayList<>();
|
||||||
|
int scroll = 0;
|
||||||
|
int maxScroll = 0;
|
||||||
|
|
||||||
|
public Scroll(int padding) {
|
||||||
|
this.padding = padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||||
|
|
||||||
|
renderScope.enableScissor(padding, padding, width - padding, height - padding);
|
||||||
|
renderScope.matrices.push();
|
||||||
|
renderScope.matrices.translate(padding, (-scroll) + padding, 0);
|
||||||
|
ElementRenderer.render(children, renderScope, ctx.mouseX - padding, ctx.mouseY - padding + scroll);
|
||||||
|
renderScope.matrices.pop();
|
||||||
|
renderScope.disableScissor();
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(width - scrollBarWidth.value - scrollBarPadding.value, calculateScrollBarY(), scrollBarWidth.value, calculateScrollBarHeight(), scrollBarRadius.value, scrollBarColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) {
|
||||||
|
scroll -= verticalAmount;
|
||||||
|
if (scroll < 0) {
|
||||||
|
scroll = 0;
|
||||||
|
} else if (scroll > maxScroll) {
|
||||||
|
scroll = maxScroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
ElementRenderer.mouseClicked(children, mouseX - padding, mouseY - padding + scroll, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Element element) {
|
||||||
|
children.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element dimensions(int width, int height) {
|
||||||
|
for (Element element : children) {
|
||||||
|
maxScroll = Math.max(maxScroll, element.y + element.height - height);
|
||||||
|
}
|
||||||
|
return super.dimensions(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
int calculateScrollBarHeight() {
|
||||||
|
if (maxScroll <= 0) return height - (scrollBarPadding.value * 2); // No scrolling needed
|
||||||
|
return Math.max(20, (height * height) / (height + maxScroll)) - (scrollBarPadding.value * 2); // At least 20px tall
|
||||||
|
}
|
||||||
|
|
||||||
|
int calculateScrollBarY() {
|
||||||
|
int scrollBarHeight = calculateScrollBarHeight();
|
||||||
|
if (maxScroll <= 0) return scrollBarPadding.value;
|
||||||
|
return (scroll * (height - scrollBarHeight)) / maxScroll + scrollBarPadding.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
ElementRenderer.keyPressed(children, keyCode, scanCode, modifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.Utils;
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class TabMenu extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("TabMenu", "hovering", "selected");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
||||||
|
private static Property<Integer> iconFg = theme.property("icon-fg", Property.color(0xFFFFFFFF));
|
||||||
|
private static Property<Integer> iconBg = theme.property("icon-bg", Property.color(0x00000000));
|
||||||
|
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||||
|
|
||||||
|
static {
|
||||||
|
theme.propertyStateDefault("hovering", "icon-bg", -7643914);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TabMenuComponent {
|
||||||
|
Runnable onClick;
|
||||||
|
Identifier sprite;
|
||||||
|
|
||||||
|
public TabMenuComponent(Identifier sprite, Runnable onClick) {
|
||||||
|
this.onClick = onClick;
|
||||||
|
this.sprite = sprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TabMenuComponent[] components;
|
||||||
|
public int selectedScreen = 0;
|
||||||
|
|
||||||
|
public TabMenu(int active, TabMenuComponent... components) {
|
||||||
|
this.components = components;
|
||||||
|
width = 25 * components.length + 6;
|
||||||
|
height = 30;
|
||||||
|
this.selectedScreen = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
|
for (TabMenuComponent component : components) {
|
||||||
|
int x = 25 * col + 5;
|
||||||
|
if (ctx.isHovering(x, 5, 20, 20) || selectedScreen == col) {
|
||||||
|
theme.setState("hovering");
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(x, 5, 20, 20, cornerRadius.value, iconBg.value);
|
||||||
|
renderScope.drawTexture(component.sprite, x + 5, 10, 0, 0, 10, 10, iconFg.value);
|
||||||
|
|
||||||
|
theme.setState(null);
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
int col = 0;
|
||||||
|
for (TabMenuComponent component : components) {
|
||||||
|
int x = 25 * col + 5;
|
||||||
|
if (Utils.isHovering(mouseX - x, mouseY - 5, 20, 20, 1.0f)) {
|
||||||
|
component.onClick.run();
|
||||||
|
}
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,27 @@
|
|||||||
package org.saturnclient.ui2.elements;
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.RenderContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
public class Text extends Element {
|
public class Text extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("Text");
|
||||||
|
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||||
|
public static Property<Integer> font = theme.property("font", Property.font(1));
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
public Text(String text) {
|
public Text(String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
width = Fonts.getWidth(text, font.value);
|
||||||
|
height = Fonts.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
renderScope.drawText(this.text, this.x, this.y, false, 0xFFFFFFFF);
|
renderScope.drawText(this.text, 0, 0, font.value, fgColor.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class TextureButton extends Element {
|
||||||
|
private static ThemeManager theme = new ThemeManager("TextureButton", "hovering");
|
||||||
|
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
||||||
|
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||||
|
private static Property<Integer> padding = theme.property("padding", Property.integer(14));
|
||||||
|
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee);
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier sprite;
|
||||||
|
private Runnable onClick;
|
||||||
|
|
||||||
|
public TextureButton(Identifier sprite, Runnable onClick) {
|
||||||
|
this.sprite = sprite;
|
||||||
|
this.onClick = onClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
if (ctx.isHovering()) {
|
||||||
|
theme.setState("hovering");
|
||||||
|
} else {
|
||||||
|
theme.setState(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||||
|
|
||||||
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
|
int texWidth = width - padding.value;
|
||||||
|
int texHeight = height - padding.value;
|
||||||
|
|
||||||
|
renderScope.drawTexture(sprite, padding.value / 2, padding.value / 2, 0, 0, texWidth, texHeight, fgColor.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void click(int mouseX, int mouseY) {
|
||||||
|
if (onClick != null) {
|
||||||
|
onClick.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,14 +6,18 @@ import net.minecraft.text.Text;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class Fonts {
|
public class Fonts {
|
||||||
public static final Identifier PANTON = Identifier.of("saturnclient", "panton");
|
public static final Identifier INTER = Identifier.of("saturnclient", "inter");
|
||||||
public static final Identifier PANTON_BOLD = Identifier.of("saturnclient", "panton_bold");
|
public static final Identifier INTER_BOLD = Identifier.of("saturnclient", "inter_bold");
|
||||||
|
public static final Identifier DEFAULT = Identifier.ofVanilla("default");
|
||||||
|
|
||||||
public static Identifier getFont(boolean bold) {
|
public static Identifier getFont(int font) {
|
||||||
if (bold) {
|
switch (font) {
|
||||||
return PANTON_BOLD;
|
case 0:
|
||||||
} else {
|
return DEFAULT;
|
||||||
return PANTON;
|
case 1:
|
||||||
|
return INTER;
|
||||||
|
default:
|
||||||
|
return INTER_BOLD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,12 +26,31 @@ public class Fonts {
|
|||||||
Style.EMPTY.withFont(font));
|
Style.EMPTY.withFont(font));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getWidth(String text, Identifier font) {
|
public static int getWidth(String text, int font) {
|
||||||
return SaturnClient.client.textRenderer.getWidth(Text.literal(text).setStyle(
|
int w = 0;
|
||||||
Style.EMPTY.withFont(font)));
|
for (String line : text.split("\n")) {
|
||||||
|
w = Math.max(w, getWidth(line, getFont(font)));
|
||||||
|
}
|
||||||
|
if (font == 0) {
|
||||||
|
return w * 2;
|
||||||
|
} else {
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getWidth(String text, Identifier font) {
|
||||||
|
return SaturnClient.client.textRenderer.getWidth(setFont(text, font));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getHeight() {
|
public static int getHeight() {
|
||||||
return SaturnClient.client.textRenderer.fontHeight;
|
return 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int centerX(int w, String text, int font) {
|
||||||
|
return (w - Fonts.getWidth(text, font)) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int centerY(int h) {
|
||||||
|
return (h - 18) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,4 +4,55 @@ import net.minecraft.util.Identifier;
|
|||||||
|
|
||||||
public class Textures {
|
public class Textures {
|
||||||
public static final Identifier CROSSHAIR_RANGE = Identifier.of("saturnclient", "textures/gui/hud/crosshair_range.png");
|
public static final Identifier CROSSHAIR_RANGE = Identifier.of("saturnclient", "textures/gui/hud/crosshair_range.png");
|
||||||
|
public static final Identifier COSMETICS = Identifier.of("saturnclient", "textures/gui/components/cosmetics.png");
|
||||||
|
public static final Identifier HUD_ICON = Identifier.of("saturnclient", "textures/gui/components/hud.png");
|
||||||
|
public static final Identifier SEARCH = Identifier.of("saturnclient", "textures/gui/components/search.png");
|
||||||
|
public static final Identifier CLOSE = Identifier.of("saturnclient", "textures/gui/components/close.png");
|
||||||
|
public static final Identifier MODS_TAB = Identifier.of("saturnclient", "textures/gui/components/mods_tab.png");
|
||||||
|
public static final Identifier SETTINGS = Identifier.of("saturnclient", "textures/gui/components/settings.png");
|
||||||
|
public static final Identifier CLOAK = Identifier.of("saturnclient", "textures/gui/components/cloak.png");
|
||||||
|
public static final Identifier HAT = Identifier.of("saturnclient", "textures/gui/components/hat.png");
|
||||||
|
public static final Identifier RESET = Identifier.of("saturnclient", "textures/gui/components/reset.png");
|
||||||
|
public static final Identifier TOGGLE_INDICATOR = Identifier.of("saturnclient",
|
||||||
|
"textures/gui/components/toggle_indicator.png");
|
||||||
|
public static final Identifier LEFT = Identifier.of("saturnclient", "textures/gui/components/left.png");
|
||||||
|
public static final Identifier RIGHT = Identifier.of("saturnclient", "textures/gui/components/right.png");
|
||||||
|
public static final Identifier STORE = Identifier.of("saturnclient", "textures/gui/components/store.png");
|
||||||
|
public static final Identifier COINS = Identifier.of("saturnclient", "textures/gui/components/coins.png");
|
||||||
|
public static final Identifier SHIRT = Identifier.of("saturnclient", "textures/gui/components/shirt.png");
|
||||||
|
public static final Identifier CIRCLE_X = Identifier.of("saturnclient", "textures/gui/components/circle_x.png");
|
||||||
|
public static final Identifier INFO = Identifier.of("saturnclient", "textures/gui/components/info.png");
|
||||||
|
public static final Identifier CHECK = Identifier.of("saturnclient", "textures/gui/components/check.png");
|
||||||
|
|
||||||
|
public static final Identifier LOGO = Identifier.of("saturnclient", "textures/logo/logo.png");
|
||||||
|
public static final Identifier REALISTIC_LOGO = Identifier.of("saturnclient", "textures/logo/realistic.png");
|
||||||
|
public static final Identifier LOGO_TEXT = Identifier.of("saturnclient", "textures/logo/text.png");
|
||||||
|
public static final Identifier LOGO_TEXT_BIG = Identifier.of("saturnclient", "textures/logo/text_big.png");
|
||||||
|
|
||||||
|
// Widgets
|
||||||
|
public static final Identifier BUTTON_BORDER = Identifier.of("saturnclient", "button_border");
|
||||||
|
public static final Identifier BUTTON = Identifier.of("saturnclient", "button");
|
||||||
|
public static final Identifier BUTTON_OP = Identifier.of("saturnclient", "button_op");
|
||||||
|
public static final Identifier SETTINGS_BG = Identifier.of("saturnclient", "settings_bg");
|
||||||
|
public static final Identifier RECT = Identifier.of("saturnclient", "rect");
|
||||||
|
public static final Identifier RECT_BORDER = Identifier.of("saturnclient", "rect_border");
|
||||||
|
public static final Identifier MOD = Identifier.of("saturnclient", "textures/gui/components/mod.png");
|
||||||
|
public static final Identifier MOD_BG = Identifier.of("saturnclient", "textures/gui/components/mod_bg.png");
|
||||||
|
|
||||||
|
public static Identifier getCloakPreview(String cloak) {
|
||||||
|
return Identifier.of("saturnclient", "textures/gui/cloak/" + (cloak.isEmpty() ? "none" : cloak) + ".png");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Identifier getHatPreview(String hat) {
|
||||||
|
return Identifier.of("saturnclient", "textures/gui/hat/" + (hat.isEmpty() ? "none" : hat) + ".png");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Identifier getEmotePreview(String emote) {
|
||||||
|
return Identifier.of("saturnclient", "textures/gui/emote/" + (emote == null ? "none" : emote) + ".png");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Identifier getModIcon(String modId) {
|
||||||
|
return Identifier.of("saturnclient", "textures/gui/mod/" + modId + ".png");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user