Compare commits
150
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 | ||
|
|
486232623a | ||
|
|
76dd1fe0a4 | ||
|
|
12c53099f2 | ||
|
|
3f89760282 | ||
|
|
3b5b51e6d2 | ||
|
|
d2894d0454 | ||
|
|
ed23cb44f2 | ||
|
|
683a9f41e8 | ||
|
|
052a56bcb0 | ||
|
|
81056dd7d7 | ||
|
|
8dd13364fb | ||
|
|
5149194cb3 | ||
|
|
98330ed8a9 | ||
|
|
ad54ed63f3 | ||
|
|
08a48c8f92 | ||
|
|
404838b70d | ||
|
|
4794e12bed | ||
|
|
3b44ead173 | ||
|
|
d1cc19a9db | ||
|
|
9b36603f86 | ||
|
|
2e5d3296d4 | ||
|
|
50e5a453a4 | ||
|
|
8f1d1f0ce8 | ||
|
|
1741e8c0b9 | ||
|
|
9f0d5ef78b | ||
|
|
5c15af0590 |
@@ -8,10 +8,12 @@
|
||||
<b>Saturn Client is a free and open source Minecraft client</b>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
# Credits
|
||||
|
||||
- Cloak rendering: `IIpho3nix` & `Dhyan Blum`
|
||||
- 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
|
||||
|
||||
+10
-1
@@ -19,6 +19,10 @@ dependencies {
|
||||
|
||||
modApi "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"
|
||||
url = "https://maven.felnull.dev"
|
||||
}
|
||||
|
||||
maven {
|
||||
name "KosmX's maven"
|
||||
url 'https://maven.kosmx.dev/'
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
@@ -43,7 +52,7 @@ processResources {
|
||||
}
|
||||
}
|
||||
|
||||
def targetJavaVersion = 17
|
||||
def targetJavaVersion = 21
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
it.options.encoding = "UTF-8"
|
||||
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
|
||||
|
||||
+8
-12
@@ -1,17 +1,13 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://modmuss50.me/fabric.html
|
||||
minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.7
|
||||
loader_version=0.16.10
|
||||
minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.7
|
||||
loader_version=0.16.10
|
||||
fabric_version=0.114.0+1.21.4
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 0.0.1-alpha0
|
||||
maven_group = me.iipho3nix
|
||||
archives_base_name = saturnclient
|
||||
mod_version = 0.0.4-beta2
|
||||
maven_group = org.saturnclient
|
||||
archives_base_name = saturnclient
|
||||
|
||||
# Dependencies
|
||||
# check this on https://modmuss50.me/fabric.html
|
||||
fabric_version=0.114.0+1.21.4
|
||||
player_anim = 2.0.3+1.21.4
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
public interface HudMod {
|
||||
public ModDimensions getDimensions();
|
||||
|
||||
public void renderDummy(RenderScope scope);
|
||||
|
||||
public void renderHud(RenderScope scope);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.saturnclient.saturnclient.config.NamedProperty;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
|
||||
public class ModDimensions {
|
||||
public Property<Integer> x = Property.integer(0);
|
||||
public Property<Integer> y = Property.integer(0);
|
||||
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 height = 0;
|
||||
|
||||
public NamedProperty<Map<String, Property<?>>> prop() {
|
||||
return Property.namespace(Map.of(
|
||||
"X", x,
|
||||
"Y", y,
|
||||
"Scale", scale,
|
||||
"Background Color", bgColor,
|
||||
"Foreground Color", fgColor,
|
||||
"Corner Radius", radius,
|
||||
"Font", font
|
||||
)).named("In-Game Display");
|
||||
}
|
||||
|
||||
public ModDimensions() {}
|
||||
|
||||
public ModDimensions(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public ModDimensions(int x, int y, int width, int height) {
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public ModDimensions(int x, int y, int width, int height, float scale) {
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
this.scale.value = scale;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
|
||||
import org.saturnclient.modules.mods.*;
|
||||
|
||||
public class ModManager {
|
||||
public static Module[] MODS = {
|
||||
new Crosshair(),
|
||||
new AutoSprint(),
|
||||
new ArmorDisplay(),
|
||||
new Fps(),
|
||||
new PotionDisplay(),
|
||||
new Coordinates(),
|
||||
new Freelook(),
|
||||
new Keystrokes()
|
||||
};
|
||||
|
||||
public static void init() {
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
for (Module m : MODS) {
|
||||
if (m.isEnabled()) {
|
||||
m.tick();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.NamedProperty;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public abstract class Module {
|
||||
private final ModuleDetails details;
|
||||
private final ConfigManager configManager;
|
||||
|
||||
public Module(ModuleDetails details, NamedProperty<?>... props) {
|
||||
this.details = details;
|
||||
configManager = new ConfigManager(details.name);
|
||||
for (NamedProperty<?> prop : props) {
|
||||
configManager.property(prop.name, prop.prop);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(RenderScope scope) {}
|
||||
public void tick() {}
|
||||
|
||||
public abstract boolean isEnabled();
|
||||
|
||||
public abstract void setEnabled(boolean e);
|
||||
|
||||
public final String getName() {
|
||||
return details.name;
|
||||
}
|
||||
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon(details.namespace);
|
||||
}
|
||||
|
||||
public ConfigManager getConfig() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
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.Textures;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
|
||||
public class Crosshair extends Module {
|
||||
public static Property<Boolean> enabled = Property.bool(false);
|
||||
|
||||
public Crosshair() {
|
||||
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
|
||||
public void render(RenderScope scope) {
|
||||
if (enabled.value
|
||||
&& SaturnClient.client.targetedEntity != null
|
||||
&& SaturnClient.client.targetedEntity.isAlive()) {
|
||||
int scaledWidth = 15;
|
||||
int scaledHeight = 15;
|
||||
|
||||
scope.setRenderLayer(RenderLayer::getCrosshair);
|
||||
scope.drawTexture(Textures.CROSSHAIR_RANGE,
|
||||
(scope.getScaledWindowWidth() - scaledWidth) / 2,
|
||||
(scope.getScaledWindowHeight() - scaledHeight) / 2, 0.0F, 0.0F, scaledWidth, scaledHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+12
-15
@@ -1,21 +1,20 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
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.saturnclient.mod_utils.CameraOverriddenEntity;
|
||||
import org.saturnclient.saturnmods.mods.FreeLook;
|
||||
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.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
@Mixin(Camera.class)
|
||||
public abstract class CameraMixin {
|
||||
@Unique
|
||||
@@ -25,9 +24,8 @@ public abstract class CameraMixin {
|
||||
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) {
|
||||
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) {
|
||||
@@ -35,13 +33,12 @@ public abstract class CameraMixin {
|
||||
cameraOverriddenEntity.freelook$setCameraYaw(MinecraftClient.getInstance().player.getYaw());
|
||||
firstTime = false;
|
||||
}
|
||||
this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(),
|
||||
cameraOverriddenEntity.freelook$getCameraPitch());
|
||||
this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), cameraOverriddenEntity.freelook$getCameraPitch());
|
||||
|
||||
}
|
||||
if (!FreeLook.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
package org.saturnclient.saturnclient.mod_utils;
|
||||
package org.saturnclient.modules.mods.utils;
|
||||
|
||||
public interface CameraOverriddenEntity {
|
||||
float freelook$getCameraPitch();
|
||||
float freelook$getCameraPitch();
|
||||
float freelook$getCameraYaw();
|
||||
|
||||
void freelook$setCameraPitch(float pitch);
|
||||
void freelook$setCameraYaw(float yaw);
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,22 @@ package org.saturnclient.saturnclient;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import org.saturnclient.modules.ModManager;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||
import org.saturnclient.saturnclient.event.KeyInputHandler;
|
||||
import org.saturnclient.saturnclient.menus.SaturnMenu;
|
||||
import org.saturnclient.saturnclient.menus.SaturnTitleScreen;
|
||||
import org.saturnclient.saturnmods.ModManager;
|
||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||
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.LoggerFactory;
|
||||
|
||||
@@ -25,26 +31,50 @@ public class SaturnClient implements ModInitializer {
|
||||
|
||||
public static final String MOD_ID = "saturnclient";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
public static MinecraftClient client;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LOGGER.info("Initializing " + MOD_ID);
|
||||
client = MinecraftClient.getInstance();
|
||||
SaturnClientConfig.init();
|
||||
ModManager.init();
|
||||
ConfigManager.load();
|
||||
|
||||
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(() -> {
|
||||
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();
|
||||
Emotes.initialize();
|
||||
if (Auth.authenticate()) {
|
||||
Cloaks.initialize();
|
||||
Hats.initialize();
|
||||
|
||||
@@ -1,53 +1,20 @@
|
||||
package org.saturnclient.saturnclient;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.ui.SaturnAnimation;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.animations.FadeIn;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
|
||||
public class SaturnClientConfig {
|
||||
public static ConfigManager config = new ConfigManager("Saturn Client");
|
||||
public static ConfigManager config;
|
||||
|
||||
public static Property<Integer> color = config.property(
|
||||
"Primary color",
|
||||
new Property<>(
|
||||
ColorHelper.getArgb(255, 251, 60, 79),
|
||||
Property.PropertyType.HEX));
|
||||
public static Property<Boolean> realisticLogo = Property.bool(false);
|
||||
|
||||
public static Property<Integer> normal = config.property(
|
||||
"Default color",
|
||||
new Property<>(
|
||||
ColorHelper.getArgb(255, 182, 182, 182),
|
||||
Property.PropertyType.HEX));
|
||||
|
||||
public static Property<Boolean> realisticLogo = config.property(
|
||||
"Realistic logo",
|
||||
new Property<>(false));
|
||||
|
||||
public static Property<Boolean> saturnTitleScreen = config.property(
|
||||
"Saturn client title screen",
|
||||
new Property<>(true));
|
||||
|
||||
public static int WHITE = ColorHelper.getArgb(255, 255, 255, 255);
|
||||
public static TextRenderer textRenderer = null;
|
||||
|
||||
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 Property<Boolean> saturnTitleScreen = Property.bool(true);
|
||||
public static Property<Integer> openEmoteWheel = Property.keybinding(GLFW.GLFW_KEY_B);
|
||||
|
||||
public static Identifier getLogo() {
|
||||
return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO;
|
||||
@@ -56,4 +23,28 @@ public class SaturnClientConfig {
|
||||
public static String getSaturnIndicator() {
|
||||
return realisticLogo.value ? "" : "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the icon color of a specific individual, here are the different colors
|
||||
*
|
||||
* - Owner: Dark Red
|
||||
* - Admin: Red
|
||||
* - Partners: Gold
|
||||
* - Contributor: Aqua
|
||||
* - Other/player: White
|
||||
*/
|
||||
public static Formatting getIconColor(String uuid) {
|
||||
if (uuid.equals("d362a04228bd49e1a807ae74dbe8aba9")) {
|
||||
return Formatting.DARK_RED; // Owner
|
||||
}
|
||||
|
||||
return Formatting.WHITE;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
config = new ConfigManager("Saturn Client");
|
||||
config.property("Realistic logo", realisticLogo);
|
||||
config.property("Saturn client title screen", saturnTitleScreen);
|
||||
config.property("Open Emote Wheel", openEmoteWheel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,22 @@ package org.saturnclient.saturnclient.auth;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
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;
|
||||
|
||||
public class Auth {
|
||||
@@ -22,13 +34,12 @@ public class Auth {
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> close());
|
||||
|
||||
try {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
if (client.getSession() == null) {
|
||||
if (SaturnClient.client.getSession() == null) {
|
||||
SaturnClient.LOGGER.error("No active Minecraft session found");
|
||||
return false;
|
||||
}
|
||||
|
||||
String accessToken = client.getSession().getAccessToken();
|
||||
String accessToken = SaturnClient.client.getSession().getAccessToken();
|
||||
SaturnClient.LOGGER.info("Authenticating");
|
||||
|
||||
Network.init();
|
||||
@@ -55,7 +66,7 @@ public class Auth {
|
||||
|
||||
Cloaks.loadCloak(uuid);
|
||||
|
||||
playerNames.put(client.getSession().getUsername(), uuid);
|
||||
playerNames.put(SaturnClient.client.getSession().getUsername(), uuid);
|
||||
|
||||
afterAuth();
|
||||
|
||||
@@ -98,9 +109,72 @@ public class Auth {
|
||||
}
|
||||
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:
|
||||
if (parser.error != null) {
|
||||
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;
|
||||
}
|
||||
@@ -119,16 +193,21 @@ public class Auth {
|
||||
private static void startPingThread() {
|
||||
pingThread = new Thread(() -> {
|
||||
try {
|
||||
while (running) {
|
||||
Thread.sleep(25000); // 25 seconds
|
||||
if (running) {
|
||||
Network.write("ping");
|
||||
while (running && !Thread.currentThread().isInterrupted()) {
|
||||
try {
|
||||
Thread.sleep(25000); // 25 seconds
|
||||
if (running) {
|
||||
Network.write("ping");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt(); // Restore interrupt status
|
||||
break; // Exit the loop on interruption
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
SaturnClient.LOGGER.warn("Ping thread interrupted", e);
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Error in ping thread", e);
|
||||
if (!(e instanceof InterruptedException)) {
|
||||
SaturnClient.LOGGER.error("Error in ping thread", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -158,7 +237,7 @@ public class Auth {
|
||||
|
||||
public static void setCloak(String cloakName) {
|
||||
try {
|
||||
Network.write("set_cloak@cloak=" + cloakName);
|
||||
Network.write("set_cloak@cloak=" + cloakName + "@notify=" + stringifyPlayers());
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
@@ -166,12 +245,26 @@ public class Auth {
|
||||
|
||||
public static void setHat(String hatName) {
|
||||
try {
|
||||
Network.write("set_hat@hat=" + hatName);
|
||||
Network.write("set_hat@hat=" + hatName + "@notify=" + stringifyPlayers());
|
||||
} catch (Exception 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) {
|
||||
try {
|
||||
playerNames.put(name, uuid.replaceAll("-", ""));
|
||||
@@ -181,14 +274,19 @@ public class Auth {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendReload() {
|
||||
for (Map.Entry<String, String> player : playerNames.entrySet()) {
|
||||
if (players.containsKey(player.getValue()) && !player.getValue().equals(uuid)) {
|
||||
MinecraftClient.getInstance().player.networkHandler
|
||||
.sendChatCommand("msg " + player.getKey() + " "
|
||||
+ "$SATURN_RELOAD if you are seeing this as a player, please report this to https://github.com/saturnclientmc/saturnclient/issues");
|
||||
;
|
||||
}
|
||||
public static void buyCloak(String name) {
|
||||
try {
|
||||
Network.write("buy_cloak@cloak=" + name);
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void buyHat(String name) {
|
||||
try {
|
||||
Network.write("buy_hat@hat=" + name);
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@ package org.saturnclient.saturnclient.auth;
|
||||
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.network.PlayerListEntry;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -19,7 +20,7 @@ public class PlayerTracker {
|
||||
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
|
||||
trackedPlayers.clear();
|
||||
client.execute(() -> {
|
||||
checkForNewPlayers(MinecraftClient.getInstance());
|
||||
checkForNewPlayers(SaturnClient.client);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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 {
|
||||
String val = params.get(i);
|
||||
if (val != null) {
|
||||
|
||||
@@ -12,38 +12,79 @@ import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private static File configFile = new File(
|
||||
MinecraftClient.getInstance().runDirectory,
|
||||
SaturnClient.client.runDirectory,
|
||||
"saturn.json");
|
||||
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
||||
private static JsonObject cachedThemeJson = null;
|
||||
|
||||
private Map<String, Property<?>> currentMap;
|
||||
private String namespace;
|
||||
|
||||
public ConfigManager(String namespace) {
|
||||
currentMap = new LinkedHashMap<>();
|
||||
properties.put(namespace, currentMap);
|
||||
System.out.println("Created namespace: " + namespace);
|
||||
}
|
||||
|
||||
public ConfigManager(ConfigManager config, String namespace) {
|
||||
currentMap = new LinkedHashMap<>();
|
||||
Property<Map<String, Property<?>>> namespaceProperty = new Property<>(currentMap,
|
||||
Property.PropertyType.NAMESPACE);
|
||||
Property<Map<String, Property<?>>> namespaceProperty = Property.namespace(currentMap);
|
||||
config.property(namespace, namespaceProperty);
|
||||
// Update the parent's state
|
||||
config.currentMap.put(namespace, namespaceProperty);
|
||||
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
|
||||
public <T> Property<T> property(String name, Property<T> value) {
|
||||
currentMap.put(name, value);
|
||||
loadProp(name, 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() {
|
||||
try {
|
||||
SaturnClient.LOGGER.info("Starting to load config...");
|
||||
@@ -92,25 +133,17 @@ public class ConfigManager {
|
||||
Map<String, Property<?>> nestedProperties = p.getNamespaceValue();
|
||||
loadProperties(nestedConfig, 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;
|
||||
if (p.value instanceof Integer) {
|
||||
((Property<Integer>) p).value = c.getAsInt();
|
||||
} else if (p.value instanceof String) {
|
||||
((Property<String>) p).value = c.getAsString();
|
||||
} else if (p.value instanceof Float) {
|
||||
((Property<Float>) p).value = c.getAsFloat();
|
||||
} else if (p.value instanceof Boolean) {
|
||||
((Property<Boolean>) p).value = c.getAsBoolean();
|
||||
} else {
|
||||
SaturnClient.LOGGER.warn(
|
||||
"Unknown property type for: " + propertyName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -156,36 +189,29 @@ public class ConfigManager {
|
||||
for (String propertyName : propertyMap.keySet()) {
|
||||
Property<?> property = propertyMap.get(propertyName);
|
||||
JsonElement propertyValue = null;
|
||||
|
||||
if (property.getType() == Property.PropertyType.NAMESPACE) {
|
||||
// Handle nested namespace
|
||||
JsonObject nestedConfig = new JsonObject();
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
||||
saveProperties(nestedConfig, nestedProperties);
|
||||
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:
|
||||
// Convert the property value based on its type
|
||||
switch (property.getType()) {
|
||||
case NAMESPACE:
|
||||
// Handle nested namespace
|
||||
JsonObject nestedConfig = new JsonObject();
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
||||
saveProperties(nestedConfig, nestedProperties);
|
||||
propertyValue = nestedConfig;
|
||||
break;
|
||||
default:
|
||||
if (property.value instanceof Integer) {
|
||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
||||
break;
|
||||
case FLOAT:
|
||||
propertyValue = new JsonPrimitive((Float) property.value);
|
||||
break;
|
||||
case STRING:
|
||||
} else if (property.value instanceof String) {
|
||||
propertyValue = new JsonPrimitive((String) property.value);
|
||||
break;
|
||||
case HEX:
|
||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
||||
break;
|
||||
default:
|
||||
} 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(
|
||||
"Unknown property type for: " + propertyName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (propertyValue != null) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.saturnclient.saturnclient.config;
|
||||
|
||||
public class NamedProperty<T> {
|
||||
public String name;
|
||||
public Property<T> prop;
|
||||
|
||||
public NamedProperty(String name, Property<T> value) {
|
||||
this.name = name;
|
||||
this.prop = value;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package org.saturnclient.saturnclient.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
@@ -13,62 +16,108 @@ public class Property<T> {
|
||||
FLOAT,
|
||||
STRING,
|
||||
HEX,
|
||||
NAMESPACE
|
||||
NAMESPACE,
|
||||
SELECT,
|
||||
KEYBINDING,
|
||||
}
|
||||
|
||||
public T value;
|
||||
public boolean isReset = false;
|
||||
private T defaultValue;
|
||||
private String[] availableValues;
|
||||
private PropertyType type;
|
||||
private boolean wasPressedLastTick = false;
|
||||
|
||||
public Property(T value) {
|
||||
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) {
|
||||
private Property(T value, PropertyType type) {
|
||||
this.value = value;
|
||||
this.defaultValue = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean getBool() {
|
||||
public static <T> Property<T> from(T value) {
|
||||
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() {
|
||||
if (value instanceof Integer) {
|
||||
return (int) value;
|
||||
}
|
||||
throw new IllegalStateException("Property does not contain an int");
|
||||
public Property<T> copy() {
|
||||
return new Property<>(this.value, this.type);
|
||||
}
|
||||
|
||||
public float getFloat() {
|
||||
if (value instanceof Float) {
|
||||
return (float) value;
|
||||
}
|
||||
throw new IllegalStateException("Property does not contain a float");
|
||||
public static Property<Integer> font(int value) {
|
||||
return select(value, "Default", "Inter", "Inter bold");
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
if (value instanceof String) {
|
||||
return (String) value;
|
||||
public static Property<Integer> select(Integer value, String... availableValues) {
|
||||
Property<Integer> property = new Property<>(value, PropertyType.SELECT);
|
||||
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() {
|
||||
@@ -115,12 +164,8 @@ public class Property<T> {
|
||||
return true;
|
||||
if (value instanceof String && primitive.isString())
|
||||
return true;
|
||||
|
||||
// Check if JSON string represents a valid hex integer
|
||||
if (value instanceof String && primitive.isString()) {
|
||||
String str = primitive.getAsString();
|
||||
return str.matches("0x[0-9A-Fa-f]+");
|
||||
}
|
||||
if (type == PropertyType.HEX && primitive.isString())
|
||||
return true;
|
||||
} else if (element.isJsonObject()) {
|
||||
return isNamespace(value);
|
||||
}
|
||||
@@ -139,4 +184,75 @@ public class Property<T> {
|
||||
public static boolean valueIsNamespace(Object obj) {
|
||||
return obj instanceof Map;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setValue(Object value) {
|
||||
this.value = (T) value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setValue(Object value, Object defaultValue) {
|
||||
this.value = (T) value;
|
||||
this.defaultValue = (T) defaultValue;
|
||||
}
|
||||
|
||||
public NamedProperty<T> named(String name) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.saturnclient.saturnclient.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public class ThemeManager {
|
||||
private static File themeFile = new File(
|
||||
SaturnClient.client.runDirectory,
|
||||
"saturn.theme.json");
|
||||
private static List<ThemeManager> theme = new ArrayList<>();
|
||||
private static JsonObject cachedThemeJson = null;
|
||||
|
||||
private Map<String, Map<String, Object>> states;
|
||||
private Map<String, Property<?>> currentStyling;
|
||||
private String namespace;
|
||||
|
||||
public ThemeManager(String namespace, String... states) {
|
||||
this.namespace = namespace;
|
||||
this.states = new LinkedHashMap<>();
|
||||
this.currentStyling = new LinkedHashMap<>();
|
||||
this.states.put(null, new LinkedHashMap<>());
|
||||
for (String s : states) {
|
||||
this.states.put(s, new LinkedHashMap<>());
|
||||
}
|
||||
theme.add(this);
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
for (Map.Entry<String, Object> tProp : states.get(state).entrySet()) {
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Property<T> property(String name, Property<T> prop) {
|
||||
for (Map.Entry<String, Map<String, Object>> state : this.states.entrySet()) {
|
||||
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);
|
||||
}
|
||||
|
||||
currentStyling.put(name, prop);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public <T> void propertyStateDefault(String state, String name, T 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() {
|
||||
try {
|
||||
SaturnClient.LOGGER.info("Starting to load theme...");
|
||||
if (!themeFile.exists()) {
|
||||
themeFile.createNewFile();
|
||||
Files.write(themeFile.toPath(), "{}".getBytes());
|
||||
}
|
||||
|
||||
cachedThemeJson = JsonParser.parseString(
|
||||
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
|
||||
|
||||
SaturnClient.LOGGER.info("Theme loaded");
|
||||
} catch (IOException e) {
|
||||
SaturnClient.LOGGER.error("Error reading the theme file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.saturnclient.saturnclient.cosmetics;
|
||||
import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.feature.FeatureRenderer;
|
||||
@@ -30,7 +30,7 @@ public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState,
|
||||
PlayerEntityRenderState state, float limbAngle, float limbDistance) {
|
||||
ItemStack headItem = state.equippedHeadStack;
|
||||
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);
|
||||
if (player == null || player.hat == null || player.hat.isEmpty()) {
|
||||
return;
|
||||
@@ -48,7 +48,7 @@ public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState,
|
||||
customHat.set(DataComponentTypes.EQUIPPABLE,
|
||||
EquippableComponent.builder(EquipmentSlot.HEAD).build());
|
||||
|
||||
ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
|
||||
ItemRenderer itemRenderer = SaturnClient.client.getItemRenderer();
|
||||
|
||||
itemRenderer.renderItem(
|
||||
customHat,
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
|
||||
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 void initialize() {
|
||||
@@ -15,7 +16,6 @@ public class Hats {
|
||||
public static void setHat(String uuid, String hatName) {
|
||||
setHatSilent(uuid, hatName);
|
||||
Auth.setHat(hatName);
|
||||
Auth.sendReload();
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
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 CLOAKS_RESOURCE_PATH = "assets/saturnclient/textures/cloaks/";
|
||||
@@ -44,10 +45,20 @@ public class Cloaks {
|
||||
public static void setCloak(String uuid, String cloakName) {
|
||||
Auth.setCloak(cloakName);
|
||||
setCloakSilent(uuid, cloakName);
|
||||
Auth.sendReload();
|
||||
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
|
||||
* server.
|
||||
@@ -96,29 +107,34 @@ public class Cloaks {
|
||||
}
|
||||
|
||||
// Register textures on main thread
|
||||
net.minecraft.client.MinecraftClient.getInstance().execute(() -> {
|
||||
SaturnClient.client.execute(() -> {
|
||||
try {
|
||||
List<AnimatedCloakData> animatedFrames = new ArrayList<>();
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
String frameId = fileName.replace(".gif", "") + "_frame_" + i;
|
||||
Identifier frameIdentifier = Identifier.of(SaturnClient.MOD_ID, "cloaks_" + frameId);
|
||||
IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frames.get(i));
|
||||
Identifier frameIdentifier = Identifier.of(SaturnClient.MOD_ID,
|
||||
"cloaks_" + frameId);
|
||||
IdentifierUtils.registerBufferedImageTexture(frameIdentifier,
|
||||
frames.get(i));
|
||||
animatedFrames.add(new AnimatedCloakData(frameIdentifier, delays.get(i)));
|
||||
}
|
||||
animatedCloaks.put(uuid, animatedFrames);
|
||||
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) {
|
||||
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) {
|
||||
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();
|
||||
} else {
|
||||
net.minecraft.client.MinecraftClient.getInstance().execute(() -> loadStaticCloak(player.cloak + ".png"));
|
||||
SaturnClient.client.execute(() -> loadStaticCloak(player.cloak + ".png"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package org.saturnclient.saturnclient.cosmetics.cloaks.utils;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import net.minecraft.client.texture.NativeImageBackedTexture;
|
||||
import net.minecraft.util.Identifier;
|
||||
@@ -20,7 +20,7 @@ public class IdentifierUtils {
|
||||
ByteBuffer bb = BufferUtils.createByteBuffer(bytes.length).put(bytes);
|
||||
bb.flip();
|
||||
NativeImageBackedTexture nibt = new NativeImageBackedTexture(NativeImage.read(bb));
|
||||
MinecraftClient.getInstance().getTextureManager().registerTexture(i, nibt);
|
||||
SaturnClient.client.getTextureManager().registerTexture(i, nibt);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -3,10 +3,17 @@ package org.saturnclient.saturnclient.event;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.option.Perspective;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import org.saturnclient.saturnclient.menus.SaturnMenu;
|
||||
import org.saturnclient.saturnmods.mods.FreeLook;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -19,52 +26,28 @@ public class KeyInputHandler {
|
||||
private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT;
|
||||
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() {
|
||||
// Register the main menu key binding
|
||||
mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
MAIN_MENU_KEY_ID,
|
||||
InputUtil.Type.KEYSYM,
|
||||
DEFAULT_MENU_KEY,
|
||||
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
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
if (mainMenuKeyBinding.wasPressed()) {
|
||||
client.setScreen(new SaturnMenu());
|
||||
} 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;
|
||||
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("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,14 @@ import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.ModManager;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnmods.HudMod;
|
||||
import org.saturnclient.saturnmods.ModDimensions;
|
||||
import org.saturnclient.saturnmods.ModManager;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
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.List;
|
||||
@@ -24,7 +26,7 @@ public class HudEditor extends Screen {
|
||||
|
||||
public HudEditor() {
|
||||
super(Text.literal("HUD Editor"));
|
||||
for (SaturnMod m : ModManager.MODS) {
|
||||
for (Module m : ModManager.MODS) {
|
||||
if (m.isEnabled() && m instanceof HudMod) {
|
||||
hudMods.add((HudMod) m);
|
||||
}
|
||||
@@ -90,9 +92,11 @@ public class HudEditor extends Screen {
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
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) {
|
||||
ModDimensions dim = mod.getDimensions();
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
@@ -102,7 +106,7 @@ public class HudEditor extends Screen {
|
||||
matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
||||
|
||||
// Render the mod
|
||||
mod.renderDummy(context);
|
||||
mod.renderDummy(scope);
|
||||
|
||||
matrices.pop();
|
||||
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
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.saturnmods.ModManager;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
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 (SaturnMod 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,77 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
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.ui.widgets.SaturnImageButton;
|
||||
|
||||
public class SaturnMenu extends SaturnUi {
|
||||
public SaturnMenu() {
|
||||
super(Text.literal("Saturn Client"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
SaturnClientConfig.textRenderer = MinecraftClient.getInstance().textRenderer;
|
||||
|
||||
int buttonWidth = 96;
|
||||
int buttonHeight = 25;
|
||||
|
||||
draw(
|
||||
new SaturnButton("Mods", () -> {
|
||||
client.setScreen(new ModMenu());
|
||||
})
|
||||
.setX((width - buttonWidth) / 2)
|
||||
.setY((height - buttonHeight) / 2)
|
||||
.setWidth(buttonWidth)
|
||||
.setHeight(buttonHeight)
|
||||
.setAnimations(new FadeIn(2)));
|
||||
|
||||
draw(
|
||||
new SaturnImageButton(Textures.HUD_ICON, 14, 14, () -> {
|
||||
client.setScreen(new HudEditor());
|
||||
})
|
||||
.setX((width - buttonWidth - (buttonHeight * 2) - 6) / 2)
|
||||
.setY((height - buttonHeight) / 2)
|
||||
.setWidth(buttonHeight)
|
||||
.setHeight(buttonHeight)
|
||||
.setAnimations(new FadeIn(2)));
|
||||
|
||||
draw(
|
||||
new SaturnImageButton(Textures.COSMETICS, 14, 14, () -> {
|
||||
client.setScreen(new CloaksMenu());
|
||||
})
|
||||
.setX((width / 2) + (buttonWidth / 2) + 3)
|
||||
.setY((height - buttonHeight) / 2)
|
||||
.setWidth(buttonHeight)
|
||||
.setHeight(buttonHeight)
|
||||
.setAnimations(new FadeIn(2)));
|
||||
|
||||
int logoSize = 49;
|
||||
|
||||
draw(
|
||||
new SaturnImage(Textures.LOGO_TEXT)
|
||||
.setX((width - logoSize) / 2)
|
||||
.setY((height - 8) / 2 - 23)
|
||||
.setWidth(logoSize)
|
||||
.setHeight(8)
|
||||
.setAnimations(new FadeIn(2)));
|
||||
|
||||
draw(
|
||||
new SaturnImage(SaturnClientConfig.getLogo())
|
||||
.setX((width - logoSize) / 2)
|
||||
.setY(height / 2 - logoSize - 24)
|
||||
.setWidth(logoSize)
|
||||
.setHeight(logoSize)
|
||||
.setAnimations(new Slide(2, 14)));
|
||||
|
||||
super.init();
|
||||
}
|
||||
}
|
||||
@@ -1,77 +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 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 SaturnMenu());
|
||||
}).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
||||
|
||||
super.init();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Code from: https://github.com/Selyss
|
||||
* Repo: https://github.com/Selyss/CrosshairIndicator/tree/main
|
||||
*/
|
||||
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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;
|
||||
import net.minecraft.client.gui.hud.InGameHud;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
@Mixin(InGameHud.class)
|
||||
public class Crosshair {
|
||||
@Shadow
|
||||
@Final
|
||||
private MinecraftClient client;
|
||||
@Unique
|
||||
Identifier textureLocation = Identifier.of("saturnclient", "textures/gui/hud/crosshair_range.png");
|
||||
|
||||
@Inject(method = "renderCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIII)V", ordinal = 0))
|
||||
private void drawCrosshair(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
|
||||
if (org.saturnclient.saturnmods.mods.Crosshair.enabled.value
|
||||
&& org.saturnclient.saturnmods.mods.Crosshair.range_indicator.value
|
||||
&& this.client.targetedEntity != null
|
||||
&& this.client.targetedEntity.isAlive()) {
|
||||
RenderSystem.setShaderTexture(0, textureLocation);
|
||||
int scaledWidth = 15;
|
||||
int scaledHeight = 15;
|
||||
|
||||
context.drawTexture(RenderLayer::getCrosshair, textureLocation,
|
||||
(context.getScaledWindowWidth() - scaledWidth) / 2,
|
||||
(context.getScaledWindowHeight() - scaledHeight) / 2, 0.0F, 0.0F, scaledWidth, scaledHeight,
|
||||
scaledWidth, scaledHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(DrawContext.class)
|
||||
public interface DrawContextAccessor {
|
||||
@Accessor("vertexConsumers")
|
||||
VertexConsumerProvider.Immediate getVertexConsumers();
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import org.saturnclient.saturnclient.mod_utils.CameraOverriddenEntity;
|
||||
import org.saturnclient.saturnmods.mods.FreeLook;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.font.TextRenderer.TextLayerType;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
@@ -9,7 +9,9 @@ import net.minecraft.client.render.entity.EntityRenderer;
|
||||
import net.minecraft.client.render.entity.state.EntityRenderState;
|
||||
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
@@ -34,20 +36,32 @@ public abstract class NameTagMixin<S extends EntityRenderState> {
|
||||
@Inject(method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"), cancellable = true)
|
||||
private void onRenderLabelIfPresent(S state, Text text, MatrixStack matrices,
|
||||
VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
|
||||
if (isSaturn(state)) {
|
||||
renderLabel(state, Text.literal(SaturnClientConfig.getSaturnIndicator()).append(text), matrices,
|
||||
|
||||
String uuid = isSaturn(state);
|
||||
|
||||
if (uuid != null) {
|
||||
MutableText iconText = Text.literal(SaturnClientConfig.getSaturnIndicator())
|
||||
.styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid)));
|
||||
|
||||
Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE));
|
||||
|
||||
renderLabel(state, iconText.append(nameText), matrices,
|
||||
vertexConsumers, light);
|
||||
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSaturn(S state) {
|
||||
private String isSaturn(S state) {
|
||||
if (state instanceof PlayerEntityRenderState) {
|
||||
String name = ((PlayerEntityRenderState) state).name;
|
||||
String uuid = Auth.playerNames.get(name);
|
||||
return uuid != null && Auth.players.containsKey(uuid);
|
||||
if (Auth.players.containsKey(uuid)) {
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderLabel(S state, Text text, MatrixStack matrices,
|
||||
@@ -61,9 +75,9 @@ public abstract class NameTagMixin<S extends EntityRenderState> {
|
||||
matrices.multiply(this.dispatcher.getRotation());
|
||||
matrices.scale(0.025F, -0.025F, 0.025F);
|
||||
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
|
||||
TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
|
||||
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
float f = (float) (-textRenderer.getWidth(text)) / 2.0F;
|
||||
int j = (int) (MinecraftClient.getInstance().options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24;
|
||||
int j = (int) (SaturnClient.client.options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24;
|
||||
textRenderer.draw(text, f, (float) i, -2130706433, false, matrix4f, vertexConsumers,
|
||||
bl ? TextLayerType.SEE_THROUGH : TextLayerType.NORMAL, j, light);
|
||||
if (bl) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import net.minecraft.client.network.PlayerListEntry;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
@@ -29,7 +32,11 @@ public abstract class TabListMixin {
|
||||
String name = profile.getName();
|
||||
String uuid = profile.getId().toString().replaceAll("-", "");
|
||||
|
||||
return Text.literal(
|
||||
Auth.players.containsKey(uuid) ? SaturnClientConfig.getSaturnIndicator() + name : name);
|
||||
MutableText iconText = Text.literal(SaturnClientConfig.getSaturnIndicator())
|
||||
.styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid)));
|
||||
|
||||
Text nameText = Text.literal(name).styled(style -> style.withColor(Formatting.WHITE));
|
||||
|
||||
return Auth.players.containsKey(uuid) ? iconText.append(nameText) : Text.literal(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,37 +0,0 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import net.minecraft.client.particle.AnimatedParticle;
|
||||
import net.minecraft.client.particle.SpriteProvider;
|
||||
import net.minecraft.client.particle.TotemParticle;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
|
||||
import org.saturnclient.saturnmods.mods.Particles;
|
||||
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;
|
||||
|
||||
@Mixin(TotemParticle.class)
|
||||
public class TotemParticleMixin extends AnimatedParticle {
|
||||
protected TotemParticleMixin(ClientWorld world, double x, double y, double z, SpriteProvider spriteProvider,
|
||||
float upwardsAcceleration) {
|
||||
super(world, x, y, z, spriteProvider, upwardsAcceleration);
|
||||
}
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "<init>")
|
||||
private void colorChanger(ClientWorld world, double x, double y, double z, double velocityX, double velocityY,
|
||||
double velocityZ, SpriteProvider spriteProvider, CallbackInfo ci) {
|
||||
if (Particles.enabled.value && Particles.totem_enabled.value) {
|
||||
if (this.random.nextInt(2) == 0) {
|
||||
this.setColor(ColorHelper.getRedFloat(Particles.totem_1.value),
|
||||
ColorHelper.getGreenFloat(Particles.totem_1.value),
|
||||
ColorHelper.getBlueFloat(Particles.totem_1.value));
|
||||
} else {
|
||||
this.setColor(ColorHelper.getRedFloat(Particles.totem_2.value),
|
||||
ColorHelper.getGreenFloat(Particles.totem_2.value),
|
||||
ColorHelper.getBlueFloat(Particles.totem_2.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.saturnclient.saturnmods;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
public interface HudMod {
|
||||
public ModDimensions getDimensions();
|
||||
|
||||
public void renderDummy(DrawContext context);
|
||||
|
||||
public void render(DrawContext context);
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.saturnclient.saturnmods;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
|
||||
public class ModDimensions {
|
||||
public Property<Integer> x = new Property<>(0);
|
||||
public Property<Integer> y = new Property<>(0);
|
||||
public Property<Float> scale = new Property<>(1.0f);
|
||||
|
||||
public int width = 0;
|
||||
public int height = 0;
|
||||
|
||||
private final ConfigManager dimensionsConfig;
|
||||
|
||||
public ModDimensions(ConfigManager configManager) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
dimensionsConfig.property("x", this.x);
|
||||
dimensionsConfig.property("y", this.y);
|
||||
dimensionsConfig.property("scale", this.scale);
|
||||
}
|
||||
|
||||
public ModDimensions(ConfigManager configManager, int x, int y) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
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) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
this.width = width;
|
||||
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) {
|
||||
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.y.value = y;
|
||||
this.scale.value = scale;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
dimensionsConfig.property("x", this.x);
|
||||
dimensionsConfig.property("y", this.y);
|
||||
dimensionsConfig.property("scale", this.scale);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package org.saturnclient.saturnmods;
|
||||
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||
import org.saturnclient.saturnmods.mods.*;
|
||||
|
||||
public class ModManager {
|
||||
|
||||
public static SaturnMod[] MODS = {
|
||||
new Coordinates(),
|
||||
new ArmorDisplay(),
|
||||
new FpsDisplay(),
|
||||
new Particles(),
|
||||
new Crosshair(),
|
||||
new FreeLook()
|
||||
};
|
||||
|
||||
public static void init() {
|
||||
HudRenderCallback.EVENT.register((context, _o) -> {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
TextRenderer textRenderer = client.textRenderer;
|
||||
|
||||
if (textRenderer != null &&
|
||||
!(client.currentScreen instanceof HudEditor)) {
|
||||
SaturnClientConfig.textRenderer = textRenderer;
|
||||
|
||||
for (SaturnMod 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.saturnclient.saturnmods;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public interface SaturnMod {
|
||||
public boolean isEnabled();
|
||||
|
||||
public void setEnabled(boolean e);
|
||||
|
||||
public String getName();
|
||||
|
||||
public Identifier getIconTexture();
|
||||
|
||||
public ConfigManager getConfig();
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package org.saturnclient.saturnmods.mods;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnmods.HudMod;
|
||||
import org.saturnclient.saturnmods.ModDimensions;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class ArmorDisplay implements SaturnMod, HudMod {
|
||||
|
||||
private static ConfigManager config = new ConfigManager("Armor Display");
|
||||
public static Property<Boolean> enabled = config.property(
|
||||
"Enabled",
|
||||
new Property<>(false));
|
||||
private static ModDimensions dimensions = new ModDimensions(
|
||||
config,
|
||||
0,
|
||||
0,
|
||||
34,
|
||||
75);
|
||||
|
||||
public static Property<Integer> fgColor = config.property(
|
||||
"Foreground color",
|
||||
new Property<>(SaturnClientConfig.WHITE, Property.PropertyType.HEX));
|
||||
|
||||
private boolean renderItem(DrawContext context, ItemStack item, int y) {
|
||||
if (item.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context.drawItem(item, 0, y);
|
||||
|
||||
if (item.getMaxDamage() > 0) {
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
|
||||
matrices.push();
|
||||
|
||||
matrices.translate(17, y + 5, 0);
|
||||
|
||||
matrices.scale(0.8f, 0.8f, 0f);
|
||||
|
||||
context.drawText(
|
||||
SaturnClientConfig.textRenderer,
|
||||
"" + (item.getMaxDamage() - item.getDamage()),
|
||||
0,
|
||||
0,
|
||||
fgColor.value,
|
||||
false);
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context) {
|
||||
PlayerEntity player = MinecraftClient.getInstance().player;
|
||||
ItemStack[] items = {
|
||||
player.getEquippedStack(EquipmentSlot.MAINHAND),
|
||||
player.getEquippedStack(EquipmentSlot.FEET),
|
||||
player.getEquippedStack(EquipmentSlot.LEGS),
|
||||
player.getEquippedStack(EquipmentSlot.CHEST),
|
||||
player.getEquippedStack(EquipmentSlot.HEAD),
|
||||
};
|
||||
|
||||
int y = 60;
|
||||
|
||||
for (ItemStack item : items) {
|
||||
if (renderItem(context, item, y)) {
|
||||
y -= 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(DrawContext context) {
|
||||
ItemStack[] items = {
|
||||
new ItemStack(Items.DIAMOND_SWORD),
|
||||
new ItemStack(Items.DIAMOND_BOOTS),
|
||||
new ItemStack(Items.DIAMOND_LEGGINGS),
|
||||
new ItemStack(Items.DIAMOND_CHESTPLATE),
|
||||
new ItemStack(Items.DIAMOND_HELMET),
|
||||
};
|
||||
|
||||
int y = 60;
|
||||
|
||||
for (ItemStack item : items) {
|
||||
if (renderItem(context, item, y)) {
|
||||
y -= 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "Armor display";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon("armor");
|
||||
}
|
||||
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigManager getConfig() {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package org.saturnclient.saturnmods.mods;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnmods.HudMod;
|
||||
import org.saturnclient.saturnmods.ModDimensions;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class Coordinates implements SaturnMod, HudMod {
|
||||
|
||||
private static ConfigManager config = new ConfigManager("Coordinates");
|
||||
public static Property<Boolean> enabled = config.property(
|
||||
"Enabled",
|
||||
new Property<>(false));
|
||||
private static ModDimensions dimensions = new ModDimensions(config);
|
||||
|
||||
public static Property<Integer> fgColor = config.property(
|
||||
"Foreground color",
|
||||
new Property<>(SaturnClientConfig.WHITE, Property.PropertyType.HEX));
|
||||
|
||||
public Coordinates() {
|
||||
// Ensure fgColor has a value
|
||||
if (fgColor.value == null) {
|
||||
fgColor.value = SaturnClientConfig.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
public void renderDummy(DrawContext context) {
|
||||
int playerX = 124;
|
||||
int playerY = 69;
|
||||
int playerZ = 83;
|
||||
|
||||
context.drawText(
|
||||
SaturnClientConfig.textRenderer,
|
||||
playerX + " " + playerY + " " + playerZ,
|
||||
0,
|
||||
0,
|
||||
fgColor.value,
|
||||
false);
|
||||
|
||||
dimensions.width = SaturnClientConfig.textRenderer.getWidth(
|
||||
playerX + " " + playerY + " " + playerZ);
|
||||
dimensions.height = SaturnClientConfig.textRenderer.fontHeight;
|
||||
}
|
||||
|
||||
public void render(DrawContext context) {
|
||||
PlayerEntity player = MinecraftClient.getInstance().player;
|
||||
int playerX = (int) player.getX();
|
||||
int playerY = (int) player.getY();
|
||||
int playerZ = (int) player.getZ();
|
||||
|
||||
context.drawText(
|
||||
SaturnClientConfig.textRenderer,
|
||||
playerX + " " + playerY + " " + playerZ,
|
||||
0,
|
||||
0,
|
||||
fgColor.value,
|
||||
false);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "Coords";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon("coords");
|
||||
}
|
||||
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigManager getConfig() {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package org.saturnclient.saturnmods.mods;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class Crosshair implements SaturnMod {
|
||||
public static ConfigManager config = new ConfigManager("Crosshair");
|
||||
|
||||
public static Property<Boolean> enabled = config.property(
|
||||
"Enabled",
|
||||
new Property<>(false));
|
||||
|
||||
public static Property<Boolean> range_indicator = config.property(
|
||||
"Hit range indicator",
|
||||
new Property<>(false));
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Crosshair";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon("crosshair");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigManager getConfig() {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package org.saturnclient.saturnmods.mods;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnmods.HudMod;
|
||||
import org.saturnclient.saturnmods.ModDimensions;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class FpsDisplay implements SaturnMod, HudMod {
|
||||
|
||||
public static ConfigManager config = new ConfigManager("Fps Display");
|
||||
|
||||
public static Property<Boolean> enabled = config.property(
|
||||
"Enabled",
|
||||
new Property<>(false));
|
||||
|
||||
public static ModDimensions dimensions = new ModDimensions(
|
||||
config,
|
||||
0,
|
||||
0,
|
||||
40,
|
||||
8);
|
||||
|
||||
public static Property<Integer> fgColor = config.property(
|
||||
"Foreground color",
|
||||
new Property<>(SaturnClientConfig.WHITE, Property.PropertyType.HEX));
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(DrawContext context) {
|
||||
int fps = 128;
|
||||
|
||||
context.drawText(
|
||||
SaturnClientConfig.textRenderer,
|
||||
String.valueOf(fps) + " FPS",
|
||||
0,
|
||||
0,
|
||||
fgColor.value,
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context) {
|
||||
int fps = MinecraftClient.getInstance().getCurrentFps();
|
||||
|
||||
context.drawText(
|
||||
SaturnClientConfig.textRenderer,
|
||||
String.valueOf(fps) + " FPS",
|
||||
0,
|
||||
0,
|
||||
fgColor.value,
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Fps Display";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon("fps");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigManager getConfig() {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package org.saturnclient.saturnmods.mods;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
import net.minecraft.client.option.Perspective;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class FreeLook implements SaturnMod {
|
||||
public static boolean isFreeLooking = false;
|
||||
public static Perspective lastPerspective = null;
|
||||
|
||||
private static ConfigManager config = new ConfigManager("Free Look");
|
||||
public static Property<Boolean> enabled = config.property(
|
||||
"Enabled",
|
||||
new Property<>(false));
|
||||
|
||||
public static Property<Boolean> toggle = config.property(
|
||||
"Toggle Free Look",
|
||||
new Property<>(false));
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigManager getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon("freelook");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Free Look";
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package org.saturnclient.saturnmods.mods;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class Particles implements SaturnMod {
|
||||
public static ConfigManager config = new ConfigManager("Particles");
|
||||
|
||||
public static Property<Boolean> enabled = config.property(
|
||||
"Enabled",
|
||||
new Property<>(false));
|
||||
|
||||
public static ConfigManager totem = new ConfigManager(config, "Totem particles");
|
||||
|
||||
public static Property<Boolean> totem_enabled = totem.property(
|
||||
"Change totem color",
|
||||
new Property<>(false));
|
||||
|
||||
public static Property<Integer> totem_1 = totem.property(
|
||||
"Totem particle color 1",
|
||||
new Property<>(SaturnClientConfig.color.value, Property.PropertyType.HEX));
|
||||
|
||||
public static Property<Integer> totem_2 = totem.property(
|
||||
"Totem particle color 2",
|
||||
new Property<>(SaturnClientConfig.color.value, Property.PropertyType.HEX));
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Particles";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon("particles");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigManager getConfig() {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -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,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 net.minecraft.client.MinecraftClient;
|
||||
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 = MinecraftClient.getInstance().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 net.minecraft.client.MinecraftClient;
|
||||
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 = MinecraftClient.getInstance().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,179 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
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 SaturnInteger extends SaturnWidget {
|
||||
|
||||
String text = "";
|
||||
public Property<Integer> prop;
|
||||
public int cursorPosition = 0;
|
||||
private TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
|
||||
|
||||
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 = 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) && 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(
|
||||
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;
|
||||
}
|
||||
|
||||
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,105 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.menus.ConfigEditor;
|
||||
import org.saturnclient.saturnmods.SaturnMod;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnModComp extends SaturnWidget {
|
||||
|
||||
SaturnMod mod;
|
||||
|
||||
public SaturnModComp(SaturnMod 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(
|
||||
SaturnClientConfig.textRenderer,
|
||||
SaturnUi.text(mod.getName()),
|
||||
20,
|
||||
(21 - SaturnClientConfig.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)) {
|
||||
MinecraftClient.getInstance()
|
||||
.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 net.minecraft.client.MinecraftClient;
|
||||
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 = MinecraftClient.getInstance().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,79 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.DiffuseLighting;
|
||||
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
// If you think this code is bad, it's because it's written by Mojang
|
||||
|
||||
public class SkinPreview extends SaturnWidget {
|
||||
public static void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, int size, float f, float mouseX,
|
||||
float mouseY, LivingEntity entity, float angle, boolean negativeAngle) {
|
||||
float g = (float) (x1 + x2) / 2.0F;
|
||||
float h = (float) (y1 + y2) / 2.0F;
|
||||
context.enableScissor(0, 6, x2, y2);
|
||||
float i = (float) Math.atan((double) ((g - mouseX) / 40.0F));
|
||||
float j = (float) Math.atan((double) ((h - mouseY) / 40.0F));
|
||||
Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F);
|
||||
float k = entity.bodyYaw;
|
||||
float l = entity.getYaw();
|
||||
float m = entity.getPitch();
|
||||
float n = entity.prevHeadYaw;
|
||||
float o = entity.headYaw;
|
||||
entity.setYaw(angle);
|
||||
entity.bodyYaw = angle;
|
||||
entity.setPitch(-j * 20.0F);
|
||||
entity.headYaw = negativeAngle ? -i * 40.0F : i * 40.0F;
|
||||
entity.prevHeadYaw = entity.getHeadYaw();
|
||||
entity.setCustomNameVisible(false);
|
||||
|
||||
float p = entity.getScale();
|
||||
Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F);
|
||||
float q = (float) size / p;
|
||||
drawEntity(context, g, h, q, vector3f, quaternionf, null, entity);
|
||||
|
||||
entity.setCustomNameVisible(true);
|
||||
entity.bodyYaw = k;
|
||||
entity.setYaw(l);
|
||||
entity.setPitch(m);
|
||||
entity.prevHeadYaw = n;
|
||||
entity.headYaw = o;
|
||||
context.disableScissor();
|
||||
}
|
||||
|
||||
public static void drawEntity(DrawContext context, float x, float y, float size, Vector3f vector3f,
|
||||
Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) {
|
||||
context.getMatrices().push();
|
||||
context.getMatrices().translate((double) x, (double) y, 50.0);
|
||||
context.getMatrices().scale(size, size, -size);
|
||||
context.getMatrices().translate(vector3f.x, vector3f.y, vector3f.z);
|
||||
context.getMatrices().multiply(quaternionf);
|
||||
context.draw();
|
||||
DiffuseLighting.method_34742();
|
||||
EntityRenderDispatcher entityRenderDispatcher = MinecraftClient.getInstance().getEntityRenderDispatcher();
|
||||
|
||||
entityRenderDispatcher.setRenderShadows(false);
|
||||
context.draw((vertexConsumers) -> {
|
||||
entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, context.getMatrices(), vertexConsumers,
|
||||
15728880);
|
||||
});
|
||||
context.draw();
|
||||
entityRenderDispatcher.setRenderShadows(true);
|
||||
context.getMatrices().pop();
|
||||
DiffuseLighting.enableGuiDepthLighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, boolean hovering, int mouseX, int mouseY) {
|
||||
LivingEntity entity = MinecraftClient.getInstance().player;
|
||||
if (entity != null) {
|
||||
drawEntity(context, 0, 0, 75, 78, 30, 0.0625F, mouseX, mouseY, entity, -30.0f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
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;
|
||||
|
||||
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 = MinecraftClient.getInstance();
|
||||
|
||||
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 net.minecraft.client.MinecraftClient;
|
||||
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 = MinecraftClient.getInstance().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,36 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
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 = SaturnClientConfig.textRenderer.getWidth(SaturnUi.text(text));
|
||||
this.height = SaturnClientConfig.textRenderer.fontHeight;
|
||||
}
|
||||
|
||||
public SaturnText(String text, int color) {
|
||||
this(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
context.drawText(
|
||||
SaturnClientConfig.textRenderer,
|
||||
SaturnUi.text(text),
|
||||
0,
|
||||
0,
|
||||
SaturnClientConfig.getColor(hovering, alpha),
|
||||
false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.saturnclient.ui2;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
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 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.height = height;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Element position(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Element centerHorizontal(int w, int h, int offsetX, int offsetY) {
|
||||
this.x = (w - (int) (width * scale)) / 2 + offsetX;
|
||||
this.y = offsetY;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
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 org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
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.VertexConsumer;
|
||||
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.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ModelTransformationMode;
|
||||
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.world.World;
|
||||
|
||||
public class RenderScope {
|
||||
public MatrixStack matrices;
|
||||
public VertexConsumerProvider.Immediate vertexConsumers;
|
||||
// private Function<Identifier, RenderLayer> renderLayers;
|
||||
private ScissorStack scissorStack = new ScissorStack();
|
||||
private int opacity = 255 << 24;
|
||||
private final ItemRenderState itemRenderState;
|
||||
|
||||
public RenderScope(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) {
|
||||
this.matrices = matrices;
|
||||
this.vertexConsumers = vertexConsumers;
|
||||
this.scissorStack = new ScissorStack();
|
||||
this.itemRenderState = new ItemRenderState();
|
||||
}
|
||||
|
||||
public void setOpacity(float alpha) {
|
||||
this.opacity = (int) (alpha * 255) << 24;
|
||||
}
|
||||
|
||||
public int getColor(int color) {
|
||||
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) {
|
||||
color = getColor(color);
|
||||
Matrix4f matrix4f = this.matrices.peek().getPositionMatrix();
|
||||
|
||||
int x1 = x;
|
||||
int x2 = x + width;
|
||||
int y1 = y;
|
||||
int y2 = y + height;
|
||||
|
||||
int i;
|
||||
if (x1 < x2) {
|
||||
i = x1;
|
||||
x1 = x2;
|
||||
x2 = i;
|
||||
}
|
||||
|
||||
if (y1 < y2) {
|
||||
i = y1;
|
||||
y1 = y2;
|
||||
y2 = i;
|
||||
}
|
||||
|
||||
VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui());
|
||||
vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, 0).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, 0).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, 0).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color);
|
||||
}
|
||||
|
||||
public void drawText(String text, int x, int y, int font, int color) {
|
||||
drawText(1.0f, text, x, y, font, 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 h = height * 20;
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
int startX = 0;
|
||||
|
||||
if (y < radius) {
|
||||
double dy = radius - y - 0.5;
|
||||
double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy));
|
||||
startX = radius - (int) dx;
|
||||
}
|
||||
|
||||
this.drawRect(startX, y, w - startX, 1, color);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) {
|
||||
// Top
|
||||
this.matrices.push();
|
||||
|
||||
this.matrices.scale(0.05f, 0.05f, 1.0f);
|
||||
|
||||
this.drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color);
|
||||
|
||||
this.matrices.pop();
|
||||
|
||||
// Bottom
|
||||
this.matrices.push();
|
||||
|
||||
this.matrices.translate(cornerWidth, cornerHeight * 2, 0);
|
||||
|
||||
this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90));
|
||||
|
||||
this.matrices.translate(0, -cornerWidth, 0);
|
||||
|
||||
this.matrices.scale(0.05f, 0.05f, 1.0f);
|
||||
|
||||
this.drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color);
|
||||
|
||||
this.matrices.pop();
|
||||
}
|
||||
|
||||
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 cornerHeight = height / 2;
|
||||
|
||||
this.matrices.push();
|
||||
|
||||
this.matrices.translate(x, y, 0);
|
||||
|
||||
this.drawRoundedSide(cornerWidth, cornerHeight, radius, color);
|
||||
|
||||
this.matrices.translate(cornerWidth * 2, cornerHeight * 2, 0);
|
||||
|
||||
this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180));
|
||||
|
||||
this.matrices.translate(0, 0, 0);
|
||||
|
||||
this.drawRoundedSide(cornerWidth, cornerHeight, radius, color);
|
||||
|
||||
this.matrices.pop();
|
||||
}
|
||||
|
||||
public int getScaledWindowWidth() {
|
||||
return SaturnClient.client.getWindow().getScaledWidth();
|
||||
}
|
||||
|
||||
public int getScaledWindowHeight() {
|
||||
return SaturnClient.client.getWindow().getScaledHeight();
|
||||
}
|
||||
public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int color) {
|
||||
this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color);
|
||||
}
|
||||
|
||||
public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height) {
|
||||
this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height);
|
||||
}
|
||||
|
||||
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(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1);
|
||||
}
|
||||
|
||||
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(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(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);
|
||||
RenderLayer renderLayer = (RenderLayer)RenderLayer.getGuiTextured(sprite);
|
||||
Matrix4f matrix4f = this.matrices.peek().getPositionMatrix();
|
||||
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)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)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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package org.saturnclient.ui2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.RotatingCubeMapRenderer;
|
||||
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.util.Identifier;
|
||||
|
||||
public abstract class SaturnScreen extends Screen {
|
||||
private final Pool pool = new Pool(3);
|
||||
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) {
|
||||
super(Text.literal(title));
|
||||
}
|
||||
|
||||
public void draw(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);
|
||||
}
|
||||
|
||||
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
|
||||
protected void init() {
|
||||
elements.clear();
|
||||
width *= 2;
|
||||
height *= 2;
|
||||
ui(); // abstraction to render the saturn ui and also render extra stuff here
|
||||
|
||||
Animation.execute((Float progress) -> {
|
||||
blurProgress = progress;
|
||||
}, blurDuration);
|
||||
}
|
||||
|
||||
public abstract void ui();
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
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
|
||||
// use DrawContext
|
||||
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||
((DrawContextAccessor) context).getVertexConsumers());
|
||||
|
||||
renderScope.matrices.push();
|
||||
|
||||
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
||||
|
||||
ElementRenderer.render(new ArrayList<>(elements), renderScope, mouseX, mouseY);
|
||||
|
||||
renderScope.matrices.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
mouseX *= 2;
|
||||
mouseY *= 2;
|
||||
|
||||
ElementRenderer.mouseClicked(elements, mouseX, mouseY, button);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.saturnclient.ui2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
public class Utils {
|
||||
public static boolean isHovering(int mouseX, int mouseY, int elementWidth, int elementHeight, float elementScale) {
|
||||
return mouseX >= 0 &&
|
||||
mouseX <= (elementWidth * elementScale) &&
|
||||
mouseY >= 0 &&
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.saturnclient.ui2.components;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
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.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public class SkinPreview extends Element {
|
||||
private boolean negativeAngle = false;
|
||||
private float angle = 0.0f;
|
||||
|
||||
public SkinPreview(float angle, boolean negativeAngle) {
|
||||
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 g = (float) (x1 + x2) / 2.0F;
|
||||
float h = (float) (y1 + y2) / 2.0F;
|
||||
renderScope.enableScissor(0, 6, x2, y2);
|
||||
float i = (float) Math.atan((double) ((g - mouseX) / 40.0F));
|
||||
float j = (float) Math.atan((double) ((h - mouseY) / 40.0F));
|
||||
Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F);
|
||||
float k = entity.bodyYaw;
|
||||
float l = entity.getYaw();
|
||||
float m = entity.getPitch();
|
||||
float n = entity.prevHeadYaw;
|
||||
float o = entity.headYaw;
|
||||
entity.setYaw(angle);
|
||||
entity.bodyYaw = angle;
|
||||
entity.setPitch(-(j * 20.0F));
|
||||
entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F);
|
||||
entity.prevHeadYaw = entity.getHeadYaw();
|
||||
entity.setCustomNameVisible(false);
|
||||
|
||||
float p = entity.getScale();
|
||||
Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F);
|
||||
float q = (float) size / p;
|
||||
drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity);
|
||||
|
||||
entity.setCustomNameVisible(true);
|
||||
entity.bodyYaw = k;
|
||||
entity.setYaw(l);
|
||||
entity.setPitch(m);
|
||||
entity.prevHeadYaw = n;
|
||||
entity.headYaw = o;
|
||||
renderScope.disableScissor();
|
||||
}
|
||||
|
||||
public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f,
|
||||
Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) {
|
||||
renderScope.matrices.push();
|
||||
renderScope.matrices.translate((double) x, (double) y, 50.0);
|
||||
renderScope.matrices.scale(size, size, -size);
|
||||
renderScope.matrices.translate(vector3f.x, vector3f.y, vector3f.z);
|
||||
renderScope.matrices.multiply(quaternionf);
|
||||
renderScope.draw();
|
||||
DiffuseLighting.method_34742();
|
||||
EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher();
|
||||
|
||||
entityRenderDispatcher.setRenderShadows(false);
|
||||
renderScope.draw((vertexConsumers) -> {
|
||||
entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, renderScope.matrices, vertexConsumers,
|
||||
15728880);
|
||||
});
|
||||
renderScope.draw();
|
||||
entityRenderDispatcher.setRenderShadows(true);
|
||||
renderScope.matrices.pop();
|
||||
DiffuseLighting.enableGuiDepthLighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
LivingEntity entity = SaturnClient.client.player;
|
||||
if (entity != null) {
|
||||
drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, negativeAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user