Emote wheel and cosmetics animations

This commit is contained in:
2026-02-25 02:07:30 +01:00
parent 0995484c09
commit cfe0d4a97f
5 changed files with 193 additions and 71 deletions
@@ -18,8 +18,11 @@ public class AnimationConfig {
// Shift menu
public static final AnimationConfig shiftMenu = new AnimationConfig(true, 300, 120);
// Cosmetics menu
public static final AnimationConfig cosmeticsMenu = new AnimationConfig(true, 700, 40);
// Emote wheel
public static final AnimationConfig emoteWheel = new AnimationConfig(true, 500, 80);
public static final AnimationConfig emoteWheel = new AnimationConfig(true, 700, 80);
public static void init(ConfigManager parent) {
config = new ConfigManager(parent, "Animations");
@@ -28,6 +31,7 @@ public class AnimationConfig {
mainMenu.init("Main Menu");
modMenu.init("Mod Menu");
shiftMenu.init("Shift Menu");
cosmeticsMenu.init("Cosmetics Menu");
emoteWheel.init("Emote Wheel");
}
@@ -2,12 +2,16 @@ package org.saturnclient.ui2.screens.cosmetics;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
import org.saturnclient.ui2.resources.Textures;
import org.saturnclient.ui2.SaturnScreen;
import org.saturnclient.ui2.anim.Fade;
import org.saturnclient.ui2.anim.SlideY;
import org.saturnclient.ui2.components.CosmeticPreview;
import org.saturnclient.ui2.components.Sidebar;
import org.saturnclient.ui2.components.SkinPreview;
import org.saturnclient.ui2.elements.AnimationStagger;
import org.saturnclient.ui2.elements.Scroll;
import org.saturnclient.ui2.elements.TabMenu;
import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent;
@@ -29,11 +33,18 @@ public class CloakMenu extends SaturnScreen {
SaturnPlayer player = SaturnPlayer.get();
AnimationStagger stagger = new AnimationStagger(AnimationConfig.cosmeticsMenu);
if (player != null) {
for (String cloak : Cloaks.availableCloaks) {
scroll.draw(new CosmeticPreview(cloak == player.cloak, Textures.getCloakPreview(cloak), () -> {
Cloaks.setCloak(cloak);
}).position((50 + g) * col, (111 + g) * row));
stagger.draw(
new CosmeticPreview(
cloak == player.cloak,
Textures.getCloakPreview(cloak),
() -> Cloaks.setCloak(cloak))
.position((50 + g) * col, (111 + g) * row)
.animation(new SlideY(AnimationConfig.cosmeticsMenu, 14)));
if (col == 5) {
col = 0;
@@ -44,19 +55,29 @@ public class CloakMenu extends SaturnScreen {
}
}
scroll.draw(stagger);
int scrollWidth = 480 + 10 + (g * 2) + (p * 2);
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
draw(scroll
.dimensions(scrollWidth, 350)
.center(width, height));
draw(new SkinPreview(-30.0f, false).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y + 40));
draw(new SkinPreview(-30.0f, false)
.scale(3.5f)
.position(scroll.x + (scrollWidth - 220), scroll.y + 40)
.animation(new Fade(500)));
draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
draw(new Sidebar(2, this::close)
.centerOffset(width, height, -(scrollWidth / 2 + 20), 0)
.animation(new Fade(400)));
draw(new TabMenu(0,
new TabMenuComponent(Textures.CLOAK, () -> {
}),
new TabMenuComponent(Textures.HAT, () -> {
SaturnClient.client.setScreen(new HatMenu());
})).centerOffset(width, height, 0, -195));
}))
.centerOffset(width, height, 0, -195));
}
}
@@ -2,12 +2,16 @@ package org.saturnclient.ui2.screens.cosmetics;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.cosmetics.Hats;
import org.saturnclient.ui2.resources.Textures;
import org.saturnclient.ui2.SaturnScreen;
import org.saturnclient.ui2.anim.Fade;
import org.saturnclient.ui2.anim.SlideY;
import org.saturnclient.ui2.components.CosmeticPreview;
import org.saturnclient.ui2.components.Sidebar;
import org.saturnclient.ui2.components.SkinPreview;
import org.saturnclient.ui2.elements.AnimationStagger;
import org.saturnclient.ui2.elements.Scroll;
import org.saturnclient.ui2.elements.TabMenu;
import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent;
@@ -29,11 +33,19 @@ public class HatMenu extends SaturnScreen {
SaturnPlayer player = SaturnPlayer.get();
AnimationStagger stagger = new AnimationStagger(AnimationConfig.cosmeticsMenu);
if (player != null) {
for (String hat : Hats.availableHats) {
scroll.draw(new CosmeticPreview(hat == player.hat, Textures.getHatPreview(hat), () -> {
Hats.setHat(hat);
}).dimensions(50, 50).position((50 + g) * col, (50 + g) * row));
stagger.draw(
new CosmeticPreview(
hat == player.hat,
Textures.getHatPreview(hat),
() -> Hats.setHat(hat))
.dimensions(50, 50)
.position((50 + g) * col, (50 + g) * row)
.animation(new SlideY(AnimationConfig.cosmeticsMenu, 14)));
if (col == 5) {
col = 0;
@@ -44,19 +56,29 @@ public class HatMenu extends SaturnScreen {
}
}
scroll.draw(stagger);
int scrollWidth = 480 + 10 + (g * 2) + (p * 2);
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
draw(scroll
.dimensions(scrollWidth, 350)
.center(width, height));
draw(new SkinPreview(170f, true).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y + 40));
draw(new SkinPreview(170f, true)
.scale(3.5f)
.position(scroll.x + (scrollWidth - 220), scroll.y + 40)
.animation(new Fade(500)));
draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
draw(new Sidebar(2, this::close)
.centerOffset(width, height, -(scrollWidth / 2 + 20), 0)
.animation(new Fade(400)));
draw(new TabMenu(1,
new TabMenuComponent(Textures.CLOAK, () -> {
SaturnClient.client.setScreen(new CloakMenu());
}),
new TabMenuComponent(Textures.HAT, () -> {
})).centerOffset(width, height, 0, -195));
}))
.centerOffset(width, height, 0, -195));
}
}
@@ -3,12 +3,16 @@ package org.saturnclient.ui2.screens.store;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.ServiceClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.config.Theme;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
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.components.CosmeticPreview;
import org.saturnclient.ui2.components.Sidebar;
import org.saturnclient.ui2.elements.AnimationStagger;
import org.saturnclient.ui2.elements.ImageTexture;
import org.saturnclient.ui2.elements.Notification.NotificationKind;
import org.saturnclient.ui2.elements.Scroll;
@@ -45,41 +49,37 @@ public class CloakStore extends SaturnScreen {
SaturnPlayer player = SaturnPlayer.get();
AnimationStagger stagger = new AnimationStagger(AnimationConfig.cosmeticsMenu);
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), () -> {
long now = System.currentTimeMillis();
if (now - lastPurchaseTime >= 3000) {
Utils.notify(NotificationKind.Info, "Purchase processing", "Please wait");
ServiceClient.buyCloak(cloak);
lastPurchaseTime = now;
new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
RenderSystem.recordRenderCall(() -> {
SaturnClient.client.setScreen(new CloakStore(now));
Utils.notify(NotificationKind.Success, "Purchase complete",
"Congrats, enjoy your new cloak!");
});
}).start();
} else {
Utils.notify(NotificationKind.Error, "Timeout error", "Please wait 3 seconds");
}
}).position(x, y));
stagger.draw(
new CosmeticPreview(
cloak == player.cloak,
Textures.getCloakPreview(cloak),
() -> handlePurchase(cloak))
.position(x, y)
.animation(new SlideY(AnimationConfig.cosmeticsMenu, 16)));
String t = "100";
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Theme.FONT.value), y + 113).scale(0.5f));
stagger.draw(
new Text(t)
.position(x + Fonts.centerX(50, t, Theme.FONT.value), y + 113)
.scale(0.5f)
.animation(new Fade(400)));
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16)
.position(x + Fonts.getWidth(t, Theme.FONT.value) - 1, y + 112).scale(0.5f));
stagger.draw(
new ImageTexture(Textures.COINS)
.dimensions(16, 16)
.position(x + Fonts.getWidth(t, Theme.FONT.value) - 1, y + 112)
.scale(0.5f)
.animation(new Fade(400)));
if (col == 8) {
col = 0;
@@ -91,17 +91,54 @@ public class CloakStore extends SaturnScreen {
}
}
scroll.draw(stagger);
int scrollWidth = 480 + 40 + (gx * 2) + (p * 2);
draw(scroll.dimensions(scrollWidth, 350).centerOffset(width, height, 15, 0));
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 Sidebar(5, this::close)
.centerOffset(width, height, -((scrollWidth - 30) / 2 + 20), 0)
.animation(new Fade(400)));
draw(new TabMenu(0,
new TabMenuComponent(Textures.CLOAK, () -> {
}),
new TabMenuComponent(Textures.HAT, () -> {
SaturnClient.client.setScreen(new HatStore());
})).centerOffset(width, height, 0, -195));
}))
.centerOffset(width, height, 0, -195));
}
private void handlePurchase(String cloak) {
long now = System.currentTimeMillis();
if (now - lastPurchaseTime >= 3000) {
Utils.notify(NotificationKind.Info, "Purchase processing", "Please wait");
ServiceClient.buyCloak(cloak);
lastPurchaseTime = now;
new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException ignored) {
}
RenderSystem.recordRenderCall(() -> {
SaturnClient.client.setScreen(new CloakStore(now));
Utils.notify(NotificationKind.Success,
"Purchase complete",
"Congrats, enjoy your new cloak!");
});
}).start();
} else {
Utils.notify(NotificationKind.Error,
"Timeout error",
"Please wait 3 seconds");
}
}
}
@@ -3,12 +3,16 @@ package org.saturnclient.ui2.screens.store;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.ServiceClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.config.Theme;
import org.saturnclient.saturnclient.cosmetics.Hats;
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.components.CosmeticPreview;
import org.saturnclient.ui2.components.Sidebar;
import org.saturnclient.ui2.elements.AnimationStagger;
import org.saturnclient.ui2.elements.ImageTexture;
import org.saturnclient.ui2.elements.Notification.NotificationKind;
import org.saturnclient.ui2.elements.Scroll;
@@ -45,41 +49,38 @@ public class HatStore extends SaturnScreen {
SaturnPlayer player = SaturnPlayer.get();
AnimationStagger stagger = new AnimationStagger(AnimationConfig.cosmeticsMenu);
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), () -> {
long now = System.currentTimeMillis();
if (now - lastPurchaseTime >= 3000) {
Utils.notify(NotificationKind.Info, "Purchase processing", "Please wait");
ServiceClient.buyHat(hat);
lastPurchaseTime = now;
new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
RenderSystem.recordRenderCall(() -> {
SaturnClient.client.setScreen(new HatStore(now));
Utils.notify(NotificationKind.Success, "Purchase complete",
"Congrats, enjoy your new hat!");
});
}).start();
} else {
Utils.notify(NotificationKind.Error, "Timeout error", "Please wait 3 seconds");
}
}).dimensions(50, 50).position(x, y));
stagger.draw(
new CosmeticPreview(
hat == player.hat,
Textures.getHatPreview(hat),
() -> handlePurchase(hat))
.dimensions(50, 50)
.position(x, y)
.animation(new SlideY(AnimationConfig.cosmeticsMenu, 16)));
String t = "50";
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Theme.FONT.value), y + 53).scale(0.5f));
stagger.draw(
new Text(t)
.position(x + Fonts.centerX(50, t, Theme.FONT.value), y + 53)
.scale(0.5f)
.animation(new Fade(400)));
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16)
.position(x + Fonts.getWidth(t, Theme.FONT.value) + 4, y + 52).scale(0.5f));
stagger.draw(
new ImageTexture(Textures.COINS)
.dimensions(16, 16)
.position(x + Fonts.getWidth(t, Theme.FONT.value) + 4, y + 52)
.scale(0.5f)
.animation(new Fade(400)));
if (col == 8) {
col = 0;
@@ -91,17 +92,54 @@ public class HatStore extends SaturnScreen {
}
}
scroll.draw(stagger);
int scrollWidth = 480 + 40 + (gx * 2) + (p * 2);
draw(scroll.dimensions(scrollWidth, 350).centerOffset(width, height, 15, 0));
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 Sidebar(5, this::close)
.centerOffset(width, height, -((scrollWidth - 30) / 2 + 20), 0)
.animation(new Fade(400)));
draw(new TabMenu(1,
new TabMenuComponent(Textures.CLOAK, () -> {
SaturnClient.client.setScreen(new CloakStore());
}),
new TabMenuComponent(Textures.HAT, () -> {
})).centerOffset(width, height, 0, -195));
}))
.centerOffset(width, height, 0, -195));
}
private void handlePurchase(String hat) {
long now = System.currentTimeMillis();
if (now - lastPurchaseTime >= 3000) {
Utils.notify(NotificationKind.Info, "Purchase processing", "Please wait");
ServiceClient.buyHat(hat);
lastPurchaseTime = now;
new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException ignored) {
}
RenderSystem.recordRenderCall(() -> {
SaturnClient.client.setScreen(new HatStore(now));
Utils.notify(NotificationKind.Success,
"Purchase complete",
"Congrats, enjoy your new hat!");
});
}).start();
} else {
Utils.notify(NotificationKind.Error,
"Timeout error",
"Please wait 3 seconds");
}
}
}