Compare 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 |
@@ -8,11 +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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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-alpha4
|
||||
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
|
||||
|
||||
@@ -6,27 +6,32 @@ import org.saturnclient.saturnclient.config.NamedProperty;
|
||||
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 Property<Integer> bgColor = new Property<>(0xFF000000, Property.PropertyType.HEX);
|
||||
public Property<Integer> fgColor = new Property<>(0xFFffffff, Property.PropertyType.HEX);
|
||||
public Property<Integer> radius = new Property<>(0);
|
||||
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 new Property<Map<String, Property<?>>>(Map.of(
|
||||
return Property.namespace(Map.of(
|
||||
"X", x,
|
||||
"Y", y,
|
||||
"Scale", scale,
|
||||
"Background Color", bgColor,
|
||||
"Foreground Color", fgColor,
|
||||
"Corner Radius", radius
|
||||
"Corner Radius", radius,
|
||||
"Font", font
|
||||
)).named("In-Game Display");
|
||||
}
|
||||
|
||||
public ModDimensions() {}
|
||||
|
||||
public ModDimensions(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
|
||||
import org.saturnclient.modules.mods.*;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
public class ModManager {
|
||||
public static Module[] MODS = {
|
||||
new Crosshair(),
|
||||
new AutoSprint(),
|
||||
new ArmorDisplay()
|
||||
new Crosshair(),
|
||||
new AutoSprint(),
|
||||
new ArmorDisplay(),
|
||||
new Fps(),
|
||||
new PotionDisplay(),
|
||||
new Coordinates(),
|
||||
new Freelook(),
|
||||
new Keystrokes()
|
||||
};
|
||||
|
||||
public static void init() {
|
||||
@@ -25,35 +24,5 @@ public class ModManager {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
HudRenderCallback.EVENT.register((context, _o) -> {
|
||||
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
|
||||
if (textRenderer != null &&
|
||||
!(SaturnClient.client.currentScreen instanceof HudEditor)) {
|
||||
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||
((DrawContextAccessor) context).getVertexConsumers());
|
||||
|
||||
for (Module m : MODS) {
|
||||
if (m instanceof HudMod && m.isEnabled()) {
|
||||
ModDimensions dim = ((HudMod) m).getDimensions();
|
||||
|
||||
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);
|
||||
|
||||
renderScope.drawRoundedRectangle(0, 0, dim.width, dim.height, dim.radius.value, dim.bgColor.value);
|
||||
|
||||
((HudMod) m).renderHud(renderScope);
|
||||
|
||||
renderScope.matrices.pop();
|
||||
} else {
|
||||
m.render(renderScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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**
|
||||
@@ -13,11 +13,12 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
|
||||
public class ArmorDisplay extends Module implements HudMod {
|
||||
private static Property<Boolean> enabled = new Property<>(true);
|
||||
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")
|
||||
super(new ModuleDetails("Armor Display", "armor")
|
||||
.description("Displays armor durability")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
enabled.named("Enabled"),
|
||||
@@ -51,8 +52,10 @@ public class ArmorDisplay extends Module implements HudMod {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderHealth(RenderScope scope, int i, int max, int current) {
|
||||
scope.drawText(0.5f, String.valueOf(((double) current / max) * 100) + "%", 17, (15 * i) + 3, false, dimensions.fgColor.value);
|
||||
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
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
|
||||
public class AutoSprint extends Module {
|
||||
private static Property<Boolean> enabled = new Property<>(true);
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
|
||||
public AutoSprint() {
|
||||
super(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,7 @@ import org.saturnclient.ui2.resources.Textures;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
|
||||
public class Crosshair extends Module {
|
||||
public static Property<Boolean> enabled = new Property<>(false);
|
||||
public static Property<Boolean> range_indicator = new Property<>(false);
|
||||
public static Property<Boolean> enabled = Property.bool(false);
|
||||
|
||||
public Crosshair() {
|
||||
super(
|
||||
@@ -19,14 +18,12 @@ public class Crosshair extends Module {
|
||||
.description("Changes the crosshair if you're aiming at a entity")
|
||||
.tags("Visuals", "Utility")
|
||||
.version("v0.1.0"),
|
||||
enabled.named("Enabled"),
|
||||
range_indicator.named("Range Indicator"));
|
||||
enabled.named("Enabled"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope scope) {
|
||||
if (enabled.value
|
||||
&& range_indicator.value
|
||||
&& SaturnClient.client.targetedEntity != null
|
||||
&& SaturnClient.client.targetedEntity.isAlive()) {
|
||||
int scaledWidth = 15;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class Fps extends Module implements HudMod {
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight());
|
||||
|
||||
public Fps() {
|
||||
super(new ModuleDetails("FPS Display", "fps")
|
||||
.description("Displays current FPS")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
enabled.named("Enabled"),
|
||||
dimensions.prop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
String text = String.valueOf(SaturnClient.client.getCurrentFps()) + " FPS";
|
||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
String text = "369 FPS";
|
||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
|
||||
import net.minecraft.client.option.Perspective;
|
||||
|
||||
public class Freelook extends Module {
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
private static Property<Boolean> toggle = Property.bool(true);
|
||||
public static Property<Integer> freelookKey = Property.keybinding(GLFW.GLFW_KEY_H);
|
||||
public static boolean isFreeLooking = false;
|
||||
private static boolean was1stPerson = false;
|
||||
|
||||
public Freelook() {
|
||||
super(
|
||||
new ModuleDetails("Freelook", "freelook")
|
||||
.description("Allows you to look around freely without moving your character")
|
||||
.tags("Movement", "Camera")
|
||||
.version("0.1.0"),
|
||||
enabled.named("Enabled"),
|
||||
toggle.named("Toggle freelook"),
|
||||
freelookKey.named("Freelook Keybinding")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (toggle.value) {
|
||||
if (freelookKey.wasKeyPressed()) {
|
||||
if (isFreeLooking) {
|
||||
stopFreelook();
|
||||
} else {
|
||||
startFreelook();
|
||||
}
|
||||
}
|
||||
} else if (freelookKey.isKeyPressed()) {
|
||||
if (!isFreeLooking) {
|
||||
startFreelook();
|
||||
}
|
||||
} else if (isFreeLooking) {
|
||||
stopFreelook();
|
||||
}
|
||||
}
|
||||
|
||||
private void startFreelook() {
|
||||
isFreeLooking = true;
|
||||
was1stPerson = SaturnClient.client.options.getPerspective() == Perspective.FIRST_PERSON;
|
||||
SaturnClient.client.options.setPerspective(Perspective.THIRD_PERSON_BACK);
|
||||
}
|
||||
|
||||
private void stopFreelook() {
|
||||
if (was1stPerson) {
|
||||
SaturnClient.client.options.setPerspective(Perspective.FIRST_PERSON);
|
||||
}
|
||||
isFreeLooking = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
|
||||
public class Keystrokes extends Module implements HudMod {
|
||||
public static Property<Boolean> enabled = Property.bool(false);
|
||||
public static Property<Boolean> showMouse = Property.bool(true);
|
||||
public static Property<Boolean> showSpace = Property.bool(false);
|
||||
public static ModDimensions dimensions = new ModDimensions(78, 46);
|
||||
private boolean w = false;
|
||||
private boolean a = false;
|
||||
private boolean s = false;
|
||||
private boolean d = false;
|
||||
private boolean lmb = false;
|
||||
private boolean rmb = false;
|
||||
private boolean space = false;
|
||||
|
||||
private static Property<Integer> clickBg = Property.color(0xFFCCCCCC);
|
||||
private static Property<Integer> clickFg = Property.color(0xFFFFFFFF);
|
||||
|
||||
public Keystrokes() {
|
||||
super(new ModuleDetails("Keystrokes", "keystrokes")
|
||||
.description("Displays the keystrokes for movement")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
|
||||
enabled.named("Enabled"),
|
||||
showMouse.named("Show mouse clicks"),
|
||||
showSpace.named("Show space clicks"),
|
||||
dimensions.prop(),
|
||||
clickFg.named("Clicked fg"),
|
||||
clickBg.named("Clicked bg"));
|
||||
|
||||
dimensions.renderBackground = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
w = SaturnClient.client.options.forwardKey.isPressed();
|
||||
a = SaturnClient.client.options.leftKey.isPressed();
|
||||
s = SaturnClient.client.options.backKey.isPressed();
|
||||
d = SaturnClient.client.options.rightKey.isPressed();
|
||||
lmb = SaturnClient.client.options.attackKey.isPressed();
|
||||
rmb = SaturnClient.client.options.useKey.isPressed();
|
||||
space = SaturnClient.client.options.jumpKey.isPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
dimensions.height = 54; // base height with padding considered
|
||||
|
||||
// WASD keys (3px padding between each key)
|
||||
renderKey(scope, true, 'W', 27, 0); // Top center
|
||||
renderKey(scope, false, 'A', 0, 27); // Bottom left
|
||||
renderKey(scope, false, 'S', 27, 27); // Bottom center
|
||||
renderKey(scope, false, 'D', 54, 27); // Bottom right
|
||||
|
||||
if (showMouse.value) {
|
||||
renderKeyM(scope, true, "LMB", 0, 54); // Below A/S/D
|
||||
renderKeyM(scope, false, "RMB", 40, 54); // With 3px between
|
||||
dimensions.height += 27;
|
||||
}
|
||||
|
||||
if (showSpace.value) {
|
||||
renderKeySpace(scope, false, 0, dimensions.height);
|
||||
dimensions.height += 22;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
dimensions.height = 54; // base height with padding considered
|
||||
|
||||
// WASD keys (3px padding between each key)
|
||||
renderKey(scope, w, 'W', 27, 0); // Top center
|
||||
renderKey(scope, a, 'A', 0, 27); // Bottom left
|
||||
renderKey(scope, s, 'S', 27, 27); // Bottom center
|
||||
renderKey(scope, d, 'D', 54, 27); // Bottom right
|
||||
|
||||
if (showMouse.value) {
|
||||
renderKeyM(scope, lmb, "LMB", 0, 54); // Below A/S/D
|
||||
renderKeyM(scope, rmb, "RMB", 40, 54); // With 3px between
|
||||
dimensions.height += 27;
|
||||
}
|
||||
|
||||
if (showSpace.value) {
|
||||
renderKeySpace(scope, space, 0, dimensions.height);
|
||||
dimensions.height += 22;
|
||||
}
|
||||
}
|
||||
|
||||
// Consistent 3px padding applied below:
|
||||
|
||||
private void renderKeySpace(RenderScope scope, boolean isPressed, int x, int y) {
|
||||
int height = 19;
|
||||
scope.drawRoundedRectangle(x, y, dimensions.width, height, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||
|
||||
// A 30-pixel line centered vertically with 3px top padding
|
||||
int lineY = y + (height - 1) / 2;
|
||||
scope.drawRect(x + (dimensions.width - 30) / 2, lineY, 30, 1, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||
}
|
||||
|
||||
private void renderKeyM(RenderScope scope, boolean isPressed, String c, int x, int y) {
|
||||
int width = 38, height = 24;
|
||||
scope.drawRoundedRectangle(x, y, width, height, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||
|
||||
// Apply padding: 3px top and left -> add slight offset to x/y
|
||||
scope.drawText(0.6f, c, x + 9, y + 7, dimensions.font.value, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||
}
|
||||
|
||||
private void renderKey(RenderScope scope, boolean isPressed, char c, int x, int y) {
|
||||
int size = 24;
|
||||
scope.drawRoundedRectangle(x, y, size, size, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||
|
||||
// Center the character with 3px top padding
|
||||
scope.drawText(0.6f, String.valueOf(c), x + 9, y + 7, dimensions.font.value, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.StatusEffectSpriteManager;
|
||||
import net.minecraft.entity.effect.StatusEffect;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class PotionDisplay extends Module implements HudMod {
|
||||
public static Property<Boolean> enabled = Property.bool(false);
|
||||
private static ModDimensions dimensions = new ModDimensions(60, 0);
|
||||
|
||||
private final StatusEffectInstance[] dummyEffects = {
|
||||
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2),
|
||||
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2),
|
||||
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2),
|
||||
};
|
||||
|
||||
public PotionDisplay() {
|
||||
super(new ModuleDetails("Potion Display", "potion")
|
||||
.description("Displays potion effects")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
|
||||
enabled.named("Enabled"),
|
||||
dimensions.prop());
|
||||
}
|
||||
|
||||
private void renderEffects(RenderScope scope, Iterable<StatusEffectInstance> effects) {
|
||||
int row = 0;
|
||||
|
||||
StatusEffectSpriteManager statusEffectSpriteManager = SaturnClient.client.getStatusEffectSpriteManager();
|
||||
|
||||
for (StatusEffectInstance effect : effects) {
|
||||
if (effect.shouldShowIcon()) {
|
||||
RegistryEntry<StatusEffect> registryEntry = effect.getEffectType();
|
||||
Sprite sprite = statusEffectSpriteManager.getSprite(registryEntry);
|
||||
scope.drawSpriteStretched(sprite, 0, 18 * row, 16, 16);
|
||||
scope.drawText(0.5f, getDurationAsString(effect), 18, 18 * row + 3, dimensions.font.value, -1);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
dimensions.height = 18 * row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
renderEffects(scope, SaturnClient.client.player.getStatusEffects());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
renderEffects(scope, Arrays.asList(dummyEffects));
|
||||
}
|
||||
|
||||
// This code was from: https://github.com/magicus/statuseffecttimer/blob/master/src/main/java/se/icus/mag/statuseffecttimer/mixin/StatusEffectTimerMixin.java
|
||||
private String getDurationAsString(StatusEffectInstance statusEffectInstance) {
|
||||
if (statusEffectInstance.isInfinite()) {
|
||||
return I18n.translate("effect.duration.infinite");
|
||||
}
|
||||
|
||||
int ticks = MathHelper.floor((float) statusEffectInstance.getDuration());
|
||||
int totalSeconds = ticks / 20;
|
||||
|
||||
if (totalSeconds >= 3600) {
|
||||
return totalSeconds / 3600 + "h";
|
||||
} else if (totalSeconds >= 60) {
|
||||
int minutes = totalSeconds / 60;
|
||||
int seconds = totalSeconds % 60;
|
||||
return String.format("%d:%02d", minutes, seconds);
|
||||
} else {
|
||||
return String.valueOf(totalSeconds) + "s";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.saturnclient.modules.mods.mixins;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import org.saturnclient.modules.mods.Freelook;
|
||||
import org.saturnclient.modules.mods.utils.CameraOverriddenEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Camera.class)
|
||||
public abstract class CameraMixin {
|
||||
@Unique
|
||||
boolean firstTime = true;
|
||||
|
||||
@Shadow
|
||||
protected abstract void setRotation(float yaw, float pitch);
|
||||
|
||||
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
|
||||
public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, float tickDelta, CallbackInfo ci) {
|
||||
if (Freelook.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) {
|
||||
CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity;
|
||||
|
||||
if (firstTime && MinecraftClient.getInstance().player != null) {
|
||||
cameraOverriddenEntity.freelook$setCameraPitch(MinecraftClient.getInstance().player.getPitch());
|
||||
cameraOverriddenEntity.freelook$setCameraYaw(MinecraftClient.getInstance().player.getYaw());
|
||||
firstTime = false;
|
||||
}
|
||||
this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), cameraOverriddenEntity.freelook$getCameraPitch());
|
||||
|
||||
}
|
||||
if (!Freelook.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) {
|
||||
firstTime = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.saturnclient.modules.mods.mixins;
|
||||
|
||||
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import org.saturnclient.modules.mods.Freelook;
|
||||
import org.saturnclient.modules.mods.utils.CameraOverriddenEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public class EntityMixin implements CameraOverriddenEntity {
|
||||
@Unique
|
||||
private float cameraPitch;
|
||||
|
||||
@Unique
|
||||
private float cameraYaw;
|
||||
|
||||
@Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true)
|
||||
public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) {
|
||||
//noinspection ConstantValue// IntelliJ is incorrect here, this code block is reachable
|
||||
if (Freelook.isFreeLooking && (Object) this instanceof ClientPlayerEntity) {
|
||||
double pitchDelta = (yDelta * 0.15);
|
||||
double yawDelta = (xDelta * 0.15);
|
||||
|
||||
this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f);
|
||||
this.cameraYaw += (float) yawDelta;
|
||||
|
||||
ci.cancel();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public float freelook$getCameraPitch() {
|
||||
return this.cameraPitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public float freelook$getCameraYaw() {
|
||||
return this.cameraYaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public void freelook$setCameraPitch(float pitch) {
|
||||
this.cameraPitch = pitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public void freelook$setCameraYaw(float yaw) {
|
||||
this.cameraYaw = yaw;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.saturnclient.modules.mods.mixins;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.ModManager;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.hud.InGameHud;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
|
||||
@Mixin(InGameHud.class)
|
||||
public class RenderMixin {
|
||||
@Inject(method = "renderChat", at = @At("TAIL"))
|
||||
public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
|
||||
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
|
||||
if (textRenderer != null &&
|
||||
!(SaturnClient.client.currentScreen instanceof HudEditor)) {
|
||||
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||
((DrawContextAccessor) context).getVertexConsumers());
|
||||
|
||||
for (org.saturnclient.modules.Module m : ModManager.MODS) {
|
||||
if (m instanceof HudMod && m.isEnabled()) {
|
||||
ModDimensions dim = ((HudMod) m).getDimensions();
|
||||
|
||||
renderScope.matrices.push();
|
||||
|
||||
renderScope.matrices.translate(dim.x.value, (float) dim.y.value, 0);
|
||||
|
||||
renderScope.matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
||||
|
||||
if (dim.renderBackground) {
|
||||
renderScope.drawRoundedRectangle(0, 0, dim.width, dim.height, dim.radius.value,
|
||||
dim.bgColor.value);
|
||||
}
|
||||
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
|
||||
((HudMod) m).renderHud(renderScope);
|
||||
|
||||
renderScope.matrices.pop();
|
||||
} else {
|
||||
m.render(renderScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.saturnclient.modules.mods.utils;
|
||||
|
||||
public interface CameraOverriddenEntity {
|
||||
float freelook$getCameraPitch();
|
||||
float freelook$getCameraYaw();
|
||||
|
||||
void freelook$setCameraPitch(float pitch);
|
||||
void freelook$setCameraYaw(float yaw);
|
||||
}
|
||||
@@ -2,14 +2,23 @@ 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.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.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;
|
||||
|
||||
@@ -30,14 +39,42 @@ public class SaturnClient implements ModInitializer {
|
||||
client = MinecraftClient.getInstance();
|
||||
SaturnClientConfig.init();
|
||||
ModManager.init();
|
||||
|
||||
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save());
|
||||
|
||||
|
||||
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,6 +1,7 @@
|
||||
package org.saturnclient.saturnclient;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
@@ -10,11 +11,10 @@ import net.minecraft.util.Identifier;
|
||||
public class SaturnClientConfig {
|
||||
public static ConfigManager config;
|
||||
|
||||
public static Property<Boolean> realisticLogo =
|
||||
new Property<>(false);
|
||||
public static Property<Boolean> realisticLogo = Property.bool(false);
|
||||
|
||||
public static Property<Boolean> saturnTitleScreen =
|
||||
new Property<>(true);
|
||||
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;
|
||||
@@ -45,5 +45,6 @@ public class SaturnClientConfig {
|
||||
config = new ConfigManager("Saturn Client");
|
||||
config.property("Realistic logo", realisticLogo);
|
||||
config.property("Saturn client title screen", saturnTitleScreen);
|
||||
config.property("Open Emote Wheel", openEmoteWheel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,22 @@ package org.saturnclient.saturnclient.auth;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
import org.saturnclient.saturnclient.cosmetics.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 {
|
||||
@@ -96,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;
|
||||
}
|
||||
@@ -161,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);
|
||||
}
|
||||
@@ -169,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("-", ""));
|
||||
@@ -184,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)) {
|
||||
SaturnClient.client.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -32,8 +32,7 @@ public class ConfigManager {
|
||||
|
||||
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);
|
||||
@@ -41,14 +40,12 @@ public class ConfigManager {
|
||||
}
|
||||
|
||||
public void sub(String namespace) {
|
||||
Property<Map<String, Property<?>>> namespaceProperty = new Property<>(currentMap,
|
||||
Property.PropertyType.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) {
|
||||
System.out.println("Adding property: " + name);
|
||||
currentMap.put(name, value);
|
||||
loadProp(name, value);
|
||||
return value;
|
||||
@@ -100,7 +97,6 @@ public class ConfigManager {
|
||||
new String(Files.readAllBytes(configFile.toPath()))).getAsJsonObject();
|
||||
|
||||
for (String namespace : properties.keySet()) {
|
||||
SaturnClient.LOGGER.info("Loading namespace: " + namespace);
|
||||
JsonElement configElement = jsonObject.get(namespace);
|
||||
|
||||
if (configElement == null)
|
||||
@@ -122,8 +118,6 @@ public class ConfigManager {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void loadProperties(JsonObject config, Map<String, Property<?>> propertyMap) {
|
||||
SaturnClient.LOGGER.info("Loading properties: " + propertyMap);
|
||||
|
||||
for (String propertyName : propertyMap.keySet()) {
|
||||
JsonElement c = config.get(propertyName);
|
||||
|
||||
@@ -139,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 {
|
||||
@@ -203,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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -154,4 +199,60 @@ public class Property<T> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,126 +3,75 @@ package org.saturnclient.saturnclient.config;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
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.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
public class ThemeManager {
|
||||
|
||||
private static File themeFile = new File(
|
||||
SaturnClient.client.runDirectory,
|
||||
"saturn.theme.json");
|
||||
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
||||
private static List<ThemeManager> theme = new ArrayList<>();
|
||||
private static JsonObject cachedThemeJson = null;
|
||||
|
||||
// private Map<String, Map<String, Property<?>>> states;
|
||||
private Map<String, Map<String, Object>> states;
|
||||
private Map<String, Property<?>> currentStyling;
|
||||
private String state;
|
||||
private String[] states;
|
||||
private String namespace;
|
||||
|
||||
public ThemeManager(String namespace, String... states) {
|
||||
// this.states = new LinkedHashMap<>();
|
||||
this.namespace = namespace;
|
||||
this.states = states;
|
||||
currentStyling = new LinkedHashMap<>();
|
||||
|
||||
properties.put(namespace, new LinkedHashMap<>());
|
||||
|
||||
this.states = new LinkedHashMap<>();
|
||||
this.currentStyling = new LinkedHashMap<>();
|
||||
this.states.put(null, new LinkedHashMap<>());
|
||||
for (String s : states) {
|
||||
properties.put(namespace+"@"+s, new LinkedHashMap<>());
|
||||
this.states.put(s, new LinkedHashMap<>());
|
||||
}
|
||||
theme.add(this);
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
if (this.state != null) {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace+"@"+state).entrySet()) {
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace).entrySet()) {
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
|
||||
}
|
||||
for (Map.Entry<String, Object> tProp : states.get(state).entrySet()) {
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void applyState(String state) {
|
||||
if (this.state != null) {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace+"@"+state).entrySet()) {
|
||||
Property<?> p = currentStyling.get(tProp.getKey());
|
||||
Property<?> currProp = properties.get(namespace).get(tProp.getKey());
|
||||
if (p.value.equals(currProp.value)) {
|
||||
p.setValue(tProp.getValue().value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setState(state);
|
||||
for (Map.Entry<String, Object> tProp : states.get(state).entrySet()) {
|
||||
if (!states.get(null).get(tProp.getKey()).equals(tProp.getValue()))
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// Generic method to store any type of property
|
||||
public <T> Property<T> property(String name, Property<T> prop) {
|
||||
for (String state : states) {
|
||||
Property<?> property = new Property<T>(prop.value);
|
||||
properties.get(namespace+"@"+state).put(name, property);
|
||||
loadProp(state, name, property);
|
||||
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);
|
||||
}
|
||||
|
||||
loadProp(null, name, prop);
|
||||
properties.get(namespace).put(name, new Property<T>(prop.value));
|
||||
currentStyling.put(name, prop);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public <T> void propertyStateDefault(String state, String name, T value) {
|
||||
Property<?> prop = properties.get(namespace+"@"+state).get(name);
|
||||
prop.setValue(value, value); // sets the current and default value
|
||||
loadProp(state, name, prop);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void loadProp(String state, String name, Property<T> prop) {
|
||||
Property<?> prop = currentStyling.get(name).copy();
|
||||
prop.setValue(value, value);
|
||||
if (cachedThemeJson == null) {
|
||||
load();
|
||||
}
|
||||
|
||||
JsonElement element = cachedThemeJson.get(state != null ? namespace+"@"+state : 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
prop.load(name, cachedThemeJson.get(state != null ? namespace + "@" + state : namespace));
|
||||
states.get(state).put(name, prop.value);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
@@ -134,85 +83,11 @@ public class ThemeManager {
|
||||
}
|
||||
|
||||
cachedThemeJson = JsonParser.parseString(
|
||||
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
|
||||
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
|
||||
|
||||
SaturnClient.LOGGER.info("Theme loaded");
|
||||
} catch (IOException e) {
|
||||
SaturnClient.LOGGER.error("Error reading the theme file", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
try {
|
||||
SaturnClient.LOGGER.info("Starting to save theme...");
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
|
||||
// Iterate through all namespaces and their properties
|
||||
for (String namespace : properties.keySet()) {
|
||||
JsonObject namespaceTheme = new JsonObject();
|
||||
Map<String, Property<?>> propertyMap = properties.get(namespace);
|
||||
|
||||
// Save properties for this namespace
|
||||
saveProperties(namespaceTheme, propertyMap);
|
||||
|
||||
// Add the namespace theme to the main JSON object
|
||||
jsonObject.add(namespace, namespaceTheme);
|
||||
}
|
||||
|
||||
// Format the json so it can easily be edited
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
String formattedJson = gson.toJson(jsonObject);
|
||||
|
||||
// Write the JSON object to the theme file
|
||||
Files.write(themeFile.toPath(), formattedJson.getBytes());
|
||||
SaturnClient.LOGGER.info("Theme saved successfully.");
|
||||
} catch (IOException e) {
|
||||
SaturnClient.LOGGER.error("Error saving the theme file", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void saveProperties(JsonObject theme, Map<String, Property<?>> propertyMap) {
|
||||
// Iterate through each property in the namespace
|
||||
for (String propertyName : propertyMap.keySet()) {
|
||||
Property<?> property = propertyMap.get(propertyName);
|
||||
JsonElement propertyValue = null;
|
||||
|
||||
if (property.getType() == Property.PropertyType.NAMESPACE) {
|
||||
// Handle nested namespace
|
||||
JsonObject nestedTheme = new JsonObject();
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
||||
saveProperties(nestedTheme, nestedProperties);
|
||||
propertyValue = nestedTheme;
|
||||
} else {
|
||||
// Convert the property value based on its type
|
||||
switch (property.getType()) {
|
||||
case BOOLEAN:
|
||||
propertyValue = new JsonPrimitive((Boolean) property.value);
|
||||
break;
|
||||
case INTEGER:
|
||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
||||
break;
|
||||
case FLOAT:
|
||||
propertyValue = new JsonPrimitive((Float) property.value);
|
||||
break;
|
||||
case STRING:
|
||||
propertyValue = new JsonPrimitive((String) property.value);
|
||||
break;
|
||||
case HEX:
|
||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
||||
break;
|
||||
default:
|
||||
SaturnClient.LOGGER.warn(
|
||||
"Unknown property type for: " + propertyName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyValue != null) {
|
||||
theme.add(propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.saturnclient.saturnclient.cosmetics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Emotes {
|
||||
public static List<String> availableEmotes = new ArrayList<>();
|
||||
|
||||
public static void initialize() {
|
||||
availableEmotes.add("tpose");
|
||||
availableEmotes.add("back_flip");
|
||||
availableEmotes.add("facepalm");
|
||||
availableEmotes.add("cry");
|
||||
availableEmotes.add("giga_chad");
|
||||
availableEmotes.add("front_flip");
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState,
|
||||
PlayerEntityRenderState state, float limbAngle, float limbDistance) {
|
||||
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;
|
||||
|
||||
@@ -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.
|
||||
@@ -101,20 +112,25 @@ public class Cloaks {
|
||||
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 {
|
||||
|
||||
@@ -3,12 +3,17 @@ package org.saturnclient.saturnclient.event;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
// import net.minecraft.client.option.Perspective;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
|
||||
// import org.saturnclient.modules.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 org.saturnclient.saturnclient.menus.SaturnMenu;
|
||||
|
||||
import dev.kosmx.playerAnim.api.layered.AnimationStack;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
@@ -21,55 +26,30 @@ public class KeyInputHandler {
|
||||
private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT;
|
||||
private static 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 ShiftMenu());
|
||||
}
|
||||
// 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;
|
||||
// }
|
||||
// }
|
||||
|
||||
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,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ public class Element {
|
||||
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) {
|
||||
}
|
||||
@@ -31,45 +32,45 @@ public class Element {
|
||||
public void charTyped(char typedChar) {
|
||||
}
|
||||
|
||||
public final Element dimensions(int width, int height) {
|
||||
public Element dimensions(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element position(int x, int y) {
|
||||
public Element position(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element centerHorizontal(int w, int h, int offsetX, int offsetY) {
|
||||
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 final Element center(int w, int h) {
|
||||
public Element center(int w, int h) {
|
||||
this.centerOffset(w, h, 0, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element centerOffset(int w, int h, int offsetX, int offsetY) {
|
||||
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 final Element animation(Animation animation) {
|
||||
public Element animation(Animation animation) {
|
||||
this.animation = animation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element animation(Animation animation, Function<Double, Double> curve) {
|
||||
public Element animation(Animation animation, Function<Double, Double> curve) {
|
||||
this.animation = animation;
|
||||
this.curve = curve;
|
||||
return this;
|
||||
|
||||
@@ -21,6 +21,7 @@ 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;
|
||||
@@ -36,7 +37,7 @@ import net.minecraft.world.World;
|
||||
public class RenderScope {
|
||||
public MatrixStack matrices;
|
||||
public VertexConsumerProvider.Immediate vertexConsumers;
|
||||
private Function<Identifier, RenderLayer> renderLayers;
|
||||
// private Function<Identifier, RenderLayer> renderLayers;
|
||||
private ScissorStack scissorStack = new ScissorStack();
|
||||
private int opacity = 255 << 24;
|
||||
private final ItemRenderState itemRenderState;
|
||||
@@ -60,7 +61,7 @@ public class RenderScope {
|
||||
}
|
||||
|
||||
public void setRenderLayer(Function<Identifier, RenderLayer> renderLayers) {
|
||||
this.renderLayers = renderLayers;
|
||||
// this.renderLayers = renderLayers;
|
||||
}
|
||||
|
||||
public void drawRect(int x, int y, int width, int height, int color) {
|
||||
@@ -92,20 +93,22 @@ public class RenderScope {
|
||||
vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color);
|
||||
}
|
||||
|
||||
public void drawText(String text, int x, int y, boolean bold, int color) {
|
||||
drawText(1.0f, text, x, y, bold, 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, boolean bold, int color) {
|
||||
public void drawText(float scale, String text, int x, int y, int font, int color) {
|
||||
if (font == 0) {
|
||||
scale *= 2;
|
||||
}
|
||||
int i = 0;
|
||||
for (String line : text.split("\n")) {
|
||||
color = getColor(color);
|
||||
Identifier font = bold ? Fonts.INTER_BOLD : Fonts.INTER;
|
||||
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, font), 0, 7, color, false, this.matrices.peek().getPositionMatrix(),
|
||||
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++;
|
||||
@@ -179,7 +182,7 @@ public class RenderScope {
|
||||
|
||||
public int getScaledWindowWidth() {
|
||||
return SaturnClient.client.getWindow().getScaledWidth();
|
||||
}
|
||||
}
|
||||
|
||||
public int getScaledWindowHeight() {
|
||||
return SaturnClient.client.getWindow().getScaledHeight();
|
||||
@@ -209,31 +212,31 @@ public class RenderScope {
|
||||
|
||||
matrices.push();
|
||||
matrices.scale(0.25f, 0.25f, 1.0f);
|
||||
RenderSystem.setShaderTexture(0, sprite);
|
||||
RenderLayer renderLayer = (RenderLayer)renderLayers.apply(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();
|
||||
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() {
|
||||
public void disableScissor() {
|
||||
this.setScissor(this.scissorStack.pop());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean scissorContains(int x, int y) {
|
||||
public boolean scissorContains(int x, int y) {
|
||||
return this.scissorStack.containsPoint(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
private void setScissor(@Nullable ScreenRect rect) {
|
||||
private void setScissor(@Nullable ScreenRect rect) {
|
||||
this.draw();
|
||||
if (rect != null) {
|
||||
Window window = SaturnClient.client.getWindow();
|
||||
@@ -290,68 +293,78 @@ public class RenderScope {
|
||||
}
|
||||
|
||||
public void drawItem(ItemStack item, int x, int y) {
|
||||
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0);
|
||||
}
|
||||
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) {
|
||||
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 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) {
|
||||
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 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);
|
||||
}
|
||||
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) {
|
||||
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)));
|
||||
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();
|
||||
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.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();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
@@ -50,6 +51,25 @@ public abstract class SaturnScreen extends Screen {
|
||||
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
|
||||
@@ -93,7 +113,7 @@ public abstract class SaturnScreen extends Screen {
|
||||
|
||||
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
||||
|
||||
ElementRenderer.render(elements, renderScope, mouseX, mouseY);
|
||||
ElementRenderer.render(new ArrayList<>(elements), renderScope, mouseX, mouseY);
|
||||
|
||||
renderScope.matrices.pop();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
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) {
|
||||
@@ -44,4 +47,9 @@ public class Utils {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +44,32 @@ public abstract class Animation {
|
||||
}
|
||||
}).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,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;
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,10 @@ 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", new Property<Integer>(0xAA000000));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> padding = theme.property("padding", new Property<Integer>(14));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", new Property<Integer>(10));
|
||||
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 {}
|
||||
|
||||
|
||||
@@ -16,13 +16,14 @@ 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", new Property<>(0xFF1d202d));
|
||||
private static Property<Integer> fgColor = theme.property("fg", new Property<>(0xFFA1A2B8));
|
||||
private static Property<Integer> iconFg = theme.property("icon-fg", new Property<>(0xFFA1A2B8));
|
||||
private static Property<Integer> iconBg = theme.property("icon-bg", new Property<>(0xFF2e3248));
|
||||
private static Property<Integer> tagBg = theme.property("tag-bg", new Property<>(0xFF2e3248));
|
||||
private static Property<Integer> iconRadius = theme.property("icon-radius", new Property<>(10));
|
||||
private static Property<Integer> radius = theme.property("radius", new Property<>(10));
|
||||
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);
|
||||
@@ -64,15 +65,15 @@ public class SaturnModule extends Element {
|
||||
|
||||
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, true, fgColor.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(), false) * 0.35f), p + 1, false, 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, false) * 0.4f);
|
||||
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, false, fgColor.value);
|
||||
renderScope.drawText(0.4f, tag, xt+2, p + (h/2) + 3, font.value, fgColor.value);
|
||||
xt += xtb + 9;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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;
|
||||
@@ -8,23 +9,23 @@ 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.CloakMenu;
|
||||
import org.saturnclient.ui2.screens.HatMenu;
|
||||
import org.saturnclient.ui2.screens.ConfigEditor;
|
||||
import org.saturnclient.ui2.screens.ModMenu;
|
||||
import org.saturnclient.ui2.screens.SaturnConfigEditor;
|
||||
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", new Property<Integer>(0x90000000));
|
||||
private static Property<Integer> iconFg = theme.property("icon-fg", new Property<Integer>(-1));
|
||||
private static Property<Integer> iconBg = theme.property("icon-bg", new Property<Integer>(0x00000000));
|
||||
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", new Property<Integer>(10));
|
||||
private static Property<Integer> iconRadius = theme.property("icon-radius", new Property<Integer>(10));
|
||||
private static Property<Integer> padding = theme.property("padding", new Property<Integer>(10));
|
||||
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);
|
||||
@@ -48,20 +49,20 @@ public class Sidebar extends Element {
|
||||
SaturnClient.client.setScreen(new ModMenu());
|
||||
}, false),
|
||||
new Sidebar.SidebarComponent(Textures.SETTINGS, () -> {
|
||||
SaturnClient.client.setScreen(new SaturnConfigEditor());
|
||||
SaturnClient.client.setScreen(new ConfigEditor(SaturnClientConfig.config));
|
||||
}, false),
|
||||
|
||||
new Sidebar.SidebarComponent(Textures.CLOAK, () -> {
|
||||
new Sidebar.SidebarComponent(Textures.SHIRT, () -> {
|
||||
SaturnClient.client.setScreen(new CloakMenu());
|
||||
}, false),
|
||||
|
||||
new Sidebar.SidebarComponent(Textures.HAT, () -> {
|
||||
SaturnClient.client.setScreen(new HatMenu());
|
||||
}, false),
|
||||
|
||||
new Sidebar.SidebarComponent(Textures.CLOSE, () -> {
|
||||
onClose.run();
|
||||
}, true)
|
||||
}, true),
|
||||
|
||||
new Sidebar.SidebarComponent(Textures.STORE, () -> {
|
||||
SaturnClient.client.setScreen(new CloakStore());
|
||||
}, true),
|
||||
};
|
||||
int active = 0;
|
||||
|
||||
@@ -77,9 +78,9 @@ public class Sidebar extends Element {
|
||||
int topRow = 0;
|
||||
int bottomRow = 0;
|
||||
|
||||
int sp = 30 - padding.value;
|
||||
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);
|
||||
@@ -100,7 +101,7 @@ public class Sidebar extends Element {
|
||||
renderScope.drawTexture(component.sprite, padding.value, y, 0, 0, s, s, iconFg.value);
|
||||
bottomRow += 1;
|
||||
} else {
|
||||
int y = padding.value + ((sp) * topRow);
|
||||
int y = padding.value + (sp * topRow);
|
||||
if (ctx.isHovering(0, y - (padding.value / 2), s2, s2) || active == i) {
|
||||
theme.setState("hovering");
|
||||
} else {
|
||||
@@ -120,19 +121,22 @@ public class Sidebar extends Element {
|
||||
int topRow = 0;
|
||||
int bottomRow = 0;
|
||||
|
||||
int sp = 30 - padding.value;
|
||||
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) {
|
||||
if (Utils.isHovering(mouseX, mouseY - (height - (sp * bottomRow) - (s * 2)), s2, s2, scale)) {
|
||||
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 {
|
||||
if (Utils.isHovering(mouseX, mouseY - (padding.value + ((sp) * topRow)), s2, s2, scale)) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,17 @@ package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public abstract class Input extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Input");
|
||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||
|
||||
String text = "";
|
||||
public int cursorPosition = 0;
|
||||
public abstract void checkReset();
|
||||
@@ -66,12 +71,11 @@ public abstract class Input extends Element {
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = getVisibleText(scrollOffset);
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
renderScope.drawText(0.6f, visibleText, 4, 4, false, textColor);
|
||||
renderScope.drawText(0.6f, visibleText, 4, 4, font.value, textColor);
|
||||
|
||||
if (focused) {
|
||||
int cursorX = 4 +
|
||||
(int) (SaturnClient.client.textRenderer.getWidth(
|
||||
Fonts.setFont(visibleText.substring(0, cursorPosition - scrollOffset))) * 0.6f);
|
||||
(int) (Fonts.getWidth(visibleText.substring(0, cursorPosition - scrollOffset), font.value) * 0.6f);
|
||||
|
||||
renderScope.drawRect(cursorX, 2, 1, height - 4, 0xFFFFFFFF);
|
||||
}
|
||||
@@ -86,7 +90,7 @@ public abstract class Input extends Element {
|
||||
int maxWidth = width - 4; // Available width for text
|
||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||
String visibleText = text.substring(offset, cursorPosition);
|
||||
if (SaturnClient.client.textRenderer.getWidth(Fonts.setFont(visibleText)) > maxWidth) {
|
||||
if (Fonts.getWidth(visibleText, font.value) > maxWidth) {
|
||||
offset++;
|
||||
} else {
|
||||
break;
|
||||
@@ -100,8 +104,7 @@ public abstract class Input extends Element {
|
||||
|
||||
// Ensure text does not overflow past the available width
|
||||
for (int i = 1; i <= visibleText.length(); i++) {
|
||||
if (SaturnClient.client.textRenderer.getWidth(
|
||||
Fonts.setFont(visibleText.substring(0, i))) > width - 4) {
|
||||
if (Fonts.getWidth(visibleText.substring(0, i), font.value) > width - 4) {
|
||||
return visibleText.substring(0, i - 1); // Trim overflow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class KeybindingSelector extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Input");
|
||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||
Property<Integer> prop;
|
||||
|
||||
public KeybindingSelector(Property<Integer> prop) {
|
||||
this.prop = prop;
|
||||
this.width = 120;
|
||||
this.height = Fonts.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
||||
renderScope.drawText(0.6f, prop.value == -1 ? "<NONE>" :
|
||||
GLFW.glfwGetKeyName(prop.value, GLFW.glfwGetKeyScancode(prop.value)).toUpperCase(),
|
||||
4, 4, font.value, textColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
prop.value = -1;
|
||||
} else {
|
||||
prop.value = keyCode;
|
||||
}
|
||||
focused = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
|
||||
public class Select extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Toggle");
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xAAAAAA));
|
||||
private static Property<Integer> arrowColor = theme.property("arrow-color", Property.color(0xff8B5CF6));
|
||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||
|
||||
private Property<Integer> prop;
|
||||
|
||||
public Select(Property<Integer> prop) {
|
||||
this.prop = prop;
|
||||
this.width = 150;
|
||||
this.height = 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
|
||||
renderScope.drawText(0.8f, "<", 0, 0, font.value, arrowColor.value);
|
||||
|
||||
String text = prop.getSelection();
|
||||
|
||||
renderScope.drawText(0.6f, text, (int) (width - ((float) Fonts.getWidth(text, font.value) * 0.6f)) / 2, 1, font.value, fgColor.value);
|
||||
|
||||
renderScope.drawText(0.8f, ">", width - 10, 0, font.value, arrowColor.value);
|
||||
|
||||
theme.setState(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
if (Utils.isHovering(mouseX - (width - 10), mouseY, 10, height, 1.0f)) {
|
||||
prop.next();
|
||||
} else if (Utils.isHovering(mouseX, mouseY, 10, height, 1.0f)) {
|
||||
prop.prev();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,9 @@ import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
public class Toggle extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Toggle", "hovering", "enabled");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0xFF808080));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFF909090));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", new Property<Integer>(30));
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF808080));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFF909090));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(30));
|
||||
|
||||
static {
|
||||
theme.propertyStateDefault("enabled", "bg-color", 0xaf8B5CF6);
|
||||
@@ -27,6 +27,8 @@ public class Toggle extends Element {
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
theme.setState(null);
|
||||
|
||||
if (prop.value) {
|
||||
theme.setState("enabled");
|
||||
}
|
||||
@@ -38,8 +40,6 @@ public class Toggle extends Element {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30, fgColor.value);
|
||||
|
||||
theme.setState(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,10 +9,10 @@ import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class Button extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Button", "hovering");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0xFF000000));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", new Property<Integer>(10));
|
||||
private static Property<Boolean> bold = theme.property("fg-bold", new Property<Boolean>(false));
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
||||
|
||||
static {
|
||||
theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee);
|
||||
@@ -24,7 +24,7 @@ public class Button extends Element {
|
||||
public Button(String text, Runnable onClick) {
|
||||
this.text = text;
|
||||
this.onClick = onClick;
|
||||
this.dimensions(Fonts.getWidth(text, bold.value) + 50, 38);
|
||||
this.dimensions(Fonts.getWidth(text, font.value) + 50, 38);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,7 +37,7 @@ public class Button extends Element {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
// renderScope.drawText(text, (width - Fonts.getWidth(text, font)) / 2, (height - Fonts.getHeight()) / 2, bold.value, fgColor.value);
|
||||
renderScope.drawText(text, Fonts.centerX(width, text, bold.value), Fonts.centerY(height), bold.value, fgColor.value);
|
||||
renderScope.drawText(text, Fonts.centerX(width, text, font.value), Fonts.centerY(height), font.value, fgColor.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,7 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
public class ClickableTexture extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("ClickableTexture", "hovering");
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||
|
||||
Identifier sprite;
|
||||
private Runnable onClick;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.saturnclient.ui2.elements;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.anim.SlideX;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
public class Notification extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Notification");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
||||
private static Property<Integer> error = theme.property("error", Property.color(0xFFbf212f));
|
||||
private static Property<Integer> info = theme.property("info", Property.color(0xFF264b96));
|
||||
private static Property<Integer> success = theme.property("success", Property.color(0xFF27b376));
|
||||
|
||||
public static enum NotificationKind {
|
||||
Error,
|
||||
Info,
|
||||
Success,
|
||||
}
|
||||
|
||||
NotificationKind kind;
|
||||
String text;
|
||||
String title;
|
||||
|
||||
public Notification(int width, int height, NotificationKind kind, String title, String text) {
|
||||
this.kind = kind;
|
||||
this.text = text;
|
||||
this.title = title;
|
||||
this.width = (int) Math.max(Fonts.getWidth(text, 1) * 0.6f, Fonts.getWidth(title, 1)) + 20;
|
||||
this.height = 50;
|
||||
this.x = width - this.width - 15;
|
||||
this.y = height - this.height - 15;
|
||||
this.animation = new SlideX(700, -width);
|
||||
this.duration = 3000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, bgColor.value);
|
||||
switch (kind) {
|
||||
case Error:
|
||||
renderScope.drawTexture(Textures.CIRCLE_X, 9, 9, 0, 0, 15, 15, error.value);
|
||||
break;
|
||||
|
||||
case Info:
|
||||
renderScope.drawTexture(Textures.INFO, 9, 9, 0, 0, 15, 15, info.value);
|
||||
break;
|
||||
|
||||
case Success:
|
||||
renderScope.drawTexture(Textures.CHECK, 9, 9, 0, 0, 15, 15, success.value);
|
||||
break;
|
||||
}
|
||||
renderScope.drawText(0.7f, title, 32, 10, 1, -1);
|
||||
renderScope.drawText(0.5f, text, 32, 28, 1, -1);
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,13 @@ import org.saturnclient.ui2.components.ElementRenderer;
|
||||
|
||||
public class Scroll extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Scroll");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0x90000000));
|
||||
private static Property<Integer> scrollBarColor = theme.property("scrollbar-color", new Property<Integer>(-7643914));
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
||||
private static Property<Integer> scrollBarColor = theme.property("scrollbar-color", Property.color(-7643914));
|
||||
|
||||
private static Property<Integer> scrollBarRadius = theme.property("scrollbar-radius", new Property<Integer>(10));
|
||||
private static Property<Integer> scrollBarWidth = theme.property("scrollbar-width", new Property<Integer>(5));
|
||||
private static Property<Integer> scrollBarPadding = theme.property("scrollbar-padding", new Property<Integer>(5));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", new Property<Integer>(10));
|
||||
private static Property<Integer> scrollBarRadius = theme.property("scrollbar-radius", Property.integer(10));
|
||||
private static Property<Integer> scrollBarWidth = theme.property("scrollbar-width", Property.integer(5));
|
||||
private static Property<Integer> scrollBarPadding = theme.property("scrollbar-padding", Property.integer(5));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||
|
||||
int padding = 0;
|
||||
|
||||
@@ -61,16 +61,14 @@ public class Scroll extends Element {
|
||||
|
||||
public void draw(Element element) {
|
||||
children.add(element);
|
||||
}
|
||||
|
||||
if (element.width > width) {
|
||||
width = element.width;
|
||||
@Override
|
||||
public Element dimensions(int width, int height) {
|
||||
for (Element element : children) {
|
||||
maxScroll = Math.max(maxScroll, element.y + element.height - height);
|
||||
}
|
||||
|
||||
if (element.height > height) {
|
||||
height = element.height;
|
||||
}
|
||||
|
||||
maxScroll = Math.max(maxScroll, element.y - maxScroll);
|
||||
return super.dimensions(width, height);
|
||||
}
|
||||
|
||||
int calculateScrollBarHeight() {
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.saturnclient.ui2.elements;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class TabMenu extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("TabMenu", "hovering", "selected");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
||||
private static Property<Integer> iconFg = theme.property("icon-fg", Property.color(0xFFFFFFFF));
|
||||
private static Property<Integer> iconBg = theme.property("icon-bg", Property.color(0x00000000));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||
|
||||
static {
|
||||
theme.propertyStateDefault("hovering", "icon-bg", -7643914);
|
||||
}
|
||||
|
||||
public static class TabMenuComponent {
|
||||
Runnable onClick;
|
||||
Identifier sprite;
|
||||
|
||||
public TabMenuComponent(Identifier sprite, Runnable onClick) {
|
||||
this.onClick = onClick;
|
||||
this.sprite = sprite;
|
||||
}
|
||||
}
|
||||
|
||||
TabMenuComponent[] components;
|
||||
public int selectedScreen = 0;
|
||||
|
||||
public TabMenu(int active, TabMenuComponent... components) {
|
||||
this.components = components;
|
||||
width = 25 * components.length + 6;
|
||||
height = 30;
|
||||
this.selectedScreen = active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
int col = 0;
|
||||
for (TabMenuComponent component : components) {
|
||||
int x = 25 * col + 5;
|
||||
if (ctx.isHovering(x, 5, 20, 20) || selectedScreen == col) {
|
||||
theme.setState("hovering");
|
||||
}
|
||||
|
||||
renderScope.drawRoundedRectangle(x, 5, 20, 20, cornerRadius.value, iconBg.value);
|
||||
renderScope.drawTexture(component.sprite, x + 5, 10, 0, 0, 10, 10, iconFg.value);
|
||||
|
||||
theme.setState(null);
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int col = 0;
|
||||
for (TabMenuComponent component : components) {
|
||||
int x = 25 * col + 5;
|
||||
if (Utils.isHovering(mouseX - x, mouseY - 5, 20, 20, 1.0f)) {
|
||||
component.onClick.run();
|
||||
}
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,23 @@ import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class Text extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Text");
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||
public static Property<Integer> font = theme.property("font", Property.font(1));
|
||||
|
||||
private String text;
|
||||
|
||||
public Text(String text) {
|
||||
this.text = text;
|
||||
width = Fonts.getWidth(text, font.value);
|
||||
height = Fonts.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawText(this.text, 0, 0, false, fgColor.value);
|
||||
renderScope.drawText(this.text, 0, 0, font.value, fgColor.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
public class TextureButton extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("TextureButton", "hovering");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0xFF000000));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> padding = theme.property("padding", new Property<Integer>(14));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", new Property<Integer>(10));
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||
private static Property<Integer> padding = theme.property("padding", Property.integer(14));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
||||
|
||||
|
||||
static {
|
||||
|
||||
@@ -8,12 +8,16 @@ import net.minecraft.util.Identifier;
|
||||
public class Fonts {
|
||||
public static final Identifier INTER = Identifier.of("saturnclient", "inter");
|
||||
public static final Identifier INTER_BOLD = Identifier.of("saturnclient", "inter_bold");
|
||||
public static final Identifier DEFAULT = Identifier.ofVanilla("default");
|
||||
|
||||
public static Identifier getFont(boolean bold) {
|
||||
if (bold) {
|
||||
return INTER_BOLD;
|
||||
} else {
|
||||
return INTER;
|
||||
public static Identifier getFont(int font) {
|
||||
switch (font) {
|
||||
case 0:
|
||||
return DEFAULT;
|
||||
case 1:
|
||||
return INTER;
|
||||
default:
|
||||
return INTER_BOLD;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,35 +26,28 @@ public class Fonts {
|
||||
Style.EMPTY.withFont(font));
|
||||
}
|
||||
|
||||
public static Text setFont(String text, boolean bold) {
|
||||
return Text.literal(text).setStyle(
|
||||
Style.EMPTY.withFont(bold ? INTER_BOLD : INTER));
|
||||
public static int getWidth(String text, int font) {
|
||||
int w = 0;
|
||||
for (String line : text.split("\n")) {
|
||||
w = Math.max(w, getWidth(line, getFont(font)));
|
||||
}
|
||||
if (font == 0) {
|
||||
return w * 2;
|
||||
} else {
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
public static Text setFont(String text) {
|
||||
return Text.literal(text).setStyle(
|
||||
Style.EMPTY.withFont(INTER));
|
||||
}
|
||||
|
||||
// public static int getWidth(String text, Identifier font) {
|
||||
// return SaturnClient.client.textRenderer.getWidth(Text.literal(text).setStyle(
|
||||
// Style.EMPTY.withFont(font)));
|
||||
// }
|
||||
|
||||
// public static int getHeight() {
|
||||
// return SaturnClient.client.textRenderer.fontHeight;
|
||||
// }
|
||||
|
||||
public static int getWidth(String text, boolean bold) {
|
||||
return SaturnClient.client.textRenderer.getWidth(setFont(text, getFont(bold)));
|
||||
private static int getWidth(String text, Identifier font) {
|
||||
return SaturnClient.client.textRenderer.getWidth(setFont(text, font));
|
||||
}
|
||||
|
||||
public static int getHeight() {
|
||||
return 18;
|
||||
}
|
||||
|
||||
public static int centerX(int w, String text, boolean bold) {
|
||||
return (w - Fonts.getWidth(text, bold)) / 2;
|
||||
public static int centerX(int w, String text, int font) {
|
||||
return (w - Fonts.getWidth(text, font)) / 2;
|
||||
}
|
||||
|
||||
public static int centerY(int h) {
|
||||
|
||||
@@ -15,11 +15,19 @@ public class Textures {
|
||||
public static final Identifier RESET = Identifier.of("saturnclient", "textures/gui/components/reset.png");
|
||||
public static final Identifier TOGGLE_INDICATOR = Identifier.of("saturnclient",
|
||||
"textures/gui/components/toggle_indicator.png");
|
||||
public static final Identifier TOGGLE_BG = Identifier.of("saturnclient", "textures/gui/components/toggle_bg.png");
|
||||
public static final Identifier LEFT = Identifier.of("saturnclient", "textures/gui/components/left.png");
|
||||
public static final Identifier RIGHT = Identifier.of("saturnclient", "textures/gui/components/right.png");
|
||||
public static final Identifier STORE = Identifier.of("saturnclient", "textures/gui/components/store.png");
|
||||
public static final Identifier COINS = Identifier.of("saturnclient", "textures/gui/components/coins.png");
|
||||
public static final Identifier SHIRT = Identifier.of("saturnclient", "textures/gui/components/shirt.png");
|
||||
public static final Identifier CIRCLE_X = Identifier.of("saturnclient", "textures/gui/components/circle_x.png");
|
||||
public static final Identifier INFO = Identifier.of("saturnclient", "textures/gui/components/info.png");
|
||||
public static final Identifier CHECK = Identifier.of("saturnclient", "textures/gui/components/check.png");
|
||||
|
||||
public static final Identifier LOGO = Identifier.of("saturnclient", "textures/logo/logo.png");
|
||||
public static final Identifier REALISTIC_LOGO = Identifier.of("saturnclient", "textures/logo/realistic.png");
|
||||
public static final Identifier LOGO_TEXT = Identifier.of("saturnclient", "textures/logo/text.png");
|
||||
public static final Identifier LOGO_TEXT_BIG = Identifier.of("saturnclient", "textures/logo/text_big.png");
|
||||
|
||||
// Widgets
|
||||
public static final Identifier BUTTON_BORDER = Identifier.of("saturnclient", "button_border");
|
||||
@@ -39,7 +47,12 @@ public class Textures {
|
||||
return Identifier.of("saturnclient", "textures/gui/hat/" + (hat.isEmpty() ? "none" : hat) + ".png");
|
||||
}
|
||||
|
||||
public static Identifier getEmotePreview(String emote) {
|
||||
return Identifier.of("saturnclient", "textures/gui/emote/" + (emote == null ? "none" : emote) + ".png");
|
||||
}
|
||||
|
||||
public static Identifier getModIcon(String modId) {
|
||||
return Identifier.of("saturnclient", "textures/gui/mod/" + modId + ".png");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.components.inputs.FloatInput;
|
||||
import org.saturnclient.ui2.components.inputs.HexInput;
|
||||
import org.saturnclient.ui2.components.inputs.IntInput;
|
||||
import org.saturnclient.ui2.components.inputs.KeybindingSelector;
|
||||
import org.saturnclient.ui2.components.inputs.Select;
|
||||
import org.saturnclient.ui2.components.inputs.Toggle;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.elements.Text;
|
||||
@@ -36,7 +38,7 @@ public class ConfigEditor extends SaturnScreen {
|
||||
|
||||
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
|
||||
|
||||
draw(new Sidebar(0, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
draw(new Sidebar(1, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -59,7 +61,7 @@ public class ConfigEditor extends SaturnScreen {
|
||||
configScroll.draw(
|
||||
new Text(
|
||||
propName
|
||||
).position(Fonts.centerX(520, propName, false), modY + 1).scale(0.7f));
|
||||
).position(Fonts.centerX(520, propName, Text.font.value), modY + 1).scale(0.7f));
|
||||
} else {
|
||||
configScroll.draw(
|
||||
new Text(
|
||||
@@ -91,6 +93,15 @@ public class ConfigEditor extends SaturnScreen {
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) prop.value;
|
||||
row = drawProperties(configScroll, nestedProperties, row + 1, col, w);
|
||||
break;
|
||||
|
||||
case SELECT:
|
||||
configScroll.draw(new Select((Property<Integer>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case KEYBINDING:
|
||||
configScroll.draw(new KeybindingSelector((Property<Integer>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package org.saturnclient.ui2.screens;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
// import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
import org.saturnclient.ui2.anim.Fade;
|
||||
import org.saturnclient.ui2.anim.SlideY;
|
||||
import org.saturnclient.ui2.elements.ImageTexture;
|
||||
import org.saturnclient.ui2.elements.TextureButton;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
import dev.kosmx.playerAnim.api.layered.AnimationStack;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class EmoteWheel extends SaturnScreen {
|
||||
int page = 1;
|
||||
|
||||
public EmoteWheel() {
|
||||
super("Emote Wheel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -105)
|
||||
.animation(new Fade(700)));
|
||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -149)
|
||||
.animation(new SlideY(700, -20)));
|
||||
|
||||
draw(new TextureButton(Textures.LEFT, () -> {
|
||||
if (page > 1) {
|
||||
page--;
|
||||
elements.clear();
|
||||
ui();
|
||||
}
|
||||
}).dimensions(30, 30).centerOffset(width, height, -20, 45).animation(new Fade(700)));
|
||||
|
||||
draw(new TextureButton(Textures.RIGHT, () -> {
|
||||
if ((8 * page) < Emotes.availableEmotes.size()) {
|
||||
page++;
|
||||
elements.clear();
|
||||
ui();
|
||||
}
|
||||
}).dimensions(30, 30).centerOffset(width, height, 20, 45).animation(new Fade(700)));
|
||||
|
||||
while (row < 3) {
|
||||
int idx = (row * 3 + col) * page;
|
||||
|
||||
if (row == 1 && col == 1) {
|
||||
col++;
|
||||
}
|
||||
|
||||
String emote = Utils.getOrNull(Emotes.availableEmotes, idx);
|
||||
|
||||
draw(new TextureButton(Textures.getEmotePreview(emote), () -> {
|
||||
if (emote == null) {
|
||||
return;
|
||||
}
|
||||
AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(SaturnClient.client.player);
|
||||
if (animationStack.isActive() && animationStack.getPriority() == 1000) {
|
||||
animationStack.removeLayer(1000);
|
||||
}
|
||||
animationStack.addAnimLayer(1000,
|
||||
PlayerAnimationRegistry.getAnimation(Identifier.of("saturnclient",
|
||||
emote)).playAnimation());
|
||||
Auth.emote(emote);
|
||||
close();
|
||||
}).dimensions(70, 70).centerOffset(width, height, -80 + (col * 80), -35 + (row * 80))
|
||||
.animation(new Fade(700)));
|
||||
|
||||
if (col < 2) {
|
||||
col++;
|
||||
} else {
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPause() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,9 @@ import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.components.SaturnModule;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.elements.ImageTexture;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
public class ModMenu extends SaturnScreen {
|
||||
public ModMenu() {
|
||||
@@ -38,5 +40,7 @@ public class ModMenu extends SaturnScreen {
|
||||
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
|
||||
|
||||
draw(new Sidebar(0, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT_BIG).dimensions(180, 18).position(width - 180 - 20, height - 18 - 20));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
package org.saturnclient.ui2.screens;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.components.inputs.FloatInput;
|
||||
import org.saturnclient.ui2.components.inputs.HexInput;
|
||||
import org.saturnclient.ui2.components.inputs.IntInput;
|
||||
import org.saturnclient.ui2.components.inputs.Toggle;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.elements.Text;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class SaturnConfigEditor extends SaturnScreen {
|
||||
public SaturnConfigEditor() {
|
||||
super("Saturn Config Editor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
int p = 10;
|
||||
int g = 10;
|
||||
|
||||
Scroll scroll = new Scroll(p);
|
||||
|
||||
drawProperties(scroll, SaturnClientConfig.config.getProperties(), 0, 0, 480 + 10 + (g * 2));
|
||||
|
||||
int scrollWidth = 480 + 10 + (g * 2) + (p * 2);
|
||||
|
||||
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
|
||||
|
||||
draw(new Sidebar(1, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private int drawProperties(Scroll configScroll, Map<String, Property<?>> properties, int row, int col, int w) {
|
||||
for (Map.Entry<String, Property<?>> propEntry : properties.entrySet()) {
|
||||
Property<?> prop = propEntry.getValue();
|
||||
String propName = propEntry.getKey();
|
||||
boolean full = isFull(prop);
|
||||
|
||||
// Always reset to col 0 if full-width component needs to be drawn mid-row
|
||||
if (full && col != 0) {
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
|
||||
int modX = (w / 2) * col; // two-column layout
|
||||
int modY = 25 * row;
|
||||
|
||||
if (prop.getType() == Property.PropertyType.NAMESPACE) {
|
||||
configScroll.draw(
|
||||
new Text(
|
||||
propName
|
||||
).position(Fonts.centerX(520, propName, false), modY + 1).scale(0.7f));
|
||||
} else {
|
||||
configScroll.draw(
|
||||
new Text(
|
||||
propName
|
||||
).position(modX, modY + 1).scale(0.7f));
|
||||
}
|
||||
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
configScroll.draw(
|
||||
new Toggle((Property<Boolean>) prop)
|
||||
.position(modX + (w / 2) - 40, modY)
|
||||
.scale(0.5f));
|
||||
break;
|
||||
|
||||
case HEX:
|
||||
configScroll.draw(new HexInput((Property<Integer>) prop, this).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
configScroll.draw(new IntInput((Property<Integer>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case FLOAT:
|
||||
configScroll.draw(new FloatInput((Property<Float>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case NAMESPACE:
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) prop.value;
|
||||
row = drawProperties(configScroll, nestedProperties, row + 1, col, w);
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
}
|
||||
|
||||
if (full) {
|
||||
row++; // full-width takes a whole row
|
||||
col = 0;
|
||||
} else {
|
||||
col++;
|
||||
if (col > 1) { // max 2 columns
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public static boolean isFull(Property<?> prop) {
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.elements.Button;
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.anim.Fade;
|
||||
import org.saturnclient.ui2.anim.SlideY;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.saturnclient.ui2.screens;
|
||||
package org.saturnclient.ui2.screens.cosmetics;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||
@@ -9,6 +10,8 @@ import org.saturnclient.ui2.components.CosmeticPreview;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.components.SkinPreview;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.elements.TabMenu;
|
||||
import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent;
|
||||
|
||||
public class CloakMenu extends SaturnScreen {
|
||||
public CloakMenu() {
|
||||
@@ -30,7 +33,7 @@ public class CloakMenu extends SaturnScreen {
|
||||
if (player != null) {
|
||||
for (String cloak : Cloaks.availableCloaks) {
|
||||
scroll.draw(new CosmeticPreview(cloak == player.cloak, Textures.getCloakPreview(cloak), () -> {
|
||||
Cloaks.setCloak(Auth.uuid, cloak);
|
||||
Cloaks.setCloak(cloak);
|
||||
}).position((50 + g) * col, (111 + g) * row));
|
||||
|
||||
if (col == 5) {
|
||||
@@ -49,5 +52,12 @@ public class CloakMenu extends SaturnScreen {
|
||||
draw(new SkinPreview(-30.0f, false).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y+40));
|
||||
|
||||
draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
|
||||
draw(new TabMenu(0,
|
||||
new TabMenuComponent(Textures.CLOAK, () -> {}),
|
||||
new TabMenuComponent(Textures.HAT, () -> {
|
||||
SaturnClient.client.setScreen(new HatMenu());
|
||||
})
|
||||
).centerOffset(width, height, 0, -195));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.saturnclient.ui2.screens;
|
||||
package org.saturnclient.ui2.screens.cosmetics;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
@@ -9,6 +10,8 @@ import org.saturnclient.ui2.components.CosmeticPreview;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.components.SkinPreview;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.elements.TabMenu;
|
||||
import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent;
|
||||
|
||||
public class HatMenu extends SaturnScreen {
|
||||
public HatMenu() {
|
||||
@@ -48,6 +51,13 @@ public class HatMenu extends SaturnScreen {
|
||||
|
||||
draw(new SkinPreview(170f, true).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y+40));
|
||||
|
||||
draw(new Sidebar(3, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
|
||||
draw(new TabMenu(1,
|
||||
new TabMenuComponent(Textures.CLOAK, () -> {
|
||||
SaturnClient.client.setScreen(new CloakMenu());
|
||||
}),
|
||||
new TabMenuComponent(Textures.HAT, () -> {})
|
||||
).centerOffset(width, height, 0, -195));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.saturnclient.ui2.screens.store;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.components.CosmeticPreview;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.elements.ImageTexture;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.elements.TabMenu;
|
||||
import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent;
|
||||
import org.saturnclient.ui2.elements.Text;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
public class CloakStore extends SaturnScreen {
|
||||
public CloakStore() {
|
||||
super("Hat Store");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
int p = 10;
|
||||
int gx = 10;
|
||||
int gy = 20;
|
||||
|
||||
Scroll scroll = new Scroll(p);
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
SaturnPlayer player = Auth.players.get(Auth.uuid);
|
||||
|
||||
if (player != null) {
|
||||
for (String cloak : Cloaks.ALL_CLOAKS) {
|
||||
if (!Cloaks.availableCloaks.contains(cloak)) {
|
||||
int x = (50 + gx) * col;
|
||||
int y = (111 + gy) * row;
|
||||
scroll.draw(new CosmeticPreview(cloak == player.cloak, Textures.getCloakPreview(cloak), () -> {
|
||||
Auth.buyCloak(cloak);
|
||||
SaturnClient.client.setScreen(new CloakStore());
|
||||
}).position(x, y));
|
||||
|
||||
String t = "100";
|
||||
|
||||
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Text.font.value), y + 113).scale(0.5f));
|
||||
|
||||
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16).position(x + Fonts.getWidth(t, Text.font.value) - 1, y + 112).scale(0.5f));
|
||||
|
||||
if (col == 8) {
|
||||
col = 0;
|
||||
row++;
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int scrollWidth = 480 + 40 + (gx * 2) + (p * 2);
|
||||
|
||||
draw(scroll.dimensions(scrollWidth, 350).centerOffset(width, height, 15, 0));
|
||||
|
||||
draw(new Sidebar(5, this::close).centerOffset(width, height, -((scrollWidth - 30) / 2 + 20), 0));
|
||||
|
||||
draw(new TabMenu(0,
|
||||
new TabMenuComponent(Textures.CLOAK, () -> {}),
|
||||
new TabMenuComponent(Textures.HAT, () -> {
|
||||
SaturnClient.client.setScreen(new HatStore());
|
||||
})
|
||||
).centerOffset(width, height, 0, -195));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.saturnclient.ui2.screens.store;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.components.CosmeticPreview;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.elements.ImageTexture;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.elements.TabMenu;
|
||||
import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent;
|
||||
import org.saturnclient.ui2.elements.Text;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
public class HatStore extends SaturnScreen {
|
||||
public HatStore() {
|
||||
super("Hat Store");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
int p = 10;
|
||||
int gx = 10;
|
||||
int gy = 20;
|
||||
|
||||
Scroll scroll = new Scroll(p);
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
SaturnPlayer player = Auth.players.get(Auth.uuid);
|
||||
|
||||
if (player != null) {
|
||||
for (String hat : Hats.ALL_HATS) {
|
||||
if (!Hats.availableHats.contains(hat)) {
|
||||
int x = (50 + gx) * col;
|
||||
int y = (50 + gy) * row;
|
||||
scroll.draw(new CosmeticPreview(hat == player.hat, Textures.getHatPreview(hat), () -> {
|
||||
Auth.buyHat(hat);
|
||||
SaturnClient.client.setScreen(new HatStore());
|
||||
}).dimensions(50, 50).position(x, y));
|
||||
|
||||
String t = "50";
|
||||
|
||||
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Text.font.value), y + 53).scale(0.5f));
|
||||
|
||||
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16).position(x + Fonts.getWidth(t, Text.font.value) + 4, y + 52).scale(0.5f));
|
||||
|
||||
if (col == 8) {
|
||||
col = 0;
|
||||
row++;
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int scrollWidth = 480 + 40 + (gx * 2) + (p * 2);
|
||||
|
||||
draw(scroll.dimensions(scrollWidth, 350).centerOffset(width, height, 15, 0));
|
||||
|
||||
draw(new Sidebar(5, this::close).centerOffset(width, height, -((scrollWidth - 30) / 2 + 20), 0));
|
||||
|
||||
draw(new TabMenu(1,
|
||||
new TabMenuComponent(Textures.CLOAK, () -> {
|
||||
SaturnClient.client.setScreen(new CloakStore());
|
||||
}),
|
||||
new TabMenuComponent(Textures.HAT, () -> {})
|
||||
).centerOffset(width, height, 0, -195));
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 368 KiB After Width: | Height: | Size: 419 KiB |
@@ -0,0 +1,305 @@
|
||||
{
|
||||
"version": 1,
|
||||
"valid": true,
|
||||
"name": "cry",
|
||||
"description": "T_T",
|
||||
"author": "dsty",
|
||||
"emote": {
|
||||
"beginTick": 0,
|
||||
"endTick": 60,
|
||||
"stopTick": 61,
|
||||
"isLoop": true,
|
||||
"returnTick": 5,
|
||||
"nsfw": false,
|
||||
"degrees": false,
|
||||
"moves": [
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"x": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"x": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"y": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"y": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.34134695
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.22808763
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 25,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.21269174
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 35,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.32248768
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 45,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.0874397
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 55,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.17582592
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.21476103
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -6.320644E-4
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 25,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": 0.029434478
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 35,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.039604172
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 45,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": 0.037607383
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 55,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": 0.050604735
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": -0.00930274
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 25,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.0010032838
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 35,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": -0.009209918
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 45,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": -0.012478679
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 55,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.031160546
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -1.8700758
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.4349194
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 0.4970688
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -0.9622451
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"x": 5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": -1.9203311
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"yaw": 0.6307226
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"roll": -0.2971223
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"bend": -0.8864816
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
{
|
||||
"version": 1,
|
||||
"valid": true,
|
||||
"name": "facepalm",
|
||||
"description": "just facepalm",
|
||||
"author": "dsty",
|
||||
"emote": {
|
||||
"beginTick": 0,
|
||||
"endTick": 60,
|
||||
"stopTick": 61,
|
||||
"isLoop": false,
|
||||
"returnTick": 2,
|
||||
"nsfw": false,
|
||||
"degrees": false,
|
||||
"moves": [
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"x": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"x": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"y": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"y": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.067995355
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.14453278
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 30,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.11871816
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 40,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.19018666
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.20064461
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": 0.060454715
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.086299464
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 30,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.087619215
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 40,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.083825104
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": 0.036273066
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.0041144555
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.12942825
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 30,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": -0.050149817
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 40,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.08701207
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.08676299
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -3.8523226
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -3.8523226
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -2.0664942
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -2.074402
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 30,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -2.074402
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 40,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -2.02932
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -2.02932
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.47555572
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.5093512
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 30,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.5093512
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 40,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.38563538
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.38563538
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 0.20147677
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 0.20521602
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 30,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 0.3274244
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 40,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 0.30787703
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 0.40478125
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -0.49199954
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -0.54730254
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 40,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -0.52019864
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 60,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -0.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,697 @@
|
||||
{
|
||||
"version": 1,
|
||||
"valid": true,
|
||||
"name": "front_flip",
|
||||
"description": "Parkour!!!!1",
|
||||
"author": "DKinchik",
|
||||
"emote": {
|
||||
"beginTick": 0,
|
||||
"endTick": 17,
|
||||
"stopTick": 18,
|
||||
"isLoop": false,
|
||||
"returnTick": 1,
|
||||
"nsfw": false,
|
||||
"degrees": false,
|
||||
"moves": [
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"x": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"x": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"y": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"y": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.7020477
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": 0.7020477
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"head": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"x": -1.9
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"x": -1.9
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"y": 11.169379
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 3,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"y": 12.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"y": 12.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"z": -0.39214998
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 3,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"z": 0.1
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"z": 0.1
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 3,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"pitch": -1.9707682
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"pitch": -1.9707682
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"roll": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"roll": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"bend": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -1.3665518
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -1.3665518
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"x": 5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"x": 5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": -1.0793308
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": -1.0793308
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"bend": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"x": 1.9
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"x": 1.9
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"y": 10.861001
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 3,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"y": 12.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"y": 12.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"z": -0.5082285
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 3,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"z": -0.1
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"z": -0.1
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 3,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 5,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"pitch": -1.9850811
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"pitch": -1.9850811
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"roll": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"bend": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"x": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 16,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"x": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"y": -0.061333913
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 7,
|
||||
"easing": "OUTQUAD",
|
||||
"body": {
|
||||
"y": 0.48852682
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "CONSTANT",
|
||||
"body": {
|
||||
"y": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 16,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"y": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 16,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 7,
|
||||
"easing": "OUTQUAD",
|
||||
"body": {
|
||||
"pitch": -2.8362873
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 15,
|
||||
"easing": "CONSTANT",
|
||||
"body": {
|
||||
"pitch": -6.2831855
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 16,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"yaw": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 16,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"yaw": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"roll": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 16,
|
||||
"easing": "INQUAD",
|
||||
"body": {
|
||||
"roll": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 2,
|
||||
"easing": "INOUTQUAD",
|
||||
"body": {
|
||||
"bend": -0.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
{
|
||||
"version": 1,
|
||||
"valid": true,
|
||||
"name": "tpose",
|
||||
"description": "MENACING",
|
||||
"author": "stephanieisdumb",
|
||||
"emote": {
|
||||
"beginTick": 0,
|
||||
"endTick": 80,
|
||||
"stopTick": 81,
|
||||
"isLoop": true,
|
||||
"returnTick": 20,
|
||||
"nsfw": false,
|
||||
"degrees": false,
|
||||
"moves": [
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -6.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"x": -6.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 3.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"y": 3.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -1.0704756
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": 0.059108086
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"pitch": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.61077195
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.008776078
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 0.6060502
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 1.5707964
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 1.5765934
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"roll": 1.5707964
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -1.3806202
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightArm": {
|
||||
"bend": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"x": 5.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"x": 6.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"x": 6.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"y": 2.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"y": 3.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"y": 3.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"z": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": -1.0045553
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": 0.010133168
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"yaw": 0.44322997
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"yaw": 0.038214765
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"yaw": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"roll": -0.5571526
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"roll": -1.5707964
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 50,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"roll": -1.5692185
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"roll": -1.5707964
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 10,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"bend": -1.3810014
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 20,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftArm": {
|
||||
"bend": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"leftLeg": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"tick": 80,
|
||||
"easing": "INOUTQUAD",
|
||||
"rightLeg": {
|
||||
"pitch": 0.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 135 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 374 B |
|
After Width: | Height: | Size: 357 B |
|
After Width: | Height: | Size: 884 B |
|
After Width: | Height: | Size: 958 B |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 129 B |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 3.1 KiB |