diff --git a/README.MD b/README.MD index dc99514..5e4de44 100644 --- a/README.MD +++ b/README.MD @@ -13,5 +13,6 @@ - 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 diff --git a/build.gradle b/build.gradle index 247ab45..9f5c6bd 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ processResources { } } -def targetJavaVersion = 17 +def targetJavaVersion = 21 tasks.withType(JavaCompile).configureEach { it.options.encoding = "UTF-8" if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { diff --git a/gradle.properties b/gradle.properties index f37aaf1..11ee09e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.16.10 # Mod Properties - mod_version = 0.0.1-alpha0 + mod_version = 0.0.1-alpha4 maven_group = me.iipho3nix archives_base_name = saturnclient diff --git a/src/main/java/org/saturnclient/saturnmods/HudMod.java b/src/main/java/org/saturnclient/modules/HudMod.java similarity index 85% rename from src/main/java/org/saturnclient/saturnmods/HudMod.java rename to src/main/java/org/saturnclient/modules/HudMod.java index 93c4237..881e02d 100644 --- a/src/main/java/org/saturnclient/saturnmods/HudMod.java +++ b/src/main/java/org/saturnclient/modules/HudMod.java @@ -1,4 +1,4 @@ -package org.saturnclient.saturnmods; +package org.saturnclient.modules; import net.minecraft.client.gui.DrawContext; diff --git a/src/main/java/org/saturnclient/saturnmods/ModDimensions.java b/src/main/java/org/saturnclient/modules/ModDimensions.java similarity index 98% rename from src/main/java/org/saturnclient/saturnmods/ModDimensions.java rename to src/main/java/org/saturnclient/modules/ModDimensions.java index 698e200..deafd46 100644 --- a/src/main/java/org/saturnclient/saturnmods/ModDimensions.java +++ b/src/main/java/org/saturnclient/modules/ModDimensions.java @@ -1,4 +1,4 @@ -package org.saturnclient.saturnmods; +package org.saturnclient.modules; import org.saturnclient.saturnclient.config.ConfigManager; import org.saturnclient.saturnclient.config.Property; diff --git a/src/main/java/org/saturnclient/modules/ModManager.java b/src/main/java/org/saturnclient/modules/ModManager.java new file mode 100644 index 0000000..2eba97f --- /dev/null +++ b/src/main/java/org/saturnclient/modules/ModManager.java @@ -0,0 +1,58 @@ +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 net.minecraft.client.util.math.MatrixStack; + +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(), + }; + + public static void init() { + ClientTickEvents.END_CLIENT_TICK.register(client -> { + for (Module m : MODS) { + if (m.isEnabled()) { + m.tick(); + } + } + }); + + HudRenderCallback.EVENT.register((context, _o) -> { + TextRenderer textRenderer = SaturnClient.client.textRenderer; + + if (textRenderer != null && + !(SaturnClient.client.currentScreen instanceof HudEditor)) { + RenderScope renderScope = new RenderScope(context.getMatrices(), + ((DrawContextAccessor) context).getVertexConsumers()); + + for (Module m : MODS) { + if (m instanceof HudMod && m.isEnabled()) { + ModDimensions dim = ((HudMod) m).getDimensions(); + + MatrixStack matrices = context.getMatrices(); + matrices.push(); + + matrices.translate(dim.x.value, (float) dim.y.value, 0); + + matrices.scale(dim.scale.value, dim.scale.value, 1.0f); + + ((HudMod) m).render(context); + + matrices.pop(); + } else { + m.render(renderScope); + } + } + } + }); + } +} diff --git a/src/main/java/org/saturnclient/modules/Module.java b/src/main/java/org/saturnclient/modules/Module.java new file mode 100644 index 0000000..95dcb03 --- /dev/null +++ b/src/main/java/org/saturnclient/modules/Module.java @@ -0,0 +1,60 @@ +package org.saturnclient.modules; + +import org.saturnclient.saturnclient.config.ConfigManager; +import org.saturnclient.saturnclient.config.NamedProperty; +import org.saturnclient.ui2.resources.Textures; +import org.saturnclient.ui2.RenderScope; + +import net.minecraft.util.Identifier; + +public abstract class Module { + private final String name; + private final String namespace; + private final String description; + private final ConfigManager configManager; + public final String[] tags; + + public Module(ModuleDetails details, NamedProperty... props) { + this.name = details.name; + this.namespace = details.namespace; + this.description = details.description; + this.tags = details.tags; + + configManager = new ConfigManager(name); + + for (NamedProperty prop : props) { + configManager.property(prop.name, prop.prop); + } + } + + public void render(RenderScope scope) {} + public void tick() {} + + public abstract boolean isEnabled(); + + public abstract void setEnabled(boolean e); + + public final String getName() { + return name; + } + + public Identifier getIconTexture() { + return Textures.getModIcon(namespace); + } + + public ConfigManager getConfig() { + return configManager; + } + + public String getDescription() { + return description; + } + + public String[] getTags() { + return tags; + } + + public String getVersion() { + return "v0.0.1"; + } +} diff --git a/src/main/java/org/saturnclient/modules/ModuleDetails.java b/src/main/java/org/saturnclient/modules/ModuleDetails.java new file mode 100644 index 0000000..3cce480 --- /dev/null +++ b/src/main/java/org/saturnclient/modules/ModuleDetails.java @@ -0,0 +1,39 @@ +package org.saturnclient.modules; + +public class ModuleDetails { + public String name; + public String namespace; + public String description; + public String version; + public String[] tags = {}; + + public ModuleDetails(String name, String namespace) { + this.name = name; + this.namespace = namespace; + } + + public ModuleDetails name(String name) { + this.name = name; + return this; + } + + public ModuleDetails namespace(String namespace) { + this.namespace = namespace; + return this; + } + + public ModuleDetails description(String description) { + this.description = description; + return this; + } + + public ModuleDetails version(String version) { + this.version = version; + return this; + } + + public ModuleDetails tags(String... tags) { + this.tags = tags; + return this; + } +} diff --git a/src/main/java/org/saturnclient/modules/mods/AutoSprint.java b/src/main/java/org/saturnclient/modules/mods/AutoSprint.java new file mode 100644 index 0000000..294fb35 --- /dev/null +++ b/src/main/java/org/saturnclient/modules/mods/AutoSprint.java @@ -0,0 +1,37 @@ +package org.saturnclient.modules.mods; + +import java.util.Objects; + +import org.saturnclient.modules.Module; +import org.saturnclient.modules.ModuleDetails; +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.config.Property; + +public class AutoSprint extends Module { + private static Property enabled = new Property<>(true); + + public AutoSprint() { + super(new ModuleDetails("Auto Sprint", "sprint").description("Makes the player always sprint").tags("Movement"), enabled.named("Enabled")); + } + + @Override + public void tick() { + if (SaturnClient.client.player == null || SaturnClient.client.getNetworkHandler() == null) { + return; + } + if (SaturnClient.client.options.forwardKey.isPressed() && !SaturnClient.client.options.backKey.isPressed() && !SaturnClient.client.player.isSneaking() && + !SaturnClient.client.player.horizontalCollision) { + Objects.requireNonNull(SaturnClient.client.player).setSprinting(true); + } + } + + @Override + public boolean isEnabled() { + return enabled.value; + } + + @Override + public void setEnabled(boolean e) { + enabled.value = e; + } +} diff --git a/src/main/java/org/saturnclient/modules/mods/Crosshair.java b/src/main/java/org/saturnclient/modules/mods/Crosshair.java new file mode 100644 index 0000000..9dca470 --- /dev/null +++ b/src/main/java/org/saturnclient/modules/mods/Crosshair.java @@ -0,0 +1,45 @@ +package org.saturnclient.modules.mods; + +import org.saturnclient.modules.Module; +import org.saturnclient.modules.ModuleDetails; +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.resources.Textures; + +import net.minecraft.client.render.RenderLayer; + +public class Crosshair extends Module { + public static Property enabled = new Property<>(false); + public static Property range_indicator = new Property<>(false); + + public Crosshair() { + super(new ModuleDetails("Crosshair", "crosshair").description("Changes the crosshair if you're aiming at a entity").tags("Visuals", "Utility"), enabled.named("Enabled"), range_indicator.named("Range Indicator")); + } + + @Override + public void render(RenderScope scope) { + if (enabled.value + && range_indicator.value + && SaturnClient.client.targetedEntity != null + && SaturnClient.client.targetedEntity.isAlive()) { + int scaledWidth = 15; + int scaledHeight = 15; + + scope.setRenderLayer(RenderLayer::getCrosshair); + scope.drawTexture(Textures.CROSSHAIR_RANGE, + (scope.getScaledWindowWidth() - scaledWidth) / 2, + (scope.getScaledWindowHeight() - scaledHeight) / 2, 0.0F, 0.0F, scaledWidth, scaledHeight); + } + } + + @Override + public boolean isEnabled() { + return enabled.value; + } + + @Override + public void setEnabled(boolean e) { + enabled.value = e; + } +} diff --git a/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/src/main/java/org/saturnclient/saturnclient/SaturnClient.java index 273ff05..1a6c933 100644 --- a/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ b/src/main/java/org/saturnclient/saturnclient/SaturnClient.java @@ -2,17 +2,14 @@ package org.saturnclient.saturnclient; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; -import net.minecraft.client.gui.screen.TitleScreen; +import net.minecraft.client.MinecraftClient; +import org.saturnclient.modules.ModManager; import org.saturnclient.saturnclient.auth.Auth; import org.saturnclient.saturnclient.config.ConfigManager; import org.saturnclient.saturnclient.cosmetics.Hats; import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.saturnclient.menus.SaturnMenu; -import org.saturnclient.saturnclient.menus.SaturnTitleScreen; -import org.saturnclient.saturnmods.ModManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,25 +22,21 @@ public class SaturnClient implements ModInitializer { public static final String MOD_ID = "saturnclient"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + public static MinecraftClient client; @Override public void onInitialize() { LOGGER.info("Initializing " + MOD_ID); + client = MinecraftClient.getInstance(); + SaturnClientConfig.init(); ModManager.init(); - ConfigManager.load(); - + ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> { - if (SaturnClientConfig.saturnTitleScreen.value && screen instanceof TitleScreen - && !(screen instanceof SaturnMenu)) { - client.setScreen(new SaturnTitleScreen()); - } - }); - + SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> { return (resourceManager, location) -> MOD_ID.equals(location.getNamespace()); }); - + KeyInputHandler.register(); if (Auth.authenticate()) { Cloaks.initialize(); diff --git a/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java b/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java index 378ce93..5d112ec 100644 --- a/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java +++ b/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java @@ -2,52 +2,19 @@ package org.saturnclient.saturnclient; import org.saturnclient.saturnclient.config.Property; import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.ui.SaturnAnimation; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.animations.FadeIn; +import org.saturnclient.ui2.resources.Textures; -import net.minecraft.client.font.TextRenderer; +import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; -import net.minecraft.util.math.ColorHelper; public class SaturnClientConfig { - public static ConfigManager config = new ConfigManager("Saturn Client"); + public static ConfigManager config; - public static Property color = config.property( - "Primary color", - new Property<>( - ColorHelper.getArgb(255, 251, 60, 79), - Property.PropertyType.HEX)); + public static Property realisticLogo = + new Property<>(false); - public static Property normal = config.property( - "Default color", - new Property<>( - ColorHelper.getArgb(255, 182, 182, 182), - Property.PropertyType.HEX)); - - public static Property realisticLogo = config.property( - "Realistic logo", - new Property<>(false)); - - public static Property saturnTitleScreen = config.property( - "Saturn client title screen", - new Property<>(true)); - - public static int WHITE = ColorHelper.getArgb(255, 255, 255, 255); - public static TextRenderer textRenderer = null; - - public static int getWhite(float alpha) { - return ((int) (alpha * 255) << 24) | (normal.value & 0x00FFFFFF); - } - - public static int getColor(boolean hovering, float alpha) { - return SaturnUi.getAlpha(hovering ? color.value : normal.value, alpha); - } - - public static SaturnAnimation[] getAnimations() { - return new SaturnAnimation[] { new FadeIn(1) }; - } + public static Property saturnTitleScreen = + new Property<>(true); public static Identifier getLogo() { return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO; @@ -56,4 +23,27 @@ public class SaturnClientConfig { public static String getSaturnIndicator() { return realisticLogo.value ? "" : ""; } + + /* + * Gets the icon color of a specific individual, here are the different colors + * + * - Owner: Dark Red + * - Admin: Red + * - Partners: Gold + * - Contributor: Aqua + * - Other/player: White + */ + public static Formatting getIconColor(String uuid) { + if (uuid.equals("d362a04228bd49e1a807ae74dbe8aba9")) { + return Formatting.DARK_RED; // Owner + } + + return Formatting.WHITE; + } + + public static void init() { + config = new ConfigManager("Saturn Client"); + config.property("Realistic logo", realisticLogo); + config.property("Saturn client title screen", saturnTitleScreen); + } } diff --git a/src/main/java/org/saturnclient/saturnclient/auth/Auth.java b/src/main/java/org/saturnclient/saturnclient/auth/Auth.java index 753bd15..a918274 100644 --- a/src/main/java/org/saturnclient/saturnclient/auth/Auth.java +++ b/src/main/java/org/saturnclient/saturnclient/auth/Auth.java @@ -3,7 +3,6 @@ package org.saturnclient.saturnclient.auth; import java.util.HashMap; import java.util.Map; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; import org.saturnclient.saturnclient.cosmetics.Hats; import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; import org.saturnclient.saturnclient.SaturnClient; @@ -22,13 +21,12 @@ public class Auth { ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> close()); try { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.getSession() == null) { + if (SaturnClient.client.getSession() == null) { SaturnClient.LOGGER.error("No active Minecraft session found"); return false; } - String accessToken = client.getSession().getAccessToken(); + String accessToken = SaturnClient.client.getSession().getAccessToken(); SaturnClient.LOGGER.info("Authenticating"); Network.init(); @@ -55,7 +53,7 @@ public class Auth { Cloaks.loadCloak(uuid); - playerNames.put(client.getSession().getUsername(), uuid); + playerNames.put(SaturnClient.client.getSession().getUsername(), uuid); afterAuth(); @@ -119,16 +117,21 @@ public class Auth { private static void startPingThread() { pingThread = new Thread(() -> { try { - while (running) { - Thread.sleep(25000); // 25 seconds - if (running) { - Network.write("ping"); + while (running && !Thread.currentThread().isInterrupted()) { + try { + Thread.sleep(25000); // 25 seconds + if (running) { + Network.write("ping"); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // Restore interrupt status + break; // Exit the loop on interruption } } - } catch (InterruptedException e) { - SaturnClient.LOGGER.warn("Ping thread interrupted", e); } catch (Exception e) { - SaturnClient.LOGGER.error("Error in ping thread", e); + if (!(e instanceof InterruptedException)) { + SaturnClient.LOGGER.error("Error in ping thread", e); + } } }); @@ -184,7 +187,7 @@ public class Auth { public static void sendReload() { for (Map.Entry player : playerNames.entrySet()) { if (players.containsKey(player.getValue()) && !player.getValue().equals(uuid)) { - MinecraftClient.getInstance().player.networkHandler + 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"); ; diff --git a/src/main/java/org/saturnclient/saturnclient/auth/PlayerTracker.java b/src/main/java/org/saturnclient/saturnclient/auth/PlayerTracker.java index 043425a..a6aff97 100644 --- a/src/main/java/org/saturnclient/saturnclient/auth/PlayerTracker.java +++ b/src/main/java/org/saturnclient/saturnclient/auth/PlayerTracker.java @@ -2,8 +2,9 @@ package org.saturnclient.saturnclient.auth; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; +import org.saturnclient.saturnclient.SaturnClient; import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.client.MinecraftClient; import java.util.HashSet; import java.util.Set; @@ -19,7 +20,7 @@ public class PlayerTracker { ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> { trackedPlayers.clear(); client.execute(() -> { - checkForNewPlayers(MinecraftClient.getInstance()); + checkForNewPlayers(SaturnClient.client); }); }); diff --git a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java index 1894f02..3bcf10c 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java +++ b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java @@ -12,21 +12,22 @@ import java.nio.file.Files; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import net.minecraft.client.MinecraftClient; import org.saturnclient.saturnclient.SaturnClient; public class ConfigManager { - private static File configFile = new File( - MinecraftClient.getInstance().runDirectory, + SaturnClient.client.runDirectory, "saturn.json"); private static Map>> properties = new HashMap<>(); + private static JsonObject cachedThemeJson = null; private Map> currentMap; + private String namespace; public ConfigManager(String namespace) { currentMap = new LinkedHashMap<>(); properties.put(namespace, currentMap); + System.out.println("Created namespace: " + namespace); } public ConfigManager(ConfigManager config, String namespace) { @@ -36,14 +37,51 @@ public class ConfigManager { config.property(namespace, namespaceProperty); // Update the parent's state config.currentMap.put(namespace, namespaceProperty); + System.out.println("Created sub-namespace: " + namespace); } // Generic method to store any type of property public Property property(String name, Property value) { + System.out.println("Adding property: " + name); currentMap.put(name, value); + loadProp(name, value); return value; } + @SuppressWarnings("unchecked") + public void loadProp(String name, Property prop) { + if (cachedThemeJson != null) { + JsonElement element = cachedThemeJson.get(namespace); + if (element != null && element.isJsonObject()) { + JsonObject theme = element.getAsJsonObject(); + JsonElement value = theme.get(name); + if (value != null && prop.matchesJson(value)) { + switch (prop.getType()) { + case BOOLEAN: + ((Property) prop).setValue(value.getAsBoolean()); + break; + case INTEGER: + ((Property) prop).setValue(value.getAsInt()); + break; + case FLOAT: + ((Property) prop).setValue(value.getAsFloat()); + break; + case STRING: + ((Property) prop).setValue(value.getAsString()); + break; + case HEX: + ((Property) prop).setValue(value.getAsInt()); + break; + default: + break; + } + } + } + } else { + load(); + } + } + public static void load() { try { SaturnClient.LOGGER.info("Starting to load config..."); @@ -56,6 +94,7 @@ 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) @@ -77,6 +116,8 @@ public class ConfigManager { @SuppressWarnings("unchecked") private static void loadProperties(JsonObject config, Map> propertyMap) { + SaturnClient.LOGGER.info("Loading properties: " + propertyMap); + for (String propertyName : propertyMap.keySet()) { JsonElement c = config.get(propertyName); diff --git a/src/main/java/org/saturnclient/saturnclient/config/NamedProperty.java b/src/main/java/org/saturnclient/saturnclient/config/NamedProperty.java new file mode 100644 index 0000000..3e63c31 --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/config/NamedProperty.java @@ -0,0 +1,11 @@ +package org.saturnclient.saturnclient.config; + +public class NamedProperty { + public String name; + public Property prop; + + public NamedProperty(String name, Property value) { + this.name = name; + this.prop = value; + } +} diff --git a/src/main/java/org/saturnclient/saturnclient/config/Property.java b/src/main/java/org/saturnclient/saturnclient/config/Property.java index e4a82fe..5fa0e26 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/Property.java +++ b/src/main/java/org/saturnclient/saturnclient/config/Property.java @@ -139,4 +139,19 @@ public class Property { public static boolean valueIsNamespace(Object obj) { return obj instanceof Map; } + + @SuppressWarnings("unchecked") + public void setValue(Object value) { + this.value = (T) value; + } + + @SuppressWarnings("unchecked") + public void setValue(Object value, Object defaultValue) { + this.value = (T) value; + this.defaultValue = (T) defaultValue; + } + + public NamedProperty named(String name) { + return new NamedProperty<>(name, this); + } } diff --git a/src/main/java/org/saturnclient/saturnclient/config/ThemeManager.java b/src/main/java/org/saturnclient/saturnclient/config/ThemeManager.java new file mode 100644 index 0000000..4e68e63 --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/config/ThemeManager.java @@ -0,0 +1,218 @@ +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.LinkedHashMap; +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>> properties = new HashMap<>(); + private static JsonObject cachedThemeJson = null; + + // private Map>> states; + private Map> 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<>()); + + for (String s : states) { + properties.put(namespace+"@"+s, new LinkedHashMap<>()); + } + } + + public void setState(String state) { + this.state = state; + if (this.state != null) { + for (Map.Entry> tProp : properties.get(namespace+"@"+state).entrySet()) { + currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value); + } + } else { + for (Map.Entry> tProp : properties.get(namespace).entrySet()) { + currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value); + } + } + } + + public void applyState(String state) { + if (this.state != null) { + for (Map.Entry> 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); + } + } + + // Generic method to store any type of property + public Property property(String name, Property prop) { + for (String state : states) { + Property property = new Property(prop.value); + properties.get(namespace+"@"+state).put(name, property); + loadProp(state, name, property); + } + + loadProp(null, name, prop); + properties.get(namespace).put(name, new Property(prop.value)); + currentStyling.put(name, prop); + + return prop; + } + + public 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 void loadProp(String state, String name, Property prop) { + 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) prop).setValue(value.getAsBoolean()); + break; + case INTEGER: + ((Property) prop).setValue(value.getAsInt()); + break; + case FLOAT: + ((Property) prop).setValue(value.getAsFloat()); + break; + case STRING: + ((Property) prop).setValue(value.getAsString()); + break; + case HEX: + ((Property) prop).setValue(value.getAsInt()); + break; + default: + break; + } + } + } + } + + public static void load() { + try { + SaturnClient.LOGGER.info("Starting to load theme..."); + if (!themeFile.exists()) { + themeFile.createNewFile(); + Files.write(themeFile.toPath(), "{}".getBytes()); + } + + cachedThemeJson = JsonParser.parseString( + new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject(); + + SaturnClient.LOGGER.info("Theme loaded"); + } catch (IOException e) { + SaturnClient.LOGGER.error("Error reading the theme file", e); + } + } + + 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> 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> 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> nestedProperties = (Map>) 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); + } + } + } +} diff --git a/src/main/java/org/saturnclient/saturnclient/cosmetics/HatFeatureRenderer.java b/src/main/java/org/saturnclient/saturnclient/cosmetics/HatFeatureRenderer.java index 30f4d17..da08814 100644 --- a/src/main/java/org/saturnclient/saturnclient/cosmetics/HatFeatureRenderer.java +++ b/src/main/java/org/saturnclient/saturnclient/cosmetics/HatFeatureRenderer.java @@ -3,7 +3,7 @@ package org.saturnclient.saturnclient.cosmetics; import org.saturnclient.saturnclient.auth.SaturnPlayer; import org.saturnclient.saturnclient.auth.Auth; -import net.minecraft.client.MinecraftClient; +import org.saturnclient.saturnclient.SaturnClient; import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRenderer; @@ -48,7 +48,7 @@ public class HatFeatureRenderer extends FeatureRenderer { + SaturnClient.client.execute(() -> { try { List animatedFrames = new ArrayList<>(); for (int i = 0; i < frameCount; i++) { @@ -118,7 +118,7 @@ public class Cloaks { } }).start(); } else { - net.minecraft.client.MinecraftClient.getInstance().execute(() -> loadStaticCloak(player.cloak + ".png")); + SaturnClient.client.execute(() -> loadStaticCloak(player.cloak + ".png")); } } } diff --git a/src/main/java/org/saturnclient/saturnclient/cosmetics/cloaks/utils/IdentifierUtils.java b/src/main/java/org/saturnclient/saturnclient/cosmetics/cloaks/utils/IdentifierUtils.java index 5171a07..40cda74 100644 --- a/src/main/java/org/saturnclient/saturnclient/cosmetics/cloaks/utils/IdentifierUtils.java +++ b/src/main/java/org/saturnclient/saturnclient/cosmetics/cloaks/utils/IdentifierUtils.java @@ -1,6 +1,6 @@ package org.saturnclient.saturnclient.cosmetics.cloaks.utils; -import net.minecraft.client.MinecraftClient; +import org.saturnclient.saturnclient.SaturnClient; import net.minecraft.client.texture.NativeImage; import net.minecraft.client.texture.NativeImageBackedTexture; import net.minecraft.util.Identifier; @@ -20,7 +20,7 @@ public class IdentifierUtils { ByteBuffer bb = BufferUtils.createByteBuffer(bytes.length).put(bytes); bb.flip(); NativeImageBackedTexture nibt = new NativeImageBackedTexture(NativeImage.read(bb)); - MinecraftClient.getInstance().getTextureManager().registerTexture(i, nibt); + SaturnClient.client.getTextureManager().registerTexture(i, nibt); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java index ad95816..8fe7aa0 100644 --- a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java @@ -3,10 +3,12 @@ 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.option.Perspective; import net.minecraft.client.util.InputUtil; -import org.saturnclient.saturnclient.menus.SaturnMenu; -import org.saturnclient.saturnmods.mods.FreeLook; + +// import org.saturnclient.modules.mods.FreeLook; +import org.saturnclient.ui2.screens.ShiftMenu; +// import org.saturnclient.saturnclient.menus.SaturnMenu; import org.lwjgl.glfw.GLFW; /** @@ -19,9 +21,9 @@ 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; + // 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. @@ -35,38 +37,39 @@ public class KeyInputHandler { DEFAULT_MENU_KEY, KEY_CATEGORY)); - freelookKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( - FREELOOK_KEY_ID, - InputUtil.Type.KEYSYM, - FREELOOK_KEY, - KEY_CATEGORY)); + // freelookKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( + // FREELOOK_KEY_ID, + // InputUtil.Type.KEYSYM, + // FREELOOK_KEY, + // KEY_CATEGORY)); // Register the event handler for the main menu key ClientTickEvents.END_CLIENT_TICK.register(client -> { if (mainMenuKeyBinding.wasPressed()) { - client.setScreen(new SaturnMenu()); - } else if (freelookKeyBinding.wasPressed() && FreeLook.enabled.value && FreeLook.toggle.value) { - FreeLook.isFreeLooking = !FreeLook.isFreeLooking; - if (FreeLook.isFreeLooking) { - FreeLook.lastPerspective = client.options.getPerspective(); - client.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } else if (FreeLook.lastPerspective != null) { - client.options.setPerspective(FreeLook.lastPerspective); - FreeLook.lastPerspective = null; - } - } else if (FreeLook.enabled.value && !FreeLook.toggle.value) { - if (freelookKeyBinding.isPressed()) { - if (!FreeLook.isFreeLooking) { - FreeLook.lastPerspective = client.options.getPerspective(); - client.options.setPerspective(Perspective.THIRD_PERSON_BACK); - FreeLook.isFreeLooking = true; - } - } else if (FreeLook.isFreeLooking && FreeLook.lastPerspective != null) { - client.options.setPerspective(FreeLook.lastPerspective); - FreeLook.isFreeLooking = false; - FreeLook.lastPerspective = null; - } + client.setScreen(new ShiftMenu()); } + // 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; + // } + // } }); } } diff --git a/src/main/java/org/saturnclient/saturnclient/menus/CloaksMenu.java b/src/main/java/org/saturnclient/saturnclient/menus/CloaksMenu.java deleted file mode 100644 index f470ec5..0000000 --- a/src/main/java/org/saturnclient/saturnclient/menus/CloaksMenu.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.saturnclient.saturnclient.menus; - -import net.minecraft.text.Text; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.auth.Auth; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.components.SkinPreview; -import org.saturnclient.ui.widgets.SaturnClickableImage; -import org.saturnclient.ui.widgets.SaturnClickableSprite; -import org.saturnclient.ui.widgets.SaturnImage; -import org.saturnclient.ui.widgets.SaturnInputBox; -import org.saturnclient.ui.widgets.SaturnScroll; -import org.saturnclient.ui.widgets.SaturnSprite; - -public class CloaksMenu extends SaturnUi { - - private SaturnScroll scroll; - private Property search = new Property<>(""); - - public CloaksMenu() { - super(Text.of("Cloaks Menu")); - } - - @Override - protected void init() { - int rectWidth = 330; - int rectHeight = 228; - int rectX = (width - rectWidth) / 2; - int rectY = (height - rectHeight + 15) / 2; - - draw( - new SaturnSprite(Textures.SETTINGS_BG) - .setX(rectX) - .setY(rectY) - .setWidth(rectWidth) - .setHeight(rectHeight) - .setAnimations(SaturnClientConfig.getAnimations())); - - int tabsX = (width - 43) / 2; - int tabsY = rectY - 17; - - draw( - new SaturnSprite(Textures.RECT) - .setX(tabsX) - .setY(tabsY) - .setWidth(43) - .setHeight(15) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnInputBox(search, rectX + rectWidth - 72, tabsY, 70).onUpdate(() -> { - scroll.clear(); - drawItems(rectX, rectY, rectWidth, rectHeight); - }) - .setHeight(15) - .setWidth(72) - .setAnimations(SaturnClientConfig.getAnimations())); - - int tabSize = 9; - tabsX = (width - tabSize) / 2; - draw( - new SaturnClickableImage(Textures.HAT, () -> { - client.setScreen(new HatsMenu()); - }) - .setX(tabsX) - .setY(tabsY + 4) - .setWidth(tabSize) - .setHeight(7) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.CLOAK, () -> { - }) - .setSelected(true) - .setX(tabsX - 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.SEARCH, () -> { - System.out.println("Pressed"); - }) - .setX(tabsX + 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - scroll = new SaturnScroll(); - - drawItems(rectX, rectY, rectWidth, rectHeight); - - draw(scroll - .setX(rectX + 17) - .setY(rectY + 10) - .setWidth(rectWidth - 17) - .setHeight(rectHeight - 10) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw(new SkinPreview() - .setScale(3.0f) - .setX((rectX + rectWidth) - 180) - .setY(rectY + 8) - .setAnimations(SaturnClientConfig.getAnimations())); - - super.init(); - } - - private void drawItems(int rectX, int rectY, int rectWidth, int rectHeight) { - int cloakWidth = 28; - int cloakHeight = 61; - - int modX = 0; - int modY = 0; - int col = 0; - - String[] searchTokens = search.value.toLowerCase().split("\\ "); - - outer: for (String cloak : Cloaks.availableCloaks) { - for (String searchToken : searchTokens) { - if (!cloak.contains(searchToken)) { - continue outer; - } - } - - scroll.draw( - new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> { - Cloaks.setCloak(Auth.uuid, cloak); - }) - .setX(modX) - .setY(modY) - .setWidth(cloakWidth + 6) - .setHeight(cloakHeight + 6)); - - scroll.draw( - new SaturnImage(Textures.getCloakPreview(cloak)) - .setX(modX + 3) - .setY(modY + 3) - .setWidth(cloakWidth) - .setHeight(cloakHeight)); - - col++; - - if (col < 4) { - modX += cloakWidth + 21; - } else { - modX = 0; - modY += cloakHeight + 20; - col = 0; - } - } - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java b/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java deleted file mode 100644 index 6afca1b..0000000 --- a/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java +++ /dev/null @@ -1,234 +0,0 @@ -package org.saturnclient.saturnclient.menus; - -import java.util.Map; -import net.minecraft.text.Text; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.components.SaturnFloat; -import org.saturnclient.ui.components.SaturnHex; -import org.saturnclient.ui.components.SaturnInteger; -import org.saturnclient.ui.components.SaturnString; -import org.saturnclient.ui.components.SaturnToggle; -import org.saturnclient.ui.widgets.SaturnImageButton; -import org.saturnclient.ui.widgets.SaturnScroll; -import org.saturnclient.ui.widgets.SaturnSprite; -import org.saturnclient.ui.widgets.SaturnText; - -public class ConfigEditor extends SaturnUi { - - private ConfigManager config; - - public ConfigEditor(ConfigManager config) { - super(Text.of("Config editor")); - this.config = config; - } - - @Override - protected void init() { - int rectWidth = 330; - int rectHeight = 228; - int rectX = (width - rectWidth) / 2; - int rectY = (height - rectHeight + 15) / 2; - - draw( - new SaturnSprite(Textures.SETTINGS_BG) - .setX(rectX) - .setY(rectY) - .setWidth(rectWidth) - .setHeight(rectHeight) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnImageButton(Textures.CLOSE, 9, 9, () -> { - this.close(); - }) - .setX(rectX) - .setY(rectY - 15) - .setWidth(13) - .setHeight(13) - .setAnimations(SaturnClientConfig.getAnimations())); - - SaturnScroll configScroll = new SaturnScroll(); - - int row = 0; - int col = 0; - - drawProperties(configScroll, config.getProperties(), rectWidth, row, col); - - draw( - configScroll - .setX(rectX + 17) - .setY(rectY + 10) - .setWidth(rectWidth - 17) - .setHeight(rectHeight - 10) - .setAnimations(SaturnClientConfig.getAnimations())); - - super.init(); - } - - @SuppressWarnings("unchecked") - private int drawProperties(SaturnScroll configScroll, Map> properties, int rectWidth, - int row, int col) { - int totalRows = row; - for (Map.Entry> propEntry : properties.entrySet()) { - Property prop = propEntry.getValue(); - String propName = propEntry.getKey(); - - boolean full = isFull(prop); - - if (full && col > 0) { - col = 0; - totalRows++; - } - - int modX = ((rectWidth / 2) - 17) * col; - int modY = 14 * totalRows; - - switch (prop.getType()) { - case BOOLEAN: - configScroll.draw( - new SaturnToggle((Property) prop) - .setX(modX) - .setY(modY)); - configScroll.draw( - new SaturnText( - propName.substring(0, 1).toUpperCase() + - propName.substring(1)) - .setX(modX + 18) - .setY(modY) - .setScale(0.8f)); - break; - case INTEGER: - configScroll.draw( - new SaturnText( - propName.substring(0, 1).toUpperCase() + - propName.substring(1)) - .setX(modX) - .setY(modY) - .setScale(0.8f)); - - configScroll.draw( - new SaturnInteger( - (Property) prop, - (rectWidth / 2) - 17, - modY, - 70)); - - configScroll.draw(resetButton(prop, modX, modY)); - break; - case FLOAT: - configScroll.draw( - new SaturnText( - propName.substring(0, 1).toUpperCase() + - propName.substring(1)) - .setX(modX) - .setY(modY) - .setScale(0.8f)); - - configScroll.draw( - new SaturnFloat( - (Property) prop, - (rectWidth / 2) - 17, - modY, - 70)); - - configScroll.draw(resetButton(prop, modX, modY)); - break; - case STRING: - configScroll.draw( - new SaturnText( - propName.substring(0, 1).toUpperCase() + - propName.substring(1)) - .setX(modX) - .setY(modY) - .setScale(0.8f)); - - configScroll.draw( - new SaturnString( - (Property) prop, - (rectWidth / 2) - 17, - modY, - 70)); - - configScroll.draw(resetButton(prop, modX, modY)); - break; - case HEX: - configScroll.draw( - new SaturnText( - propName.substring(0, 1).toUpperCase() + - propName.substring(1)) - .setX(modX) - .setY(modY) - .setScale(0.8f)); - - configScroll.draw( - new SaturnHex( - (Property) prop, - (rectWidth / 2) - 17, - modY, - 70)); - - configScroll.draw(resetButton(prop, modX, modY)); - break; - case NAMESPACE: - configScroll.draw( - new SaturnText( - propName.substring(0, 1).toUpperCase() + - propName.substring(1)) - .setX(modX) - .setY(modY) - .setScale(0.8f)); - - // Recursively draw nested properties and update total rows - Map> nestedProperties = (Map>) prop.value; - totalRows = drawProperties(configScroll, nestedProperties, rectWidth, - totalRows + 1, 0); - } - - if (full) { - totalRows++; - } else { - col++; - if (col > 1) { - col = 0; - totalRows++; - } - } - } - return totalRows; - } - - public static boolean isFull(Property prop) { - switch (prop.getType()) { - case BOOLEAN: - return false; - default: - return true; - } - } - - @Override - public void close() { - ConfigManager.save(); - super.close(); - } - - public SaturnWidget resetButton(Property prop, int modX, int modY) { - int size = textRenderer.fontHeight - 1; - return new SaturnImageButton( - Textures.RESET, - size, - size, - () -> { - prop.reset(); - }) - .setX(modX + 209) - .setY(modY) - .setWidth(size + 3) - .setHeight(size + 3); - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/menus/HatsMenu.java b/src/main/java/org/saturnclient/saturnclient/menus/HatsMenu.java deleted file mode 100644 index 506f90b..0000000 --- a/src/main/java/org/saturnclient/saturnclient/menus/HatsMenu.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.saturnclient.saturnclient.menus; - -import net.minecraft.text.Text; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.auth.Auth; -import org.saturnclient.saturnclient.cosmetics.Hats; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.components.SkinPreview; -import org.saturnclient.ui.widgets.SaturnClickableImage; -import org.saturnclient.ui.widgets.SaturnClickableSprite; -import org.saturnclient.ui.widgets.SaturnImage; -import org.saturnclient.ui.widgets.SaturnScroll; -import org.saturnclient.ui.widgets.SaturnSprite; - -public class HatsMenu extends SaturnUi { - - public HatsMenu() { - super(Text.of("Hats Menu")); - } - - @Override - protected void init() { - int rectWidth = 330; - int rectHeight = 228; - int rectX = (width - rectWidth) / 2; - int rectY = (height - rectHeight + 15) / 2; - - draw( - new SaturnSprite(Textures.SETTINGS_BG) - .setX(rectX) - .setY(rectY) - .setWidth(rectWidth) - .setHeight(rectHeight) - .setAnimations(SaturnClientConfig.getAnimations())); - - int tabsX = (width - 43) / 2; - int tabsY = rectY - 17; - - draw( - new SaturnSprite(Textures.RECT) - .setX(tabsX) - .setY(tabsY) - .setWidth(43) - .setHeight(15) - .setAnimations(SaturnClientConfig.getAnimations())); - - int tabSize = 9; - tabsX = (width - tabSize) / 2; - draw( - new SaturnClickableImage(Textures.HAT, () -> { - client.setScreen(new HatsMenu()); - }) - .setSelected(true) - .setX(tabsX) - .setY(tabsY + 4) - .setWidth(tabSize) - .setHeight(7) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.CLOAK, () -> { - client.setScreen(new CloaksMenu()); - }) - .setX(tabsX - 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.SEARCH, () -> { - System.out.println("Pressed"); - }) - .setX(tabsX + 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - int hatSize = 28; - - int modX = 0; - int modY = 0; - int col = 0; - - SaturnScroll modsScroll = new SaturnScroll(); - - for (String hat : Hats.availableHats) { - modsScroll.draw( - new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> { - Hats.setHat(Auth.uuid, hat); - }) - .setX(modX) - .setY(modY) - .setWidth(hatSize + 6) - .setHeight(hatSize + 6)); - - modsScroll.draw( - new SaturnImage(Textures.getHatPreview(hat)) - .setX(modX + 3) - .setY(modY + 3) - .setWidth(hatSize) - .setHeight(hatSize)); - - col++; - - if (col < 4) { - modX += hatSize + 21; - } else { - modX = 0; - modY += hatSize + 20; - col = 0; - } - } - - draw( - modsScroll - .setX(rectX + 17) - .setY(rectY + 10) - .setWidth(rectWidth - 17) - .setHeight(rectHeight - 10) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw(new SkinPreview() - .setScale(3.0f) - .setX((rectX + rectWidth) - 180) - .setY(rectY + 8) - .setAnimations(SaturnClientConfig.getAnimations())); - - super.init(); - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/menus/HudEditor.java b/src/main/java/org/saturnclient/saturnclient/menus/HudEditor.java index 5c56147..2d9b92a 100644 --- a/src/main/java/org/saturnclient/saturnclient/menus/HudEditor.java +++ b/src/main/java/org/saturnclient/saturnclient/menus/HudEditor.java @@ -5,12 +5,12 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; +import org.saturnclient.modules.HudMod; +import org.saturnclient.modules.ModDimensions; +import org.saturnclient.modules.ModManager; +import org.saturnclient.modules.Module; import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnmods.HudMod; -import org.saturnclient.saturnmods.ModDimensions; -import org.saturnclient.saturnmods.ModManager; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.SaturnUi; +import org.saturnclient.ui2.SaturnScreen; import java.util.ArrayList; import java.util.List; @@ -24,7 +24,7 @@ public class HudEditor extends Screen { public HudEditor() { super(Text.literal("HUD Editor")); - for (SaturnMod m : ModManager.MODS) { + for (Module m : ModManager.MODS) { if (m.isEnabled() && m instanceof HudMod) { hudMods.add((HudMod) m); } @@ -90,7 +90,7 @@ public class HudEditor extends Screen { @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (client.world == null && client.getCurrentServerEntry() == null) { - SaturnUi.ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta); + SaturnScreen.ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta); } for (HudMod mod : hudMods) { diff --git a/src/main/java/org/saturnclient/saturnclient/menus/ModMenu.java b/src/main/java/org/saturnclient/saturnclient/menus/ModMenu.java deleted file mode 100644 index 339e39f..0000000 --- a/src/main/java/org/saturnclient/saturnclient/menus/ModMenu.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.saturnclient.saturnclient.menus; - -import net.minecraft.text.Text; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnmods.ModManager; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.components.SaturnModComp; -import org.saturnclient.ui.widgets.SaturnClickableImage; -import org.saturnclient.ui.widgets.SaturnInputBox; -import org.saturnclient.ui.widgets.SaturnScroll; -import org.saturnclient.ui.widgets.SaturnSprite; - -public class ModMenu extends SaturnUi { - - private SaturnScroll scroll; - private Property search = new Property<>(""); - - public ModMenu() { - super(Text.literal("Mods")); - } - - @Override - protected void init() { - int rectWidth = 330; - int rectHeight = 228; - int rectX = (width - rectWidth) / 2; - int rectY = (height - rectHeight + 15) / 2; - - draw( - new SaturnSprite(Textures.SETTINGS_BG) - .setX(rectX) - .setY(rectY) - .setWidth(rectWidth) - .setHeight(rectHeight) - .setAnimations(SaturnClientConfig.getAnimations())); - - int tabsX = (width - 43) / 2; - int tabsY = rectY - 17; - - draw( - new SaturnSprite(Textures.RECT) - .setX(tabsX) - .setY(tabsY) - .setWidth(43) - .setHeight(15) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnInputBox(search, rectX + rectWidth - 72, tabsY, 70).onUpdate(() -> { - scroll.clear(); - drawItems(rectX, rectY, rectWidth, rectHeight); - }) - .setHeight(15) - .setWidth(72) - .setAnimations(SaturnClientConfig.getAnimations())); - - int tabSize = 9; - tabsX = (width - tabSize) / 2; - draw( - new SaturnClickableImage(Textures.SETTINGS, () -> { - client.setScreen(new SaturnConfigEditor()); - }) - .setX(tabsX) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.MODS_TAB, () -> { - }) - .setSelected(true) - .setX(tabsX - 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.SEARCH, () -> { - System.out.println("Pressed"); - }) - .setX(tabsX + 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - scroll = new SaturnScroll(); - - drawItems(rectX, rectY, rectWidth, rectHeight); - - draw(scroll - .setX(rectX + 17) - .setY(rectY + 10) - .setWidth(rectWidth - 17) - .setHeight(rectHeight - 20) - .setAnimations(SaturnClientConfig.getAnimations())); - - super.init(); - } - - @Override - public void close() { - ConfigManager.save(); - super.close(); - } - - private void drawItems(int rectX, int rectY, int rectWidth, int rectHeight) { - int modX = 0; - int modY = 0; - int col = 0; - - String[] searchTokens = search.value.toLowerCase().split("\\ "); - - outer: for (SaturnMod mod : ModManager.MODS) { - String modName = mod.getName().toLowerCase(); - for (String searchToken : searchTokens) { - if (!modName.contains(searchToken)) { - continue outer; - } - } - - scroll.draw( - new SaturnModComp(mod) - .setX(modX) - .setY(modY) - .setWidth(86) - .setHeight(20)); - - col++; - - if (col < 3) { - modX += 86 + 18; - } else { - modX = 0; - modY += 20 + 20; - col = 0; - } - } - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/menus/SaturnConfigEditor.java b/src/main/java/org/saturnclient/saturnclient/menus/SaturnConfigEditor.java deleted file mode 100644 index 5a852b6..0000000 --- a/src/main/java/org/saturnclient/saturnclient/menus/SaturnConfigEditor.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient.menus; - -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.widgets.SaturnClickableImage; -import org.saturnclient.ui.widgets.SaturnSprite; - -public class SaturnConfigEditor extends ConfigEditor { - - public SaturnConfigEditor() { - super(SaturnClientConfig.config); - } - - @Override - protected void init() { - int rectHeight = 228; - int rectY = (height - rectHeight + 15) / 2; - - int tabsX = (width - 43) / 2; - int tabsY = rectY - 17; - - draw( - new SaturnSprite(Textures.RECT) - .setX(tabsX) - .setY(tabsY) - .setWidth(43) - .setHeight(15) - .setAnimations(SaturnClientConfig.getAnimations())); - - int tabSize = 9; - tabsX = (width - tabSize) / 2; - draw( - new SaturnClickableImage(Textures.SETTINGS, () -> { - }) - .setSelected(true) - .setX(tabsX) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.MODS_TAB, () -> { - client.setScreen(new ModMenu()); - }) - .setX(tabsX - 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - draw( - new SaturnClickableImage(Textures.SEARCH, () -> { - System.out.println("Pressed"); - }) - .setX(tabsX + 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClientConfig.getAnimations())); - - super.init(); - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/menus/SaturnMenu.java b/src/main/java/org/saturnclient/saturnclient/menus/SaturnMenu.java deleted file mode 100644 index d15dcb8..0000000 --- a/src/main/java/org/saturnclient/saturnclient/menus/SaturnMenu.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.saturnclient.saturnclient.menus; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.text.Text; - -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.animations.FadeIn; -import org.saturnclient.ui.animations.Slide; -import org.saturnclient.ui.widgets.SaturnButton; -import org.saturnclient.ui.widgets.SaturnImage; -import org.saturnclient.ui.widgets.SaturnImageButton; - -public class SaturnMenu extends SaturnUi { - public SaturnMenu() { - super(Text.literal("Saturn Client")); - } - - @Override - protected void init() { - SaturnClientConfig.textRenderer = MinecraftClient.getInstance().textRenderer; - - int buttonWidth = 96; - int buttonHeight = 25; - - draw( - new SaturnButton("Mods", () -> { - client.setScreen(new ModMenu()); - }) - .setX((width - buttonWidth) / 2) - .setY((height - buttonHeight) / 2) - .setWidth(buttonWidth) - .setHeight(buttonHeight) - .setAnimations(new FadeIn(2))); - - draw( - new SaturnImageButton(Textures.HUD_ICON, 14, 14, () -> { - client.setScreen(new HudEditor()); - }) - .setX((width - buttonWidth - (buttonHeight * 2) - 6) / 2) - .setY((height - buttonHeight) / 2) - .setWidth(buttonHeight) - .setHeight(buttonHeight) - .setAnimations(new FadeIn(2))); - - draw( - new SaturnImageButton(Textures.COSMETICS, 14, 14, () -> { - client.setScreen(new CloaksMenu()); - }) - .setX((width / 2) + (buttonWidth / 2) + 3) - .setY((height - buttonHeight) / 2) - .setWidth(buttonHeight) - .setHeight(buttonHeight) - .setAnimations(new FadeIn(2))); - - int logoSize = 49; - - draw( - new SaturnImage(Textures.LOGO_TEXT) - .setX((width - logoSize) / 2) - .setY((height - 8) / 2 - 23) - .setWidth(logoSize) - .setHeight(8) - .setAnimations(new FadeIn(2))); - - draw( - new SaturnImage(SaturnClientConfig.getLogo()) - .setX((width - logoSize) / 2) - .setY(height / 2 - logoSize - 24) - .setWidth(logoSize) - .setHeight(logoSize) - .setAnimations(new Slide(2, 14))); - - super.init(); - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/menus/SaturnTitleScreen.java b/src/main/java/org/saturnclient/saturnclient/menus/SaturnTitleScreen.java deleted file mode 100644 index 2cc3785..0000000 --- a/src/main/java/org/saturnclient/saturnclient/menus/SaturnTitleScreen.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.saturnclient.saturnclient.menus; - -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.Textures; -import org.saturnclient.ui.animations.FadeIn; -import org.saturnclient.ui.animations.Slide; -import org.saturnclient.ui.widgets.SaturnButton; -import org.saturnclient.ui.widgets.SaturnImage; - -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.text.Text; - -public class SaturnTitleScreen extends SaturnUi { - public SaturnTitleScreen() { - super(Text.literal("Title Screen")); - } - - @Override - protected void init() { - blur = false; - - int logoSize = 49; - int bX = (width - 150) / 2; - int bY = height / 2 - logoSize - 27; - - draw( - new SaturnImage(SaturnClientConfig.getLogo()) - .setX((width - logoSize) / 2) - .setY(bY) - .setWidth(logoSize) - .setHeight(logoSize) - .setAnimations(new Slide(3, 14))); - - bY += 44; - - draw( - new SaturnImage(Textures.LOGO_TEXT) - .setX((width - logoSize) / 2) - .setY(bY) - .setWidth(logoSize) - .setHeight(8) - .setAnimations(new FadeIn(3))); - - bY += 15; - - draw(new SaturnButton("SINGLEPLAYER", () -> { - client.setScreen(new SelectWorldScreen(new SaturnTitleScreen())); - }).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f)); - - bY += 20; - - draw(new SaturnButton("MULTIPLAYER", () -> { - client.setScreen(new MultiplayerScreen(new SaturnTitleScreen())); - }).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f)); - - bY += 20; - - draw(new SaturnButton("OPTIONS", () -> { - client.setScreen(new OptionsScreen(new SaturnTitleScreen(), this.client.options)); - }).setBold(true).setWidth(103).setHeight(26).setX(bX).setY(bY).setScale(0.69f)); - - draw(new SaturnButton("QUIT", () -> { - client.scheduleStop(); - }).setBold(true).setWidth(103).setHeight(26).setX(bX + 74).setY(bY).setScale(0.69f)); - - bY += 20; - - draw(new SaturnButton("SATURN OPTIONS", () -> { - client.setScreen(new SaturnMenu()); - }).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f)); - - super.init(); - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/CameraMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/CameraMixin.java deleted file mode 100644 index 55d0135..0000000 --- a/src/main/java/org/saturnclient/saturnclient/mixin/CameraMixin.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.Camera; - -import org.saturnclient.saturnclient.mod_utils.CameraOverriddenEntity; -import org.saturnclient.saturnmods.mods.FreeLook; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - 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; - } - } - -} diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/Crosshair.java b/src/main/java/org/saturnclient/saturnclient/mixin/Crosshair.java deleted file mode 100644 index 457207b..0000000 --- a/src/main/java/org/saturnclient/saturnclient/mixin/Crosshair.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Code from: https://github.com/Selyss - * Repo: https://github.com/Selyss/CrosshairIndicator/tree/main -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderTickCounter; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.gui.DrawContext; - -@Mixin(InGameHud.class) -public class Crosshair { - @Shadow - @Final - private MinecraftClient client; - @Unique - Identifier textureLocation = Identifier.of("saturnclient", "textures/gui/hud/crosshair_range.png"); - - @Inject(method = "renderCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIII)V", ordinal = 0)) - private void drawCrosshair(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - if (org.saturnclient.saturnmods.mods.Crosshair.enabled.value - && org.saturnclient.saturnmods.mods.Crosshair.range_indicator.value - && this.client.targetedEntity != null - && this.client.targetedEntity.isAlive()) { - RenderSystem.setShaderTexture(0, textureLocation); - int scaledWidth = 15; - int scaledHeight = 15; - - context.drawTexture(RenderLayer::getCrosshair, textureLocation, - (context.getScaledWindowWidth() - scaledWidth) / 2, - (context.getScaledWindowHeight() - scaledHeight) / 2, 0.0F, 0.0F, scaledWidth, scaledHeight, - scaledWidth, scaledHeight); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java new file mode 100644 index 0000000..f049e40 --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java @@ -0,0 +1,12 @@ +package org.saturnclient.saturnclient.mixin; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.render.VertexConsumerProvider; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(DrawContext.class) +public interface DrawContextAccessor { + @Accessor("vertexConsumers") + VertexConsumerProvider.Immediate getVertexConsumers(); +} diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/EntityMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/EntityMixin.java deleted file mode 100644 index f452cd8..0000000 --- a/src/main/java/org/saturnclient/saturnclient/mixin/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -import org.saturnclient.saturnclient.mod_utils.CameraOverriddenEntity; -import org.saturnclient.saturnmods.mods.FreeLook; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreeLook.isFreeLooking && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java index 638c262..defa7f5 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java @@ -1,6 +1,6 @@ package org.saturnclient.saturnclient.mixin; -import net.minecraft.client.MinecraftClient; +import org.saturnclient.saturnclient.SaturnClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer.TextLayerType; import net.minecraft.client.render.VertexConsumerProvider; @@ -9,7 +9,9 @@ import net.minecraft.client.render.entity.EntityRenderer; import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.util.math.Vec3d; import org.saturnclient.saturnclient.SaturnClientConfig; @@ -34,20 +36,32 @@ public abstract class NameTagMixin { @Inject(method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"), cancellable = true) private void onRenderLabelIfPresent(S state, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { - if (isSaturn(state)) { - renderLabel(state, Text.literal(SaturnClientConfig.getSaturnIndicator()).append(text), matrices, + + String uuid = isSaturn(state); + + if (uuid != null) { + MutableText iconText = Text.literal(SaturnClientConfig.getSaturnIndicator()) + .styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid))); + + Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE)); + + renderLabel(state, iconText.append(nameText), matrices, vertexConsumers, light); + ci.cancel(); } } - private boolean isSaturn(S state) { + private String isSaturn(S state) { if (state instanceof PlayerEntityRenderState) { String name = ((PlayerEntityRenderState) state).name; String uuid = Auth.playerNames.get(name); - return uuid != null && Auth.players.containsKey(uuid); + if (Auth.players.containsKey(uuid)) { + return uuid; + } } - return false; + + return null; } private void renderLabel(S state, Text text, MatrixStack matrices, @@ -61,9 +75,9 @@ public abstract class NameTagMixin { matrices.multiply(this.dispatcher.getRotation()); matrices.scale(0.025F, -0.025F, 0.025F); Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + TextRenderer textRenderer = SaturnClient.client.textRenderer; float f = (float) (-textRenderer.getWidth(text)) / 2.0F; - int j = (int) (MinecraftClient.getInstance().options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24; + int j = (int) (SaturnClient.client.options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24; textRenderer.draw(text, f, (float) i, -2130706433, false, matrix4f, vertexConsumers, bl ? TextLayerType.SEE_THROUGH : TextLayerType.NORMAL, j, light); if (bl) { diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java index 1eadb68..058ec46 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java @@ -1,7 +1,10 @@ package org.saturnclient.saturnclient.mixin; import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + import org.jetbrains.annotations.Nullable; import org.saturnclient.saturnclient.SaturnClientConfig; import org.saturnclient.saturnclient.auth.Auth; @@ -29,7 +32,11 @@ public abstract class TabListMixin { String name = profile.getName(); String uuid = profile.getId().toString().replaceAll("-", ""); - return Text.literal( - Auth.players.containsKey(uuid) ? SaturnClientConfig.getSaturnIndicator() + name : name); + MutableText iconText = Text.literal(SaturnClientConfig.getSaturnIndicator()) + .styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid))); + + Text nameText = Text.literal(name).styled(style -> style.withColor(Formatting.WHITE)); + + return Auth.players.containsKey(uuid) ? iconText.append(nameText) : Text.literal(name); } } diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/TitleScreenMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/TitleScreenMixin.java new file mode 100644 index 0000000..44151c1 --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/mixin/TitleScreenMixin.java @@ -0,0 +1,22 @@ +package org.saturnclient.saturnclient.mixin; + +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.SaturnClientConfig; +import org.saturnclient.ui2.screens.TitleMenu; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.gui.screen.TitleScreen; + +@Mixin(TitleScreen.class) +public class TitleScreenMixin { + @Inject(method = "init", at = @At("HEAD"), cancellable = true) + private void onInit(CallbackInfo ci) { + if (SaturnClientConfig.saturnTitleScreen.value) { + SaturnClient.client.setScreen(new TitleMenu()); + ci.cancel(); + } + } +} diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/TotemParticleMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/TotemParticleMixin.java deleted file mode 100644 index c2ff037..0000000 --- a/src/main/java/org/saturnclient/saturnclient/mixin/TotemParticleMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.particle.AnimatedParticle; -import net.minecraft.client.particle.SpriteProvider; -import net.minecraft.client.particle.TotemParticle; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.util.math.ColorHelper; - -import org.saturnclient.saturnmods.mods.Particles; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(TotemParticle.class) -public class TotemParticleMixin extends AnimatedParticle { - protected TotemParticleMixin(ClientWorld world, double x, double y, double z, SpriteProvider spriteProvider, - float upwardsAcceleration) { - super(world, x, y, z, spriteProvider, upwardsAcceleration); - } - - @Inject(at = @At("TAIL"), method = "") - private void colorChanger(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, - double velocityZ, SpriteProvider spriteProvider, CallbackInfo ci) { - if (Particles.enabled.value && Particles.totem_enabled.value) { - if (this.random.nextInt(2) == 0) { - this.setColor(ColorHelper.getRedFloat(Particles.totem_1.value), - ColorHelper.getGreenFloat(Particles.totem_1.value), - ColorHelper.getBlueFloat(Particles.totem_1.value)); - } else { - this.setColor(ColorHelper.getRedFloat(Particles.totem_2.value), - ColorHelper.getGreenFloat(Particles.totem_2.value), - ColorHelper.getBlueFloat(Particles.totem_2.value)); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/saturnclient/mod_utils/CameraOverriddenEntity.java b/src/main/java/org/saturnclient/saturnclient/mod_utils/CameraOverriddenEntity.java deleted file mode 100644 index a72664a..0000000 --- a/src/main/java/org/saturnclient/saturnclient/mod_utils/CameraOverriddenEntity.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.saturnclient.mod_utils; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - void freelook$setCameraYaw(float yaw); -} diff --git a/src/main/java/org/saturnclient/saturnmods/ModManager.java b/src/main/java/org/saturnclient/saturnmods/ModManager.java deleted file mode 100644 index f488a9c..0000000 --- a/src/main/java/org/saturnclient/saturnmods/ModManager.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.saturnclient.saturnmods; - -import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.util.math.MatrixStack; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.menus.HudEditor; -import org.saturnclient.saturnmods.mods.*; - -public class ModManager { - - public static SaturnMod[] MODS = { - new Coordinates(), - new ArmorDisplay(), - new FpsDisplay(), - new Particles(), - new Crosshair(), - new FreeLook() - }; - - public static void init() { - HudRenderCallback.EVENT.register((context, _o) -> { - MinecraftClient client = MinecraftClient.getInstance(); - TextRenderer textRenderer = client.textRenderer; - - if (textRenderer != null && - !(client.currentScreen instanceof HudEditor)) { - SaturnClientConfig.textRenderer = textRenderer; - - for (SaturnMod m : MODS) { - if (m instanceof HudMod && m.isEnabled()) { - ModDimensions dim = ((HudMod) m).getDimensions(); - - MatrixStack matrices = context.getMatrices(); - matrices.push(); - - matrices.translate(dim.x.value, (float) dim.y.value, 0); - - matrices.scale(dim.scale.value, dim.scale.value, 1.0f); - - ((HudMod) m).render(context); - - matrices.pop(); - } - } - } - }); - } -} diff --git a/src/main/java/org/saturnclient/saturnmods/SaturnMod.java b/src/main/java/org/saturnclient/saturnmods/SaturnMod.java deleted file mode 100644 index 3d0ec34..0000000 --- a/src/main/java/org/saturnclient/saturnmods/SaturnMod.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.saturnclient.saturnmods; - -import org.saturnclient.saturnclient.config.ConfigManager; - -import net.minecraft.util.Identifier; - -public interface SaturnMod { - public boolean isEnabled(); - - public void setEnabled(boolean e); - - public String getName(); - - public Identifier getIconTexture(); - - public ConfigManager getConfig(); -} diff --git a/src/main/java/org/saturnclient/saturnmods/mods/ArmorDisplay.java b/src/main/java/org/saturnclient/saturnmods/mods/ArmorDisplay.java deleted file mode 100644 index 2afe787..0000000 --- a/src/main/java/org/saturnclient/saturnmods/mods/ArmorDisplay.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.saturnclient.saturnmods.mods; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnmods.HudMod; -import org.saturnclient.saturnmods.ModDimensions; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.Textures; - -public class ArmorDisplay implements SaturnMod, HudMod { - - private static ConfigManager config = new ConfigManager("Armor Display"); - public static Property enabled = config.property( - "Enabled", - new Property<>(false)); - private static ModDimensions dimensions = new ModDimensions( - config, - 0, - 0, - 34, - 75); - - public static Property fgColor = config.property( - "Foreground color", - new Property<>(SaturnClientConfig.WHITE, Property.PropertyType.HEX)); - - private boolean renderItem(DrawContext context, ItemStack item, int y) { - if (item.isEmpty()) { - return false; - } - - context.drawItem(item, 0, y); - - if (item.getMaxDamage() > 0) { - MatrixStack matrices = context.getMatrices(); - - matrices.push(); - - matrices.translate(17, y + 5, 0); - - matrices.scale(0.8f, 0.8f, 0f); - - context.drawText( - SaturnClientConfig.textRenderer, - "" + (item.getMaxDamage() - item.getDamage()), - 0, - 0, - fgColor.value, - false); - - matrices.pop(); - } - - return true; - } - - @Override - public void render(DrawContext context) { - PlayerEntity player = MinecraftClient.getInstance().player; - ItemStack[] items = { - player.getEquippedStack(EquipmentSlot.MAINHAND), - player.getEquippedStack(EquipmentSlot.FEET), - player.getEquippedStack(EquipmentSlot.LEGS), - player.getEquippedStack(EquipmentSlot.CHEST), - player.getEquippedStack(EquipmentSlot.HEAD), - }; - - int y = 60; - - for (ItemStack item : items) { - if (renderItem(context, item, y)) { - y -= 15; - } - } - } - - @Override - public void renderDummy(DrawContext context) { - ItemStack[] items = { - new ItemStack(Items.DIAMOND_SWORD), - new ItemStack(Items.DIAMOND_BOOTS), - new ItemStack(Items.DIAMOND_LEGGINGS), - new ItemStack(Items.DIAMOND_CHESTPLATE), - new ItemStack(Items.DIAMOND_HELMET), - }; - - int y = 60; - - for (ItemStack item : items) { - if (renderItem(context, item, y)) { - y -= 15; - } - } - } - - public String getName() { - return "Armor display"; - } - - @Override - public Identifier getIconTexture() { - return Textures.getModIcon("armor"); - } - - public ModDimensions getDimensions() { - return dimensions; - } - - public boolean isEnabled() { - return enabled.value; - } - - public void setEnabled(boolean e) { - enabled.value = e; - } - - @Override - public ConfigManager getConfig() { - return config; - } -} diff --git a/src/main/java/org/saturnclient/saturnmods/mods/Coordinates.java b/src/main/java/org/saturnclient/saturnmods/mods/Coordinates.java deleted file mode 100644 index 49ca13e..0000000 --- a/src/main/java/org/saturnclient/saturnmods/mods/Coordinates.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.saturnclient.saturnmods.mods; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnmods.HudMod; -import org.saturnclient.saturnmods.ModDimensions; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.Textures; - -public class Coordinates implements SaturnMod, HudMod { - - private static ConfigManager config = new ConfigManager("Coordinates"); - public static Property enabled = config.property( - "Enabled", - new Property<>(false)); - private static ModDimensions dimensions = new ModDimensions(config); - - public static Property fgColor = config.property( - "Foreground color", - new Property<>(SaturnClientConfig.WHITE, Property.PropertyType.HEX)); - - public Coordinates() { - // Ensure fgColor has a value - if (fgColor.value == null) { - fgColor.value = SaturnClientConfig.WHITE; - } - } - - public void renderDummy(DrawContext context) { - int playerX = 124; - int playerY = 69; - int playerZ = 83; - - context.drawText( - SaturnClientConfig.textRenderer, - playerX + " " + playerY + " " + playerZ, - 0, - 0, - fgColor.value, - false); - - dimensions.width = SaturnClientConfig.textRenderer.getWidth( - playerX + " " + playerY + " " + playerZ); - dimensions.height = SaturnClientConfig.textRenderer.fontHeight; - } - - public void render(DrawContext context) { - PlayerEntity player = MinecraftClient.getInstance().player; - int playerX = (int) player.getX(); - int playerY = (int) player.getY(); - int playerZ = (int) player.getZ(); - - context.drawText( - SaturnClientConfig.textRenderer, - playerX + " " + playerY + " " + playerZ, - 0, - 0, - fgColor.value, - false); - } - - public String getName() { - return "Coords"; - } - - @Override - public Identifier getIconTexture() { - return Textures.getModIcon("coords"); - } - - public ModDimensions getDimensions() { - return dimensions; - } - - public boolean isEnabled() { - return enabled.value; - } - - public void setEnabled(boolean e) { - enabled.value = e; - } - - @Override - public ConfigManager getConfig() { - return config; - } -} diff --git a/src/main/java/org/saturnclient/saturnmods/mods/Crosshair.java b/src/main/java/org/saturnclient/saturnmods/mods/Crosshair.java deleted file mode 100644 index d32416d..0000000 --- a/src/main/java/org/saturnclient/saturnmods/mods/Crosshair.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.saturnmods.mods; - -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.Textures; - -public class Crosshair implements SaturnMod { - public static ConfigManager config = new ConfigManager("Crosshair"); - - public static Property enabled = config.property( - "Enabled", - new Property<>(false)); - - public static Property range_indicator = config.property( - "Hit range indicator", - new Property<>(false)); - - @Override - public boolean isEnabled() { - return enabled.value; - } - - @Override - public void setEnabled(boolean e) { - enabled.value = e; - } - - @Override - public String getName() { - return "Crosshair"; - } - - @Override - public Identifier getIconTexture() { - return Textures.getModIcon("crosshair"); - } - - @Override - public ConfigManager getConfig() { - return config; - } -} diff --git a/src/main/java/org/saturnclient/saturnmods/mods/FpsDisplay.java b/src/main/java/org/saturnclient/saturnmods/mods/FpsDisplay.java deleted file mode 100644 index 8be27c1..0000000 --- a/src/main/java/org/saturnclient/saturnmods/mods/FpsDisplay.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.saturnclient.saturnmods.mods; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnmods.HudMod; -import org.saturnclient.saturnmods.ModDimensions; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.Textures; - -public class FpsDisplay implements SaturnMod, HudMod { - - public static ConfigManager config = new ConfigManager("Fps Display"); - - public static Property enabled = config.property( - "Enabled", - new Property<>(false)); - - public static ModDimensions dimensions = new ModDimensions( - config, - 0, - 0, - 40, - 8); - - public static Property fgColor = config.property( - "Foreground color", - new Property<>(SaturnClientConfig.WHITE, Property.PropertyType.HEX)); - - @Override - public ModDimensions getDimensions() { - return dimensions; - } - - @Override - public void renderDummy(DrawContext context) { - int fps = 128; - - context.drawText( - SaturnClientConfig.textRenderer, - String.valueOf(fps) + " FPS", - 0, - 0, - fgColor.value, - false); - } - - @Override - public void render(DrawContext context) { - int fps = MinecraftClient.getInstance().getCurrentFps(); - - context.drawText( - SaturnClientConfig.textRenderer, - String.valueOf(fps) + " FPS", - 0, - 0, - fgColor.value, - false); - } - - @Override - public boolean isEnabled() { - return enabled.value; - } - - @Override - public void setEnabled(boolean e) { - enabled.value = e; - } - - @Override - public String getName() { - return "Fps Display"; - } - - @Override - public Identifier getIconTexture() { - return Textures.getModIcon("fps"); - } - - @Override - public ConfigManager getConfig() { - return config; - } -} diff --git a/src/main/java/org/saturnclient/saturnmods/mods/FreeLook.java b/src/main/java/org/saturnclient/saturnmods/mods/FreeLook.java deleted file mode 100644 index 4943604..0000000 --- a/src/main/java/org/saturnclient/saturnmods/mods/FreeLook.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.saturnmods.mods; - -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.Textures; - -import net.minecraft.client.option.Perspective; -import net.minecraft.util.Identifier; - -public class FreeLook implements SaturnMod { - public static boolean isFreeLooking = false; - public static Perspective lastPerspective = null; - - private static ConfigManager config = new ConfigManager("Free Look"); - public static Property enabled = config.property( - "Enabled", - new Property<>(false)); - - public static Property toggle = config.property( - "Toggle Free Look", - new Property<>(false)); - - public boolean isEnabled() { - return enabled.value; - } - - public void setEnabled(boolean e) { - enabled.value = e; - } - - @Override - public ConfigManager getConfig() { - return config; - } - - @Override - public Identifier getIconTexture() { - return Textures.getModIcon("freelook"); - } - - @Override - public String getName() { - return "Free Look"; - } -} diff --git a/src/main/java/org/saturnclient/saturnmods/mods/Particles.java b/src/main/java/org/saturnclient/saturnmods/mods/Particles.java deleted file mode 100644 index 88bf0be..0000000 --- a/src/main/java/org/saturnclient/saturnmods/mods/Particles.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.saturnclient.saturnmods.mods; - -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.Textures; - -public class Particles implements SaturnMod { - public static ConfigManager config = new ConfigManager("Particles"); - - public static Property enabled = config.property( - "Enabled", - new Property<>(false)); - - public static ConfigManager totem = new ConfigManager(config, "Totem particles"); - - public static Property totem_enabled = totem.property( - "Change totem color", - new Property<>(false)); - - public static Property totem_1 = totem.property( - "Totem particle color 1", - new Property<>(SaturnClientConfig.color.value, Property.PropertyType.HEX)); - - public static Property totem_2 = totem.property( - "Totem particle color 2", - new Property<>(SaturnClientConfig.color.value, Property.PropertyType.HEX)); - - @Override - public boolean isEnabled() { - return enabled.value; - } - - @Override - public void setEnabled(boolean e) { - enabled.value = e; - } - - @Override - public String getName() { - return "Particles"; - } - - @Override - public Identifier getIconTexture() { - return Textures.getModIcon("particles"); - } - - @Override - public ConfigManager getConfig() { - return config; - } -} diff --git a/src/main/java/org/saturnclient/ui/SaturnAnimation.java b/src/main/java/org/saturnclient/ui/SaturnAnimation.java deleted file mode 100644 index 61ea141..0000000 --- a/src/main/java/org/saturnclient/ui/SaturnAnimation.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.ui; - -public class SaturnAnimation { - - public int delay = 0; - public int lastTick = 0; - - public void init(SaturnWidget widget) {} - - public boolean run(SaturnWidget widget, int tick) { - return true; - } -} diff --git a/src/main/java/org/saturnclient/ui/SaturnUi.java b/src/main/java/org/saturnclient/ui/SaturnUi.java deleted file mode 100644 index 6e5f69d..0000000 --- a/src/main/java/org/saturnclient/ui/SaturnUi.java +++ /dev/null @@ -1,322 +0,0 @@ -package org.saturnclient.ui; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.PostEffectProcessor; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.render.DefaultFramebufferSet; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.util.Pool; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import org.lwjgl.glfw.GLFW; - -public class SaturnUi extends Screen { - - private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); - - private final Pool pool = new Pool(3); - private float f = 0.0f; - public boolean blur = true; - public boolean titleBackground = false; - public List widgets = new ArrayList<>(); - private int tick = 0; - - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer( - Identifier.of("saturnclient", "textures/gui/title/background/panorama")); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - public static MutableText text(String text) { - return Text.literal(text).setStyle( - Style.EMPTY.withFont(Identifier.of("saturnclient:panton"))); - } - - public static MutableText textBold(String text) { - return Text.literal(text).setStyle( - Style.EMPTY.withFont(Identifier.of("saturnclient:panton_bold"))); - } - - public static void drawHighResTexture(DrawContext context, Identifier t, int x, int y, int w, int h) { - MatrixStack matricies = context.getMatrices(); - matricies.push(); - matricies.translate(x, y, 0); - matricies.scale(.25f, .25f, 1.0f); - - context.drawTexture(RenderLayer::getGuiTextured, t, 0, 0, 0, 0, - w * 4, h * 4, w * 4, h * 4); - - matricies.pop(); - } - - public static void drawHighResTexture(DrawContext context, Identifier t, int x, int y, int w, int h, int c) { - MatrixStack matricies = context.getMatrices(); - matricies.push(); - matricies.translate(x, y, 0); - matricies.scale(.25f, .25f, 1.0f); - - context.drawTexture(RenderLayer::getGuiTextured, t, 0, 0, 0, 0, - w * 4, h * 4, w * 4, h * 4, c); - - matricies.pop(); - } - - public static void drawHighResGuiTexture(DrawContext context, Identifier t, int x, int y, int w, int h, int c) { - MatrixStack matricies = context.getMatrices(); - matricies.push(); - matricies.translate(x, y, 0); - matricies.scale(.25f, .25f, 1.0f); - - context.drawGuiTexture( - RenderLayer::getGuiTextured, - t, - 0, - 0, - w * 4, - h * 4, - c); - - matricies.pop(); - } - - public static int getAlpha(int color, float alpha) { - return ((int) (alpha * 255) << 24) | - (color & 0x00FFFFFF); - } - - public SaturnUi(Text title) { - super(title); - } - - @Override - protected void init() { - scheduler.scheduleAtFixedRate( - this::saturnTick, - 0, - 7, - TimeUnit.MILLISECONDS); - super.init(); - } - - public void draw(SaturnWidget widget) { - synchronized (widgets) { - widget.init(); - widgets.add(widget); - } - } - - public void refresh() { - synchronized (widgets) { - widgets.clear(); - - f = 0.0f; - tick = 0; - - init(); - } - } - - @SuppressWarnings("deprecation") - @Override - public void render( - DrawContext context, - int mouseX, - int mouseY, - float delta) { - - if (client.world == null && client.getCurrentServerEntry() == null) { - ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta); - } - - // Blur - if (!(f < 1.0F) && blur) { - PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect( - Identifier.ofVanilla("blur"), - DefaultFramebufferSet.MAIN_ONLY); - if (postEffectProcessor != null) { - postEffectProcessor.setUniforms("Radius", f); - postEffectProcessor.render(this.client.getFramebuffer(), this.pool); - } - - } - - for (SaturnWidget widget : new ArrayList<>(widgets)) { - if (!widget.visible) - continue; - - double adjustedMouseX = mouseX - widget.x; - double adjustedMouseY = mouseY - widget.y; - boolean isMouseInside = adjustedMouseX >= 0 && - adjustedMouseX <= (widget.width * widget.scale) && - adjustedMouseY >= 0 && - adjustedMouseY <= (widget.height * widget.scale); - - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.translate(widget.x, widget.y, 0); - matrices.scale(widget.scale, widget.scale, 1.0f); - widget.render( - context, - isMouseInside, - (int) (adjustedMouseX / widget.scale), - (int) (adjustedMouseY / widget.scale)); - matrices.pop(); - } - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == 0) { - for (SaturnWidget widget : new ArrayList<>(widgets)) { - widget.focused = false; - if (!widget.visible) - continue; - - double adjustedMouseX = mouseX - widget.x; - double adjustedMouseY = mouseY - widget.y; - boolean isMouseInside = adjustedMouseX >= 0 && - adjustedMouseX <= (widget.width * widget.scale) && - adjustedMouseY >= 0 && - adjustedMouseY <= (widget.height * widget.scale); - - if (isMouseInside) { - widget.focused = true; - widget.click( - (int) (adjustedMouseX / widget.scale), - (int) (adjustedMouseY / widget.scale)); - } - } - } - - return false; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - for (SaturnWidget widget : new ArrayList<>(widgets)) { - if (!widget.visible && !widget.focused) - continue; - - widget.keyPressed(keyCode, scanCode, modifiers); - - char typedChar = getCharFromKey(keyCode, modifiers); - if (typedChar != '\0') { - widget.charTyped(typedChar); - } - } - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public boolean mouseScrolled( - double mouseX, - double mouseY, - double horizontalAmount, - double verticalAmount) { - for (SaturnWidget widget : new ArrayList<>(widgets)) { - double adjustedMouseX = mouseX - widget.x; - double adjustedMouseY = mouseY - widget.y; - boolean isMouseInside = adjustedMouseX >= 0 && - adjustedMouseX <= (widget.width * widget.scale) && - adjustedMouseY >= 0 && - adjustedMouseY <= (widget.height * widget.scale); - - if (isMouseInside) { - widget.mouseScrolled( - (int) (adjustedMouseX / widget.scale), - (int) (adjustedMouseY / widget.scale), - horizontalAmount, - verticalAmount); - } - } - - return super.mouseScrolled( - mouseX, - mouseY, - horizontalAmount, - verticalAmount); - } - - private char getCharFromKey(int keyCode, int modifiers) { - boolean shift = (modifiers & GLFW.GLFW_MOD_SHIFT) != 0; - - // A-Z - if (keyCode >= GLFW.GLFW_KEY_A && keyCode <= GLFW.GLFW_KEY_Z) { - return (char) (shift - ? 'A' + (keyCode - GLFW.GLFW_KEY_A) - : 'a' + (keyCode - GLFW.GLFW_KEY_A)); - } - - // 0-9 - if (keyCode >= GLFW.GLFW_KEY_0 && keyCode <= GLFW.GLFW_KEY_9) { - return shift - ? ")!@#$%^&*(".charAt(keyCode - GLFW.GLFW_KEY_0) - : (char) ('0' + (keyCode - GLFW.GLFW_KEY_0)); - } - - // Special characters - return switch (keyCode) { - case GLFW.GLFW_KEY_SPACE -> ' '; - case GLFW.GLFW_KEY_PERIOD -> shift ? '>' : '.'; - case GLFW.GLFW_KEY_COMMA -> shift ? '<' : ','; - case GLFW.GLFW_KEY_MINUS -> shift ? '_' : '-'; - case GLFW.GLFW_KEY_EQUAL -> shift ? '+' : '='; - case GLFW.GLFW_KEY_SEMICOLON -> shift ? ':' : ';'; - case GLFW.GLFW_KEY_APOSTROPHE -> shift ? '"' : '\''; - case GLFW.GLFW_KEY_SLASH -> shift ? '?' : '/'; - case GLFW.GLFW_KEY_BACKSLASH -> shift ? '|' : '\\'; - case GLFW.GLFW_KEY_LEFT_BRACKET -> shift ? '{' : '['; - case GLFW.GLFW_KEY_RIGHT_BRACKET -> shift ? '}' : ']'; - case GLFW.GLFW_KEY_GRAVE_ACCENT -> shift ? '~' : '`'; - default -> '\0'; - }; - } - - public void saturnTick() { - synchronized (scheduler) { - if (f < 15.0f) { - f += 0.25f; - } - } - synchronized (widgets) { - for (SaturnWidget widget : widgets) { - if (widget.visible && widget.animations != null) { - for (SaturnAnimation animation : widget.animations) { - if (animation != null && - tick - animation.lastTick == animation.delay) { - if (animation.run(widget, tick)) { - animation = null; - } else { - animation.lastTick = tick; - } - } - } - } - - widget.tick(); - } - tick++; - } - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - super.resize(client, width, height); - refresh(); - } -} diff --git a/src/main/java/org/saturnclient/ui/SaturnWidget.java b/src/main/java/org/saturnclient/ui/SaturnWidget.java deleted file mode 100644 index 1d248f9..0000000 --- a/src/main/java/org/saturnclient/ui/SaturnWidget.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.saturnclient.ui; - -import net.minecraft.client.gui.DrawContext; - -public class SaturnWidget { - - public int x = 0; - public int y = 0; - public int width = 0; - public int height = 0; - public float alpha = 1.0f; - public float scale = 1.0f; - public SaturnAnimation[] animations = null; - public boolean visible = true; - public boolean focused = false; - - public void init() { - } - - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - } - - public void click(int mouseX, int mouseY) { - } - - public void keyPressed(int keyCode, int scanCode, int modifiers) { - } - - public void charTyped(char typedChar) { - } - - public void tick() { - } - - public void mouseScrolled( - int mouseX, - int mouseY, - double horizontalAmount, - double verticalAmount) { - } - - public SaturnWidget setX(int x) { - this.x = x; - return this; - } - - public SaturnWidget setY(int y) { - this.y = y; - return this; - } - - public SaturnWidget setWidth(int width) { - this.width = width; - return this; - } - - public SaturnWidget setHeight(int height) { - this.height = height; - return this; - } - - public SaturnWidget setAlpha(float alpha) { - this.alpha = alpha; - return this; - } - - public SaturnWidget setAnimations(SaturnAnimation... animations) { - this.animations = animations; - for (SaturnAnimation anim : this.animations) { - anim.init(this); - } - return this; - } - - public SaturnWidget setVisible(boolean visible) { - this.visible = visible; - return this; - } - - public SaturnWidget setScale(float scale) { - this.scale = scale; - return this; - } -} diff --git a/src/main/java/org/saturnclient/ui/animations/FadeIn.java b/src/main/java/org/saturnclient/ui/animations/FadeIn.java deleted file mode 100644 index a7c0b62..0000000 --- a/src/main/java/org/saturnclient/ui/animations/FadeIn.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.saturnclient.ui.animations; - -import org.saturnclient.ui.SaturnAnimation; -import org.saturnclient.ui.SaturnWidget; - -public class FadeIn extends SaturnAnimation { - public FadeIn(int delay) { - this.delay = delay; - } - - public void init(SaturnWidget widget) { - widget.alpha = 0.0f; - } - - public boolean run(SaturnWidget widget, int tick) { - widget.alpha += 0.05f; - - return widget.alpha > 0.9f; - } -} diff --git a/src/main/java/org/saturnclient/ui/animations/Slide.java b/src/main/java/org/saturnclient/ui/animations/Slide.java deleted file mode 100644 index ceb6b85..0000000 --- a/src/main/java/org/saturnclient/ui/animations/Slide.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.ui.animations; - -import org.saturnclient.ui.SaturnAnimation; -import org.saturnclient.ui.SaturnWidget; - -public class Slide extends SaturnAnimation { - private int offset; - - public Slide(int delay, int offset) { - this.delay = delay; - this.offset = offset; - } - - public void init(SaturnWidget widget) { - widget.y += offset; - } - - public boolean run(SaturnWidget widget, int tick) { - widget.y--; - offset--; - - return offset == 0; - } -} diff --git a/src/main/java/org/saturnclient/ui/components/SaturnFloat.java b/src/main/java/org/saturnclient/ui/components/SaturnFloat.java deleted file mode 100644 index e89ddee..0000000 --- a/src/main/java/org/saturnclient/ui/components/SaturnFloat.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.saturnclient.ui.components; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import org.lwjgl.glfw.GLFW; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -public class SaturnFloat extends SaturnWidget { - - String text = ""; - public Property prop; - public int cursorPosition = 0; - private TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - - public SaturnFloat(Property prop, int x, int y, int width) { - this.x = x; - this.y = y; - this.width = width; - this.prop = prop; - this.text = String.valueOf(prop.value); - this.height = textRenderer.fontHeight + 4; - this.scale = 0.8f; - } - - @Override - public void click(int mouseX, int mouseY) { - int scrollOffset = getScrollOffset(); - String visibleText = text.substring(scrollOffset); - - int newCursorPos = scrollOffset; - int textWidth = 0; - - for (int i = 0; i < visibleText.length(); i++) { - textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1)); - - if (textWidth > mouseX) { - break; - } - - newCursorPos++; - } - - cursorPosition = newCursorPos; - } - - @Override - public void charTyped(char chr) { - if ((Character.isDigit(chr) || chr == '.') && text.length() < 10) { - if (text.equals("0") && cursorPosition == 1) { - text = "" + chr; - } else { - text = text.substring(0, cursorPosition) + - chr + - text.substring(cursorPosition); - - prop.value = text.isEmpty() ? 0 : Float.parseFloat(text); - ConfigManager.save(); - - cursorPosition++; - } - } - } - - @Override - public void keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (cursorPosition > 0) { - text = text.substring(0, cursorPosition - 1) + - text.substring(cursorPosition); - cursorPosition--; - if (text.length() == 0) { - text = "0"; - cursorPosition = 1; - } - prop.value = Float.parseFloat(text); - ConfigManager.save(); - } - } else if (keyCode == GLFW.GLFW_KEY_LEFT) { - if (cursorPosition > 0) { - cursorPosition--; - } - } else if (keyCode == GLFW.GLFW_KEY_RIGHT) { - if (cursorPosition < text.length()) { - cursorPosition++; - } - } - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - if (prop.isReset) { - this.text = String.valueOf(prop.value); - this.cursorPosition = 0; - prop.isReset = false; - } - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON_BORDER, - 0, - 0, - this.width, - this.height, - focused - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha)); - - int scrollOffset = getScrollOffset(); - String visibleText = getVisibleText(scrollOffset); - - int textColor = focused ? 0xFFFFFF : 0xAAAAAA; - context.drawText( - textRenderer, - SaturnUi.text(visibleText), - 2, - 2, - textColor, - false); - - if (focused) { - int cursorX = 2 + - textRenderer.getWidth( - SaturnUi.text( - visibleText.substring(0, cursorPosition - scrollOffset))); - context.fill( - cursorX, - 2, - cursorX + 1, - textRenderer.fontHeight + 4, - 0xFFFFFFFF); - } - } - - public void clearText() { - text = "0"; - cursorPosition = 1; - prop.value = 0.0f; - } - - private int getScrollOffset() { - if (text.isEmpty()) { - return 0; - } - - int offset = 0; - int maxWidth = width - 4; // Available width for text - while (offset < cursorPosition) { // Ensure cursor remains visible - String visibleText = text.substring(offset, cursorPosition); - if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) { - offset++; - } else { - break; - } - } - return offset; - } - - private String getVisibleText(int scrollOffset) { - String visibleText = text.substring(scrollOffset); - - // Ensure text does not overflow past the available width - for (int i = 1; i <= visibleText.length(); i++) { - if (textRenderer.getWidth( - SaturnUi.text(visibleText.substring(0, i))) > width - 4) { - return visibleText.substring(0, i - 1); // Trim overflow - } - } - return visibleText; - } -} diff --git a/src/main/java/org/saturnclient/ui/components/SaturnHex.java b/src/main/java/org/saturnclient/ui/components/SaturnHex.java deleted file mode 100644 index c7f9cfc..0000000 --- a/src/main/java/org/saturnclient/ui/components/SaturnHex.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.saturnclient.ui.components; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import org.lwjgl.glfw.GLFW; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -public class SaturnHex extends SaturnWidget { - - private String text = "#"; // Always starts with '#' - public Property prop; - public int cursorPosition = 1; // After '#' - private final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - - public SaturnHex(Property prop, int x, int y, int width) { - this.x = x; - this.y = y; - this.width = width; - this.prop = prop; - this.text = intToHex(prop.value); - this.height = textRenderer.fontHeight + 4; - this.scale = 0.8f; - } - - @Override - public void click(int mouseX, int mouseY) { - cursorPosition = Math.min(7, text.length()); // Keep cursor inside hex length - } - - @Override - public void charTyped(char chr) { - if (isHexChar(chr) && text.length() < 7) { // Limit to 6 hex digits + '#' - text = text.substring(0, cursorPosition) + - chr + - text.substring(cursorPosition); - cursorPosition++; - - if (text.length() == 7) { // Only update value when full hex is entered - prop.value = hexToInt(text); - ConfigManager.save(); - } - } - } - - @Override - public void keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE && cursorPosition > 1) { // Prevent deleting '#' - text = text.substring(0, cursorPosition - 1) + - text.substring(cursorPosition); - cursorPosition--; - } else if (keyCode == GLFW.GLFW_KEY_LEFT && cursorPosition > 1) { - cursorPosition--; - } else if (keyCode == GLFW.GLFW_KEY_RIGHT && cursorPosition < text.length()) { - cursorPosition++; - } - - if (text.length() == 1) { // Reset if empty (keep '#') - text = "#"; - cursorPosition = 1; - } - - if (text.length() == 7) { // Update only when valid hex - prop.value = hexToInt(text); - ConfigManager.save(); - } - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - if (prop.isReset) { - this.text = intToHex(prop.value); - this.cursorPosition = 0; - prop.isReset = false; - } - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON_BORDER, - 0, - 0, - this.width, - this.height, - focused - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha)); - - int textColor = focused ? 0xFFFFFF : 0xAAAAAA; - context.drawText( - textRenderer, - SaturnUi.text(text), - 2, - 2, - textColor, - false); - - if (focused) { - int cursorX = 2 + - textRenderer.getWidth( - SaturnUi.text(text.substring(0, cursorPosition))); - context.fill( - cursorX, - 2, - cursorX + 1, - textRenderer.fontHeight + 4, - 0xFFFFFFFF); - } - } - - public void clearText() { - text = "#"; - cursorPosition = 1; - prop.value = 0xFFFFFFFF; // Default white - } - - private boolean isHexChar(char chr) { - return ((chr >= '0' && chr <= '9') || - (chr >= 'A' && chr <= 'F') || - (chr >= 'a' && chr <= 'f')); - } - - public static int hexToInt(String hex) { - hex = hex.replace("#", ""); - int rgb = Integer.parseInt(hex, 16); - return (0xFF << 24) | rgb; - } - - public static String intToHex(int color) { - int rgb = color & 0xFFFFFF; - return String.format("#%06X", rgb).toLowerCase(); - } -} diff --git a/src/main/java/org/saturnclient/ui/components/SaturnInteger.java b/src/main/java/org/saturnclient/ui/components/SaturnInteger.java deleted file mode 100644 index cb9ab6d..0000000 --- a/src/main/java/org/saturnclient/ui/components/SaturnInteger.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.saturnclient.ui.components; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import org.lwjgl.glfw.GLFW; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -public class SaturnInteger extends SaturnWidget { - - String text = ""; - public Property prop; - public int cursorPosition = 0; - private TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - - public SaturnInteger(Property prop, int x, int y, int width) { - this.x = x; - this.y = y; - this.width = width; - this.prop = prop; - this.text = String.valueOf(prop.value); - this.height = textRenderer.fontHeight + 4; - this.scale = 0.8f; - } - - @Override - public void click(int mouseX, int mouseY) { - int scrollOffset = getScrollOffset(); - String visibleText = text.substring(scrollOffset); - - int newCursorPos = scrollOffset; - int textWidth = 0; - - for (int i = 0; i < visibleText.length(); i++) { - textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1)); - - if (textWidth > mouseX) { - break; - } - - newCursorPos++; - } - - cursorPosition = newCursorPos; - } - - @Override - public void charTyped(char chr) { - if (Character.isDigit(chr) && text.length() < 10) { - if (text.equals("0") && cursorPosition == 1) { - text = "" + chr; - } else { - text = text.substring(0, cursorPosition) + - chr + - text.substring(cursorPosition); - - prop.value = text.isEmpty() ? 0 : Integer.parseInt(text); - ConfigManager.save(); - - cursorPosition++; - } - } - } - - @Override - public void keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (cursorPosition > 0) { - text = text.substring(0, cursorPosition - 1) + - text.substring(cursorPosition); - cursorPosition--; - if (text.length() == 0) { - text = "0"; - cursorPosition = 1; - } - prop.value = Integer.parseInt(text); - ConfigManager.save(); - } - } else if (keyCode == GLFW.GLFW_KEY_LEFT) { - if (cursorPosition > 0) { - cursorPosition--; - } - } else if (keyCode == GLFW.GLFW_KEY_RIGHT) { - if (cursorPosition < text.length()) { - cursorPosition++; - } - } - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - if (prop.isReset) { - this.text = String.valueOf(prop.value); - this.cursorPosition = 0; - prop.isReset = false; - } - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON_BORDER, - 0, - 0, - this.width, - this.height, - focused - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha)); - - int scrollOffset = getScrollOffset(); - String visibleText = getVisibleText(scrollOffset); - - int textColor = focused ? 0xFFFFFF : 0xAAAAAA; - context.drawText( - textRenderer, - SaturnUi.text(visibleText), - 2, - 2, - textColor, - false); - - if (focused) { - int cursorX = 2 + - textRenderer.getWidth( - SaturnUi.text( - visibleText.substring(0, cursorPosition - scrollOffset))); - context.fill( - cursorX, - 2, - cursorX + 1, - textRenderer.fontHeight + 4, - 0xFFFFFFFF); - } - } - - public void clearText() { - text = "0"; - cursorPosition = 1; - prop.value = 0; - } - - private int getScrollOffset() { - if (text.isEmpty()) { - return 0; - } - - int offset = 0; - int maxWidth = width - 4; // Available width for text - while (offset < cursorPosition) { // Ensure cursor remains visible - String visibleText = text.substring(offset, cursorPosition); - if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) { - offset++; - } else { - break; - } - } - return offset; - } - - private String getVisibleText(int scrollOffset) { - String visibleText = text.substring(scrollOffset); - - // Ensure text does not overflow past the available width - for (int i = 1; i <= visibleText.length(); i++) { - if (textRenderer.getWidth( - SaturnUi.text(visibleText.substring(0, i))) > width - 4) { - return visibleText.substring(0, i - 1); // Trim overflow - } - } - return visibleText; - } -} diff --git a/src/main/java/org/saturnclient/ui/components/SaturnModComp.java b/src/main/java/org/saturnclient/ui/components/SaturnModComp.java deleted file mode 100644 index 73a92f6..0000000 --- a/src/main/java/org/saturnclient/ui/components/SaturnModComp.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.saturnclient.ui.components; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.menus.ConfigEditor; -import org.saturnclient.saturnmods.SaturnMod; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -public class SaturnModComp extends SaturnWidget { - - SaturnMod mod; - - public SaturnModComp(SaturnMod mod) { - this.mod = mod; - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - boolean enabled = mod.isEnabled(); - - boolean hovering_settings = settingsHovering(mouseX, mouseY); - - int color = !hovering_settings && (enabled || hovering) - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(alpha); - - int size = 12; - - if (enabled) { - SaturnUi.drawHighResTexture( - context, - Textures.MOD_BG, - 0, - 0, - 86, - 20, - SaturnClientConfig.color.value); - } - - SaturnUi.drawHighResTexture( - context, - Textures.MOD, - 0, - 0, - 86, - 20, - color); - - SaturnUi.drawHighResTexture( - context, - mod.getIconTexture(), - 4, - 4, - size, - size, - color); - - context.drawText( - SaturnClientConfig.textRenderer, - SaturnUi.text(mod.getName()), - 20, - (21 - SaturnClientConfig.textRenderer.fontHeight) / 2, - color, - false); - - SaturnUi.drawHighResTexture( - context, - Textures.SETTINGS, - 77, - 11, - 7, - 7, - hovering_settings - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(alpha)); - } - - @Override - public void click(int mouseX, int mouseY) { - if (settingsHovering(mouseX, mouseY)) { - MinecraftClient.getInstance() - .setScreen(new ConfigEditor(mod.getConfig())); - } else { - mod.setEnabled(!mod.isEnabled()); - } - } - - public boolean settingsHovering(int mouseX, int mouseY) { - int sX = 77; - int sY = 11; - int size = 7; - - return (sX < mouseX && - sX + size > mouseX && - sY < mouseY && - sY + size > mouseY); - } -} diff --git a/src/main/java/org/saturnclient/ui/components/SaturnString.java b/src/main/java/org/saturnclient/ui/components/SaturnString.java deleted file mode 100644 index c8f7c59..0000000 --- a/src/main/java/org/saturnclient/ui/components/SaturnString.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.saturnclient.ui.components; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import org.lwjgl.glfw.GLFW; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -public class SaturnString extends SaturnWidget { - - public Property prop; - public int cursorPosition = 0; - private TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - - public SaturnString(Property prop, int x, int y, int width) { - this.x = x; - this.y = y; - this.width = width; - this.prop = prop; - this.height = textRenderer.fontHeight + 4; - this.scale = 0.8f; - } - - @Override - public void click(int mouseX, int mouseY) { - int scrollOffset = getScrollOffset(); - String visibleText = prop.value.substring(scrollOffset); - - int newCursorPos = scrollOffset; - int textWidth = 0; - - for (int i = 0; i < visibleText.length(); i++) { - textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1)); - - if (textWidth > mouseX) { - break; - } - - newCursorPos++; - } - - cursorPosition = newCursorPos; - } - - @Override - public void charTyped(char chr) { - prop.value = prop.value.substring(0, cursorPosition) + - chr + - prop.value.substring(cursorPosition); - - cursorPosition++; - } - - @Override - public void keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (cursorPosition > 0) { - prop.value = prop.value.substring(0, cursorPosition - 1) + - prop.value.substring(cursorPosition); - cursorPosition--; - } - } else if (keyCode == GLFW.GLFW_KEY_LEFT) { - if (cursorPosition > 0) { - cursorPosition--; - } - } else if (keyCode == GLFW.GLFW_KEY_RIGHT) { - if (cursorPosition < prop.value.length()) { - cursorPosition++; - } - } - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON_BORDER, - 0, - 0, - this.width, - this.height, - focused - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha)); - - int scrollOffset = getScrollOffset(); - String visibleText = getVisibleText(scrollOffset); - - int textColor = focused ? 0xFFFFFF : 0xAAAAAA; - context.drawText( - textRenderer, - SaturnUi.text(visibleText), - 2, - 2, - textColor, - false); - - if (focused) { - int cursorX = 2 + - textRenderer.getWidth( - SaturnUi.text( - visibleText.substring(0, cursorPosition - scrollOffset))); - context.fill( - cursorX, - 2, - cursorX + 1, - textRenderer.fontHeight + 3, - 0xFFFFFFFF); - } - } - - public void clearText() { - prop.value = ""; - cursorPosition = 1; - } - - private int getScrollOffset() { - if (prop.value.isEmpty()) { - return 0; - } - - int offset = 0; - int maxWidth = width - 4; // Available width for prop.value - while (offset < cursorPosition) { // Ensure cursor remains visible - String visibleText = prop.value.substring(offset, cursorPosition); - if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) { - offset++; - } else { - break; - } - } - return offset; - } - - private String getVisibleText(int scrollOffset) { - String visibleText = prop.value.substring(scrollOffset); - - // Ensure prop.value does not overflow past the available width - for (int i = 1; i <= visibleText.length(); i++) { - if (textRenderer.getWidth( - SaturnUi.text(visibleText.substring(0, i))) > width - 4) { - return visibleText.substring(0, i - 1); // Trim overflow - } - } - return visibleText; - } -} diff --git a/src/main/java/org/saturnclient/ui/components/SaturnToggle.java b/src/main/java/org/saturnclient/ui/components/SaturnToggle.java deleted file mode 100644 index 3bf248d..0000000 --- a/src/main/java/org/saturnclient/ui/components/SaturnToggle.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.saturnclient.ui.components; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.RenderLayer; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.ConfigManager; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -public class SaturnToggle extends SaturnWidget { - - Property prop; - - public SaturnToggle(Property prop) { - this.prop = prop; - width = 16; - height = 8; - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - int color = prop.value - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(alpha); - int w = 13; - int h = 6; - int s = 8; - - context.drawTexture( - RenderLayer::getGuiTextured, - Textures.TOGGLE_BG, - 0, - 1, - 0, - 0, - w, - h, - w, - h, - color); - - context.drawTexture( - RenderLayer::getGuiTextured, - Textures.TOGGLE_INDICATOR, - prop.value ? 5 : 0, - 0, - 0, - 0, - s, - s, - s, - s, - color); - } - - @Override - public void click(int mouseX, int mouseY) { - prop.value = !prop.value; - ConfigManager.save(); - } -} diff --git a/src/main/java/org/saturnclient/ui/components/SkinPreview.java b/src/main/java/org/saturnclient/ui/components/SkinPreview.java deleted file mode 100644 index c635795..0000000 --- a/src/main/java/org/saturnclient/ui/components/SkinPreview.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.ui.components; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.ui.SaturnWidget; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.entity.LivingEntity; - -// If you think this code is bad, it's because it's written by Mojang - -public class SkinPreview extends SaturnWidget { - public static void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, int size, float f, float mouseX, - float mouseY, LivingEntity entity, float angle, boolean negativeAngle) { - float g = (float) (x1 + x2) / 2.0F; - float h = (float) (y1 + y2) / 2.0F; - context.enableScissor(0, 6, x2, y2); - float i = (float) Math.atan((double) ((g - mouseX) / 40.0F)); - float j = (float) Math.atan((double) ((h - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F); - float k = entity.bodyYaw; - float l = entity.getYaw(); - float m = entity.getPitch(); - float n = entity.prevHeadYaw; - float o = entity.headYaw; - entity.setYaw(angle); - entity.bodyYaw = angle; - entity.setPitch(-j * 20.0F); - entity.headYaw = negativeAngle ? -i * 40.0F : i * 40.0F; - entity.prevHeadYaw = entity.getHeadYaw(); - entity.setCustomNameVisible(false); - - float p = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F); - float q = (float) size / p; - drawEntity(context, g, h, q, vector3f, quaternionf, null, entity); - - entity.setCustomNameVisible(true); - entity.bodyYaw = k; - entity.setYaw(l); - entity.setPitch(m); - entity.prevHeadYaw = n; - entity.headYaw = o; - context.disableScissor(); - } - - public static void drawEntity(DrawContext context, float x, float y, float size, Vector3f vector3f, - Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { - context.getMatrices().push(); - context.getMatrices().translate((double) x, (double) y, 50.0); - context.getMatrices().scale(size, size, -size); - context.getMatrices().translate(vector3f.x, vector3f.y, vector3f.z); - context.getMatrices().multiply(quaternionf); - context.draw(); - DiffuseLighting.method_34742(); - EntityRenderDispatcher entityRenderDispatcher = MinecraftClient.getInstance().getEntityRenderDispatcher(); - - entityRenderDispatcher.setRenderShadows(false); - context.draw((vertexConsumers) -> { - entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, context.getMatrices(), vertexConsumers, - 15728880); - }); - context.draw(); - entityRenderDispatcher.setRenderShadows(true); - context.getMatrices().pop(); - DiffuseLighting.enableGuiDepthLighting(); - } - - @Override - public void render(DrawContext context, boolean hovering, int mouseX, int mouseY) { - LivingEntity entity = MinecraftClient.getInstance().player; - if (entity != null) { - drawEntity(context, 0, 0, 75, 78, 30, 0.0625F, mouseX, mouseY, entity, -30.0f, true); - } - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnButton.java b/src/main/java/org/saturnclient/ui/widgets/SaturnButton.java deleted file mode 100644 index 320d872..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnButton.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.saturnclient.ui.widgets; - -import com.mojang.blaze3d.systems.RenderSystem; -import java.util.function.Consumer; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.text.Text; - -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -public class SaturnButton extends SaturnWidget { - - public boolean active = true; - public String text; - public Consumer onPress; - public boolean background = true; - public boolean bold = false; - private float hoverAlpha = 0.0f; - - public SaturnButton(String text, Consumer onPress) { - this.text = text; - this.onPress = onPress; - } - - public SaturnButton(String text, Runnable onPress) { - this(text, b -> { - onPress.run(); - }); - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - MinecraftClient minecraftClient = MinecraftClient.getInstance(); - - if (background) { - RenderSystem.setShaderTexture(0, Textures.BUTTON); - - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON, - 0, - 0, - this.width, - this.height, - SaturnClientConfig.getColor(hovering, alpha)); - - if (hovering) { - if (hoverAlpha == 0.0f) - hoverAlpha = 0.1f; - - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON_BORDER, - 0, - 0, - this.width, - this.height, - SaturnClientConfig.getColor(hovering, alpha)); - } else { - hoverAlpha = 0.0f; - } - } - - if (alpha != 0.0f) { - Text t = bold ? SaturnUi.textBold(text) : SaturnUi.text(text); - context.drawText( - minecraftClient.textRenderer, - t, - ((this.width - - minecraftClient.textRenderer.getWidth(t)) - / - 2), - ((this.height - minecraftClient.textRenderer.fontHeight + 1) / - 2), - SaturnClientConfig.getColor(hovering, alpha), - false); - } - } - - @Override - public void click(int mouseX, int mouseY) { - this.onPress.accept(this); - } - - @Override - public void tick() { - if (hoverAlpha > 0.0f && hoverAlpha < 0.9f) - hoverAlpha += 0.03f; - else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f) - hoverAlpha = 1.0f; - } - - public SaturnWidget setBold(boolean bold) { - this.bold = bold; - return this; - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnClickableImage.java b/src/main/java/org/saturnclient/ui/widgets/SaturnClickableImage.java deleted file mode 100644 index 7c59bc3..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnClickableImage.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.ui.widgets; - -import java.util.function.Consumer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; - -public class SaturnClickableImage extends SaturnWidget { - - public Identifier texture; - public boolean selected = false; - public Consumer onPress; - private float hoverAlpha = 0.0f; - - public SaturnClickableImage( - Identifier texture, - Consumer onPress) { - this.texture = texture; - this.onPress = onPress; - } - - public SaturnClickableImage(Identifier texture, Runnable onPress) { - this(texture, _o -> { - onPress.run(); - }); - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - if (hovering) { - if (hoverAlpha == 0.0f) - hoverAlpha = 0.1f; - } - - SaturnUi.drawHighResTexture( - context, - texture, - 0, - 0, - width, - height, - SaturnClientConfig.getColor(hovering || selected, alpha)); - } - - @Override - public void click(int mouseX, int mouseY) { - this.onPress.accept(this); - } - - public SaturnClickableImage setSelected(boolean selected) { - this.selected = selected; - return this; - } - - @Override - public void tick() { - if (hoverAlpha > 0.0f && hoverAlpha < 0.9f) - hoverAlpha += 0.03f; - else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f) - hoverAlpha = 1.0f; - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnClickableSprite.java b/src/main/java/org/saturnclient/ui/widgets/SaturnClickableSprite.java deleted file mode 100644 index 8541cca..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnClickableSprite.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.saturnclient.ui.widgets; - -import java.util.function.Consumer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; - -public class SaturnClickableSprite extends SaturnWidget { - - public Identifier sprite; - public boolean selected = false; - public Consumer onPress; - - public SaturnClickableSprite( - Identifier sprite, - Consumer onPress) { - this.sprite = sprite; - this.onPress = onPress; - } - - public SaturnClickableSprite(Identifier sprite, Runnable onPress) { - this(sprite, _o -> { - onPress.run(); - }); - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - SaturnUi.drawHighResGuiTexture( - context, - sprite, - 0, - 0, - this.width, - this.height, - SaturnClientConfig.getColor(hovering, alpha)); - } - - @Override - public void click(int mouseX, int mouseY) { - this.onPress.accept(this); - } - - public SaturnClickableSprite setSelected(boolean selected) { - this.selected = selected; - return this; - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnImage.java b/src/main/java/org/saturnclient/ui/widgets/SaturnImage.java deleted file mode 100644 index b86eafe..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnImage.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.saturnclient.ui.widgets; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.ColorHelper; - -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; - -public class SaturnImage extends SaturnWidget { - - private final Identifier sprite; - - public SaturnImage(Identifier sprite) { - this.sprite = sprite; - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - SaturnUi.drawHighResTexture( - context, - sprite, - 0, - 0, - width, - height, - ColorHelper.getWhite(alpha)); - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnImageButton.java b/src/main/java/org/saturnclient/ui/widgets/SaturnImageButton.java deleted file mode 100644 index 7fb60a5..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnImageButton.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.saturnclient.ui.widgets; - -import java.util.function.Consumer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.util.Identifier; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; -import org.saturnclient.ui.Textures; - -import com.mojang.blaze3d.systems.RenderSystem; - -public class SaturnImageButton extends SaturnWidget { - - public Identifier sprite; - public int imageWidth; - public int imageHeight; - public Consumer onPress; - private float hoverAlpha = 0.0f; - - public SaturnImageButton( - Identifier sprite, - int imageWidth, - int imageHeight, - Consumer onPress) { - this.sprite = sprite; - this.imageWidth = imageWidth; - this.imageHeight = imageHeight; - this.onPress = onPress; - } - - public SaturnImageButton( - Identifier sprite, - int imageWidth, - int imageHeight, - Runnable onPress) { - this(sprite, imageWidth, imageHeight, _o -> { - onPress.run(); - }); - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - if (hovering) { - if (hoverAlpha == 0.0f) - hoverAlpha = 0.1f; - } - RenderSystem.setShaderTexture(0, Textures.BUTTON); - - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON, - 0, - 0, - this.width, - this.height, - SaturnClientConfig.getColor(hovering, alpha)); - - if (hovering) { - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON_BORDER, - 0, - 0, - this.width, - this.height, - SaturnClientConfig.getColor(hovering, alpha)); - } - - context.drawTexture( - RenderLayer::getGuiTextured, - sprite, - ((width - imageWidth) / 2), - ((height - imageHeight) / 2), - 0, - 0, - imageWidth, - imageHeight, - imageWidth, - imageHeight, - SaturnClientConfig.getColor(hovering, alpha)); - } - - @Override - public void click(int mouseX, int mouseY) { - this.onPress.accept(this); - } - - @Override - public void tick() { - if (hoverAlpha > 0.0f && hoverAlpha < 0.9f) - hoverAlpha += 0.03f; - else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f) - hoverAlpha = 1.0f; - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnInputBox.java b/src/main/java/org/saturnclient/ui/widgets/SaturnInputBox.java deleted file mode 100644 index 6ca2861..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnInputBox.java +++ /dev/null @@ -1,230 +0,0 @@ -package org.saturnclient.ui.widgets; - -import org.saturnclient.ui.SaturnWidget; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.util.math.MatrixStack; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.config.Property; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.Textures; - -public class SaturnInputBox extends SaturnWidget { - - private TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - private int tick = 0; - private boolean cursorVisible = true; - - public Property prop; - public int cursorPosition = 0; - public Runnable onUpdate; - - public SaturnInputBox(Property prop, int x, int y, int width) { - this.x = x; - this.y = y; - this.width = width; - this.prop = prop; - this.height = textRenderer.fontHeight + 4; - this.scale = 1.0f; - } - - @Override - public void click(int mouseX, int mouseY) { - int scrollOffset = getScrollOffset(); - String visibleText = prop.value.substring(scrollOffset); - - int newCursorPos = scrollOffset; - int textWidth = 0; - - for (int i = 0; i < visibleText.length(); i++) { - textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1)); - - if (textWidth > mouseX) { - break; - } - - newCursorPos++; - } - - cursorPosition = newCursorPos; - } - - @Override - public void charTyped(char chr) { - prop.value = prop.value.substring(0, cursorPosition) + - chr + - prop.value.substring(cursorPosition); - - cursorPosition++; - - onUpdate.run(); - } - - @Override - public void keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (cursorPosition > 0) { - prop.value = prop.value.substring(0, cursorPosition - 1) + - prop.value.substring(cursorPosition); - cursorPosition--; - } - onUpdate.run(); - } else if (keyCode == GLFW.GLFW_KEY_LEFT) { - if (cursorPosition > 0) { - cursorPosition--; - } - } else if (keyCode == GLFW.GLFW_KEY_RIGHT) { - if (cursorPosition < prop.value.length()) { - cursorPosition++; - } - } - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON, - 0, - 0, - this.width, - this.height, - focused - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha)); - - if (hovering || focused) { - SaturnUi.drawHighResGuiTexture( - context, - Textures.BUTTON_BORDER, - 0, - 0, - this.width, - this.height, - hovering - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha)); - } - - MatrixStack matrices = context.getMatrices(); - matrices.push(); - - if (prop.value.isEmpty() && !focused) { - SaturnUi.drawHighResTexture( - context, - Textures.SEARCH, - 3, - 3, - 9, - 9, - hovering - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha)); - - matrices.scale(0.9f, 0.9f, 1.0f); - - context.drawText( - textRenderer, - SaturnUi.text("Search"), - 14, - textRenderer.fontHeight / 2 + 1, - hovering - ? SaturnClientConfig.color.value - : SaturnClientConfig.getWhite(this.alpha), - false); - } - - matrices.pop(); - - matrices.push(); - - matrices.scale(0.9f, 0.9f, 1.0f); - - int scrollOffset = getScrollOffset(); - String visibleText = getVisibleText(scrollOffset); - int textColor = focused ? 0xFFFFFF : 0xAAAAAA; - context.drawText( - textRenderer, - SaturnUi.text(visibleText), - 3, - textRenderer.fontHeight / 2, - textColor, - false); - - if (focused && cursorVisible) { - int cursorX = 2 + - textRenderer.getWidth( - SaturnUi.text( - visibleText.substring(0, cursorPosition - scrollOffset))); - matrices.translate(cursorX, 0, 0); - context.fill( - 1, - 2, - 2, - textRenderer.fontHeight + 3, - 0xFFFFFFFF); - } - - matrices.pop(); - } - - public void clearText() { - prop.value = ""; - cursorPosition = 1; - } - - private int getScrollOffset() { - if (prop.value.isEmpty()) { - return 0; - } - - int offset = 0; - int maxWidth = width - 4; // Available width for prop.value - while (offset < cursorPosition) { // Ensure cursor remains visible - String visibleText = prop.value.substring(offset, cursorPosition); - if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) { - offset++; - } else { - break; - } - } - return offset; - } - - private String getVisibleText(int scrollOffset) { - String visibleText = prop.value.substring(scrollOffset); - - // Ensure prop.value does not overflow past the available width - for (int i = 1; i <= visibleText.length(); i++) { - if (textRenderer.getWidth( - SaturnUi.text(visibleText.substring(0, i))) > width - 4) { - return visibleText.substring(0, i - 1); // Trim overflow - } - } - return visibleText; - } - - public SaturnInputBox onUpdate(Runnable onUpdate) { - this.onUpdate = onUpdate; - return this; - } - - @Override - public void tick() { - if (focused) { - if (tick < 45 || tick < 60 && cursorVisible) { - tick++; - } else { - tick = 0; - cursorVisible = !cursorVisible; - } - } - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnScroll.java b/src/main/java/org/saturnclient/ui/widgets/SaturnScroll.java deleted file mode 100644 index 3fdc8e5..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnScroll.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.saturnclient.ui.widgets; - -import java.util.ArrayList; -import java.util.List; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.util.math.MatrixStack; -import org.saturnclient.ui.SaturnWidget; - -public class SaturnScroll extends SaturnWidget { - - private int scroll = 0; - private int maxScroll = 0; - private List children = new ArrayList<>(); - - @Override - public void mouseScrolled( - int mouseX, - int mouseY, - double horizontalAmount, - double verticalAmount - ) { - verticalAmount *= 2; - - if (scroll - verticalAmount <= 0) { - scroll = 0; - } else if (scroll - verticalAmount >= maxScroll) { - scroll = maxScroll; - } else { - scroll -= verticalAmount; - } - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY - ) { - context.enableScissor(0, 0, width, height); - - for (SaturnWidget widget : children) { - if (!widget.visible) continue; - - double adjustedMouseX = (mouseX - widget.x); - double adjustedMouseY = (mouseY - widget.y + scroll); - boolean isMouseInside = - adjustedMouseX >= 0 && - adjustedMouseX <= (widget.width * widget.scale) && - adjustedMouseY >= 0 && - adjustedMouseY <= (widget.height * widget.scale); - - if ( - widget.y - scroll < height && widget.y + widget.height > scroll - ) { - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.translate(widget.x, widget.y - scroll, 0); - matrices.scale(widget.scale, widget.scale, 1.0f); - - widget.render( - context, - isMouseInside, - (int) (adjustedMouseX / widget.scale), - (int) (adjustedMouseY / widget.scale) - ); - matrices.pop(); - } - } - context.disableScissor(); - } - - @Override - public void init() { - maxScroll = 0; - for (SaturnWidget child : children) { - maxScroll = Math.max(maxScroll, child.y + child.height - height); - } - } - - public void draw(SaturnWidget widget) { - synchronized (children) { - widget.init(); - children.add(widget); - } - } - - public boolean isScrollable() { - for (SaturnWidget widget : children) { - if (widget.y + widget.height > height) { - return true; - } - } - return false; - } - - @Override - public void keyPressed(int keyCode, int scanCode, int modifiers) { - for (SaturnWidget widget : children) { - if (!widget.visible || !widget.focused) { - continue; - } - - widget.keyPressed(keyCode, scanCode, modifiers); - break; - } - } - - @Override - public void charTyped(char typedChar) { - for (SaturnWidget widget : children) { - if (!widget.visible || !widget.focused) { - continue; - } - - widget.charTyped(typedChar); - break; - } - } - - @Override - public void click(int mouseX, int mouseY) { - for (SaturnWidget widget : children) { - widget.focused = false; - if (!widget.visible) { - continue; - } - - double adjustedMouseX = (mouseX - widget.x); - double adjustedMouseY = (mouseY - (widget.y - scroll)); - boolean isMouseInside = - adjustedMouseX >= 0 && - adjustedMouseX <= (widget.width * widget.scale) && - adjustedMouseY >= 0 && - adjustedMouseY <= (widget.height * widget.scale); - - if (isMouseInside) { - widget.focused = true; - widget.click( - (int) (adjustedMouseX / widget.scale), - (int) (adjustedMouseY / widget.scale) - ); - } - } - } - - public void clear() { - children.clear(); - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnSprite.java b/src/main/java/org/saturnclient/ui/widgets/SaturnSprite.java deleted file mode 100644 index a5eebdc..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnSprite.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.saturnclient.ui.widgets; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.ColorHelper; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; - -public class SaturnSprite extends SaturnWidget { - - private final Identifier sprite; - - public SaturnSprite(Identifier sprite) { - this.sprite = sprite; - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - SaturnUi.drawHighResGuiTexture( - context, - sprite, - 0, - 0, - this.width, - this.height, - ColorHelper.getWhite(this.alpha)); - } -} diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnText.java b/src/main/java/org/saturnclient/ui/widgets/SaturnText.java deleted file mode 100644 index 9171447..0000000 --- a/src/main/java/org/saturnclient/ui/widgets/SaturnText.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.ui.widgets; - -import net.minecraft.client.gui.DrawContext; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui.SaturnUi; -import org.saturnclient.ui.SaturnWidget; - -public class SaturnText extends SaturnWidget { - - private String text; - - public SaturnText(String text) { - this.text = text; - this.width = SaturnClientConfig.textRenderer.getWidth(SaturnUi.text(text)); - this.height = SaturnClientConfig.textRenderer.fontHeight; - } - - public SaturnText(String text, int color) { - this(text); - } - - @Override - public void render( - DrawContext context, - boolean hovering, - int mouseX, - int mouseY) { - context.drawText( - SaturnClientConfig.textRenderer, - SaturnUi.text(text), - 0, - 0, - SaturnClientConfig.getColor(hovering, alpha), - false); - } -} diff --git a/src/main/java/org/saturnclient/ui2/Element.java b/src/main/java/org/saturnclient/ui2/Element.java new file mode 100644 index 0000000..499a047 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/Element.java @@ -0,0 +1,82 @@ +package org.saturnclient.ui2; + +import java.util.function.Function; + +import org.saturnclient.ui2.anim.Animation; +import org.saturnclient.ui2.anim.Curve; + +public class Element { + public int x; + public int y; + public int width; + public int height; + public float opacity = 1.0f; + public boolean focused; + public Animation animation; + public float scale = 1.0f; + public Function curve = Curve::easeInOutCubic; + + public void render(RenderScope renderScope, ElementContext ctx) { + } + + public void click(int mouseX, int mouseY) { + } + + public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) { + } + + public void keyPressed(int keyCode, int scanCode, int modifiers) { + } + + public void charTyped(char typedChar) { + } + + public final Element dimensions(int width, int height) { + this.width = width; + this.height = height; + + return this; + } + + public final 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) { + this.x = (w - (int) (width * scale)) / 2 + offsetX; + this.y = offsetY; + + return this; + } + + public final 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) { + this.x = (w - (int) (width * scale)) / 2 + offsetX; + this.y = (h - (int) (height * scale)) / 2 + offsetY; + + return this; + } + + public final Element animation(Animation animation) { + this.animation = animation; + return this; + } + + public final Element animation(Animation animation, Function curve) { + this.animation = animation; + this.curve = curve; + return this; + } + + public Element scale(float scale) { + this.scale = scale; + return this; + } +} diff --git a/src/main/java/org/saturnclient/ui2/ElementContext.java b/src/main/java/org/saturnclient/ui2/ElementContext.java new file mode 100644 index 0000000..8f3f898 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/ElementContext.java @@ -0,0 +1,23 @@ +package org.saturnclient.ui2; + +public class ElementContext { + public int mouseX, mouseY; + public int elementWidth, elementHeight; + public float elementScale; + + public ElementContext(int mouseX, int mouseY, Element e) { + this.mouseX = mouseX - e.x; + this.mouseY = mouseY - e.y; + this.elementWidth = e.width; + this.elementHeight = e.height; + this.elementScale = e.scale; + } + + public boolean isHovering() { + return Utils.isHovering(mouseX, mouseY, elementWidth, elementHeight, elementScale); + } + + public boolean isHovering(int x, int y, int width, int height) { + return Utils.isHovering(mouseX - x, mouseY - y, width, height, elementScale); + } +} diff --git a/src/main/java/org/saturnclient/ui2/RenderScope.java b/src/main/java/org/saturnclient/ui2/RenderScope.java new file mode 100644 index 0000000..53285c7 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/RenderScope.java @@ -0,0 +1,279 @@ +package org.saturnclient.ui2; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; + +import org.jetbrains.annotations.Nullable; +import org.joml.Matrix4f; +import org.saturnclient.ui2.resources.Fonts; +import com.mojang.blaze3d.systems.RenderSystem; + +import org.saturnclient.saturnclient.SaturnClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.font.TextRenderer.TextLayerType; +import net.minecraft.client.gui.ScreenRect; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.util.Window; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.RotationAxis; + +public class RenderScope { + public MatrixStack matrices; + public VertexConsumerProvider.Immediate vertexConsumers; + private Function renderLayers; + private ScissorStack scissorStack = new ScissorStack(); + private int opacity = 255 << 24; + + public RenderScope(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) { + this.matrices = matrices; + this.vertexConsumers = vertexConsumers; + this.scissorStack = new ScissorStack(); + } + + public void setOpacity(float alpha) { + this.opacity = (int) (alpha * 255) << 24; + } + + public int getColor(int color) { + int originalAlpha = (color >>> 24) & 0xFF; + int newAlpha = (opacity >>> 24) & 0xFF; + int mixedAlpha = (originalAlpha * newAlpha) / 255; + return (mixedAlpha << 24) | (color & 0x00FFFFFF); + } + + public void setRenderLayer(Function renderLayers) { + this.renderLayers = renderLayers; + } + + public void drawRect(int x, int y, int width, int height, int color) { + color = getColor(color); + Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); + + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + + int i; + if (x1 < x2) { + i = x1; + x1 = x2; + x2 = i; + } + + if (y1 < y2) { + i = y1; + y1 = y2; + y2 = i; + } + + VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); + vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, 0).color(color); + vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, 0).color(color); + vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, 0).color(color); + vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color); + } + + public void drawText(String text, int x, int y, boolean bold, int color) { + drawText(1.0f, text, x, y, bold, color); + } + + public void drawText(float scale, String text, int x, int y, boolean bold, int color) { + 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(), + this.vertexConsumers, TextLayerType.NORMAL, 0, 15728880); + matrices.pop(); + i++; + } + } + + private void drawRoundedCorner(int width, int height, int radius, int color) { + int w = width * 20; + int h = height * 20; + + for (int y = 0; y < h; y++) { + int startX = 0; + + if (y < radius) { + double dy = radius - y - 0.5; + double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); + startX = radius - (int) dx; + } + + this.drawRect(startX, y, w - startX, 1, color); + } + } + + private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { + // Top + this.matrices.push(); + + this.matrices.scale(0.05f, 0.05f, 1.0f); + + this.drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); + + this.matrices.pop(); + + // Bottom + this.matrices.push(); + + this.matrices.translate(cornerWidth, cornerHeight * 2, 0); + + this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90)); + + this.matrices.translate(0, -cornerWidth, 0); + + this.matrices.scale(0.05f, 0.05f, 1.0f); + + this.drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); + + this.matrices.pop(); + } + + public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { + radius = Math.min(radius, Math.min(width, height)); + int cornerWidth = width / 2; + int cornerHeight = height / 2; + + this.matrices.push(); + + this.matrices.translate(x, y, 0); + + this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); + + this.matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); + + this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180)); + + this.matrices.translate(0, 0, 0); + + this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); + + this.matrices.pop(); + } + + public int getScaledWindowWidth() { + return SaturnClient.client.getWindow().getScaledWidth(); + } + + public int getScaledWindowHeight() { + return SaturnClient.client.getWindow().getScaledHeight(); + } + public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int color) { + this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); + } + + public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height) { + this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); + } + + public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWith, int regionHeight, int textureWidth, int textureHeight) { + this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1); + } + + public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { + this.drawTexturedQuad(sprite, x, x + width, y, y + height, (u + 0.0F) / (float)textureWidth, (u + (float)regionWidth) / (float)textureWidth, (v + 0.0F) / (float)textureHeight, (v + (float)regionHeight) / (float)textureHeight, color); + } + + private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, float v2, int color) { + x1 *= 4; + x2 *= 4; + y1 *= 4; + y2 *= 4; + color = getColor(color); + + matrices.push(); + matrices.scale(0.25f, 0.25f, 1.0f); + RenderSystem.setShaderTexture(0, sprite); + RenderLayer renderLayer = (RenderLayer)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(); + } + + public void enableScissor(int x1, int y1, int x2, int y2) { + ScreenRect screenRect = (new ScreenRect(x1, y1, x2 - x1, y2 - y1)).transform(this.matrices.peek().getPositionMatrix()); + this.setScissor(this.scissorStack.push(screenRect)); + } + + public void disableScissor() { + this.setScissor(this.scissorStack.pop()); + } + + public boolean scissorContains(int x, int y) { + return this.scissorStack.containsPoint(x, y); + } + + private void setScissor(@Nullable ScreenRect rect) { + this.draw(); + if (rect != null) { + Window window = SaturnClient.client.getWindow(); + int i = window.getFramebufferHeight(); + double d = window.getScaleFactor(); + double e = (double)rect.getLeft() * d; + double f = (double)i - (double)rect.getBottom() * d; + double g = (double)rect.width() * d; + double h = (double)rect.height() * d; + RenderSystem.enableScissor((int)e, (int)f, Math.max(0, (int)g), Math.max(0, (int)h)); + } else { + RenderSystem.disableScissor(); + } + + } + + public void draw() { + this.vertexConsumers.draw(); + } + + public void draw(Consumer drawer) { + drawer.accept(this.vertexConsumers); + this.vertexConsumers.draw(); + } + + static class ScissorStack { + private final Deque stack = new ArrayDeque<>(); + + public ScreenRect push(ScreenRect p_281812_) { + ScreenRect screenrectangle = this.stack.peekLast(); + if (screenrectangle != null) { + ScreenRect screenrectangle1 = Objects.requireNonNullElse(p_281812_.intersection(screenrectangle), ScreenRect.empty()); + this.stack.addLast(screenrectangle1); + return screenrectangle1; + } else { + this.stack.addLast(p_281812_); + return p_281812_; + } + } + + @Nullable + public ScreenRect pop() { + if (this.stack.isEmpty()) { + throw new IllegalStateException("Scissor stack underflow"); + } else { + this.stack.removeLast(); + return this.stack.peekLast(); + } + } + + public boolean containsPoint(int p_329411_, int p_333404_) { + return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_); + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/SaturnScreen.java b/src/main/java/org/saturnclient/ui2/SaturnScreen.java new file mode 100644 index 0000000..695ad62 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/SaturnScreen.java @@ -0,0 +1,141 @@ +package org.saturnclient.ui2; + +import java.util.ArrayList; +import java.util.List; + +import org.saturnclient.saturnclient.mixin.DrawContextAccessor; +import org.saturnclient.ui2.anim.Animation; +import org.saturnclient.ui2.components.ElementRenderer; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.PostEffectProcessor; +import net.minecraft.client.gui.CubeMapRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.RotatingCubeMapRenderer; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.render.DefaultFramebufferSet; +import net.minecraft.client.util.Pool; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +public abstract class SaturnScreen extends Screen { + private final Pool pool = new Pool(3); + protected List elements = new ArrayList<>(); + public int blurDuration = 700; + public float blurProgress = 0.0f; + public int backgroundBlur = 10; + + protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer( + Identifier.of("saturnclient", "textures/gui/title/background/panorama")); + + public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; + + static { + ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); + } + + public SaturnScreen(String title) { + super(Text.literal(title)); + } + + public void draw(Element element) { + synchronized (elements) { + elements.add(element); + } + + if (element.animation != null) { + element.animation.init(element); + + Animation.execute((Float progress) -> { + element.animation.tick(progress, element); + }, element.animation.duration); + } + } + + @Override + protected void init() { + elements.clear(); + width *= 2; + height *= 2; + ui(); // abstraction to render the saturn ui and also render extra stuff here + + Animation.execute((Float progress) -> { + blurProgress = progress; + }, blurDuration); + } + + public abstract void ui(); + + @SuppressWarnings("deprecation") + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + mouseX *= 2; + mouseY *= 2; + + if (client.world == null && client.getCurrentServerEntry() == null) { + ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta); + } + + PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect( + Identifier.ofVanilla("blur"), + DefaultFramebufferSet.MAIN_ONLY); + if (postEffectProcessor != null) { + postEffectProcessor.setUniforms("Radius", backgroundBlur * blurProgress); + postEffectProcessor.render(this.client.getFramebuffer(), this.pool); + } + + // We are using a Abstracted RenderScope because older minecraft versions don't + // use DrawContext + RenderScope renderScope = new RenderScope(context.getMatrices(), + ((DrawContextAccessor) context).getVertexConsumers()); + + renderScope.matrices.push(); + + renderScope.matrices.scale(0.5f, 0.5f, 0.5f); + + ElementRenderer.render(elements, renderScope, mouseX, mouseY); + + renderScope.matrices.pop(); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + mouseX *= 2; + mouseY *= 2; + + ElementRenderer.mouseClicked(elements, mouseX, mouseY, button); + + return false; + } + + @Override + public boolean mouseScrolled( + double mouseX, + double mouseY, + double horizontalAmount, + double verticalAmount) { + mouseX *= 2; + mouseY *= 2; + + ElementRenderer.mouseScrolled(elements, mouseX, mouseY, horizontalAmount, verticalAmount); + + return super.mouseScrolled( + mouseX, + mouseY, + horizontalAmount, + verticalAmount); + } + + @Override + public void resize(MinecraftClient client, int width, int height) { + elements.clear(); + super.resize(client, width, height); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + ElementRenderer.keyPressed(elements, keyCode, scanCode, modifiers); + + return super.keyPressed(keyCode, scanCode, modifiers); + } +} diff --git a/src/main/java/org/saturnclient/ui2/Utils.java b/src/main/java/org/saturnclient/ui2/Utils.java new file mode 100644 index 0000000..58bd7fb --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/Utils.java @@ -0,0 +1,47 @@ +package org.saturnclient.ui2; + +import org.lwjgl.glfw.GLFW; + +public class Utils { + public static boolean isHovering(int mouseX, int mouseY, int elementWidth, int elementHeight, float elementScale) { + return mouseX >= 0 && + mouseX <= (elementWidth * elementScale) && + mouseY >= 0 && + mouseY <= (elementHeight * elementScale); + } + + public static char getCharFromKey(int keyCode, int modifiers) { + boolean shift = (modifiers & GLFW.GLFW_MOD_SHIFT) != 0; + + // A-Z + if (keyCode >= GLFW.GLFW_KEY_A && keyCode <= GLFW.GLFW_KEY_Z) { + return (char) (shift + ? 'A' + (keyCode - GLFW.GLFW_KEY_A) + : 'a' + (keyCode - GLFW.GLFW_KEY_A)); + } + + // 0-9 + if (keyCode >= GLFW.GLFW_KEY_0 && keyCode <= GLFW.GLFW_KEY_9) { + return shift + ? ")!@#$%^&*(".charAt(keyCode - GLFW.GLFW_KEY_0) + : (char) ('0' + (keyCode - GLFW.GLFW_KEY_0)); + } + + // Special characters + return switch (keyCode) { + case GLFW.GLFW_KEY_SPACE -> ' '; + case GLFW.GLFW_KEY_PERIOD -> shift ? '>' : '.'; + case GLFW.GLFW_KEY_COMMA -> shift ? '<' : ','; + case GLFW.GLFW_KEY_MINUS -> shift ? '_' : '-'; + case GLFW.GLFW_KEY_EQUAL -> shift ? '+' : '='; + case GLFW.GLFW_KEY_SEMICOLON -> shift ? ':' : ';'; + case GLFW.GLFW_KEY_APOSTROPHE -> shift ? '"' : '\''; + case GLFW.GLFW_KEY_SLASH -> shift ? '?' : '/'; + case GLFW.GLFW_KEY_BACKSLASH -> shift ? '|' : '\\'; + case GLFW.GLFW_KEY_LEFT_BRACKET -> shift ? '{' : '['; + case GLFW.GLFW_KEY_RIGHT_BRACKET -> shift ? '}' : ']'; + case GLFW.GLFW_KEY_GRAVE_ACCENT -> shift ? '~' : '`'; + default -> '\0'; + }; + } +} diff --git a/src/main/java/org/saturnclient/ui2/anim/Animation.java b/src/main/java/org/saturnclient/ui2/anim/Animation.java new file mode 100644 index 0000000..6991c73 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/anim/Animation.java @@ -0,0 +1,47 @@ +package org.saturnclient.ui2.anim; + +import java.util.function.Consumer; +import java.util.function.Function; + +import org.saturnclient.ui2.Element; + +public abstract class Animation { + public int duration; + + Animation(int duration) { + this.duration = duration; + } + + public abstract void tick(float progress, Element element); + public abstract void init(Element element); + + public static void execute(Consumer tick, int duration) { + new Thread(() -> { + Function curveFunction = Curve::easeInOutCubic; + float progress = 0.0f; + double incremental = (1000 - duration) / 10000.0; + + for (int i = 0; i <= 100; i++) { + float newProgress = (float) (double) curveFunction.apply(i / 100.0); + + while (Math.abs(newProgress - progress) > 1e-6) { + if (progress < newProgress) { + progress += incremental; + if (progress > newProgress) progress = newProgress; + } else { + progress -= incremental; + if (progress < newProgress) progress = newProgress; + } + + tick.accept(newProgress); + + try { + Thread.sleep(duration / 100); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }).start(); + } +} diff --git a/src/main/java/org/saturnclient/ui2/anim/Curve.java b/src/main/java/org/saturnclient/ui2/anim/Curve.java new file mode 100644 index 0000000..c7f0a1c --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/anim/Curve.java @@ -0,0 +1,26 @@ +package org.saturnclient.ui2.anim; + +public class Curve { + public static double easeOutCubic(double x) { + return 1 - Math.pow(1 - x, 3); + } + + public static double easeInOutCubic(double x) { + return (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2); + } + + public static double easeInOutCubicReverse(double x) { + return -(x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2); + } + + public static double easeInOutBack(double x) { + double c1 = 1.70158; + double c2 = c1 * 1.525; + + if (x < 0.5) { + return (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2; + } else { + return (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (2 * x - 2) + c2) + 2) / 2; + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/anim/Fade.java b/src/main/java/org/saturnclient/ui2/anim/Fade.java new file mode 100644 index 0000000..47dfd65 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/anim/Fade.java @@ -0,0 +1,22 @@ +package org.saturnclient.ui2.anim; + +import org.saturnclient.ui2.Element; + +public class Fade extends Animation { + float targetOpacity; + + public Fade(int duration) { + super(duration); + } + + @Override + public void tick(float progress, Element element) { + element.opacity = targetOpacity * progress; + } + + @Override + public void init(Element element) { + targetOpacity = element.opacity; + element.opacity = 0; + } +} diff --git a/src/main/java/org/saturnclient/ui2/anim/SlideY.java b/src/main/java/org/saturnclient/ui2/anim/SlideY.java new file mode 100644 index 0000000..48ca61b --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/anim/SlideY.java @@ -0,0 +1,38 @@ +package org.saturnclient.ui2.anim; + +import org.saturnclient.ui2.Element; + +public class SlideY extends Animation { + int offset = 20; + int maxOffset = 20; + int elementY; + + public SlideY(int duration) { + super(duration); + } + + public SlideY(int duration, int offset) { + super(duration); + + this.offset = offset; + this.maxOffset = offset; + } + + public SlideY(int duration, int offset, int maxOffset) { + super(duration); + + this.offset = offset; + this.maxOffset = offset; + } + + @Override + public void tick(float progress, Element element) { + element.y = elementY + (int) (offset * progress); + } + + @Override + public void init(Element element) { + element.y -= offset; + elementY = element.y; + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/CosmeticPreview.java b/src/main/java/org/saturnclient/ui2/components/CosmeticPreview.java new file mode 100644 index 0000000..3a021ef --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/CosmeticPreview.java @@ -0,0 +1,60 @@ +package org.saturnclient.ui2.components; + +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; + +import net.minecraft.client.render.RenderLayer; +import net.minecraft.util.Identifier; + +public class CosmeticPreview extends Element { + private static ThemeManager theme = new ThemeManager("CosmeticPreview", "selected", "hovering"); + private static Property bgColor = theme.property("bg-color", new Property(0xAA000000)); + private static Property fgColor = theme.property("fg-color", new Property(0xFFFFFFFF)); + private static Property padding = theme.property("padding", new Property(14)); + private static Property cornerRadius = theme.property("corner-radius", new Property(10)); + + static {} + + Identifier sprite; + private Runnable onClick; + private boolean isSelected; + + public CosmeticPreview(boolean isSelected, Identifier sprite, Runnable onClick) { + this.sprite = sprite; + this.onClick = onClick; + this.isSelected = isSelected; + + this.width = 50; + this.height = 111; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + if (ctx.isHovering()) { + theme.setState("hovering"); + } else if (isSelected) { + theme.setState("selected"); + } + + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); + + renderScope.setRenderLayer(RenderLayer::getGuiTextured); + + int texWidth = width - padding.value; + int texHeight = height - padding.value; + + renderScope.drawTexture(sprite, padding.value / 2, padding.value / 2, 0, 0, texWidth, texHeight, fgColor.value); + + theme.setState(null); + } + + @Override + public void click(int mouseX, int mouseY) { + if (onClick != null) { + onClick.run(); + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/ElementRenderer.java b/src/main/java/org/saturnclient/ui2/components/ElementRenderer.java new file mode 100644 index 0000000..d7b9a02 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/ElementRenderer.java @@ -0,0 +1,84 @@ +package org.saturnclient.ui2.components; + +import java.util.ArrayList; +import java.util.List; + +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.Utils; +import org.saturnclient.ui2.anim.Animation; + +public class ElementRenderer { + public static void draw(List elements, Element element) { + synchronized (elements) { + elements.add(element); + } + + if (element.animation != null) { + element.animation.init(element); + + Animation.execute((Float progress) -> { + element.animation.tick(progress, element); + }, element.animation.duration); + } + } + + public static void render(List elements, RenderScope renderScope, int mouseX, int mouseY) { + for (Element element : elements) { + renderScope.matrices.push(); + renderScope.setOpacity(element.opacity); + renderScope.matrices.translate(element.x, element.y, 0); + renderScope.matrices.scale(element.scale, element.scale, 1.0f); + element.render(renderScope, new ElementContext(mouseX, mouseY, element)); + renderScope.matrices.pop(); + renderScope.setRenderLayer(null); + } + } + + public static void mouseClicked(List elements, double mouseX, double mouseY, int button) { + if (button == 0) { + for (Element element : new ArrayList<>(elements)) { + element.focused = false; + + int adjustedMouseX = (int) mouseX - element.x; + int adjustedMouseY = (int) mouseY - element.y; + + if (element.opacity > 0 && Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width, element.height, element.scale)) { + element.focused = true; + element.click((int) (adjustedMouseX * element.scale), (int) (adjustedMouseY * element.scale)); + } + } + } + } + + public static void mouseScrolled( + List elements, + double mouseX, + double mouseY, + double horizontalAmount, + double verticalAmount) { + for (Element element : new ArrayList<>(elements)) { + if (Utils.isHovering((int) mouseX - element.x, (int) mouseY - element.y, element.width, element.height, element.scale)) { + element.scroll( + (int) mouseX - element.x, + (int) mouseY - element.y, + horizontalAmount, + verticalAmount); + } + } + } + + public static void keyPressed(List elements, int keyCode, int scanCode, int modifiers) { + for (Element element : new ArrayList<>(elements)) { + if (element.focused && element.opacity > 0) { + element.keyPressed(keyCode, scanCode, modifiers); + + char typedChar = Utils.getCharFromKey(keyCode, modifiers); + if (typedChar != '\0') { + element.charTyped(typedChar); + } + } + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/SaturnModule.java b/src/main/java/org/saturnclient/ui2/components/SaturnModule.java new file mode 100644 index 0000000..8cb08df --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/SaturnModule.java @@ -0,0 +1,87 @@ +package org.saturnclient.ui2.components; + +import org.saturnclient.modules.Module; +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.resources.Textures; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.Utils; +import org.saturnclient.ui2.screens.ConfigEditor; + +import net.minecraft.client.render.RenderLayer; + +public class SaturnModule extends Element { + private static ThemeManager theme = new ThemeManager("Module", "enabled", "hovering"); + private static Property bgColor = theme.property("bg", new Property<>(0xFF1d202d)); + private static Property fgColor = theme.property("fg", new Property<>(0xFFA1A2B8)); + private static Property iconFg = theme.property("icon-fg", new Property<>(0xFFA1A2B8)); + private static Property iconBg = theme.property("icon-bg", new Property<>(0xFF2e3248)); + private static Property iconRadius = theme.property("icon-radius", new Property<>(10)); + private static Property radius = theme.property("radius", new Property<>(10)); + + static { + theme.propertyStateDefault("enabled", "bg", 0xFF1d202d); + theme.propertyStateDefault("enabled", "icon-bg", 0xFF845eee); + theme.propertyStateDefault("hovering", "fg", 0xFF845eee); + } + + private Module mod; + + public SaturnModule(Module mod) { + this.mod = mod; + this.width = 160; + this.height = 50; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + int p = 10; + int s = 14; + boolean settingsHover = false; + + renderScope.setRenderLayer(RenderLayer::getGuiTextured); + + if (mod.isEnabled()) { + theme.setState("enabled"); + } + + if (ctx.isHovering(width - s - p - 5, height - s - p - 5, s + 10, s + 10)) { + settingsHover = true; + } else if (ctx.isHovering()) { + theme.applyState("hovering"); + } + + renderScope.drawRoundedRectangle(0, 0, width, height, radius.value, bgColor.value); + + int h = height-(p * 2); + + renderScope.drawRoundedRectangle(p, p, h, h, iconRadius.value, iconBg.value); + + renderScope.drawTexture(mod.getIconTexture(), p + (p / 2), p + (p / 2), 0, 0, h - p, h - p, iconFg.value); + + renderScope.drawText(0.6f, mod.getName(), p+h+4, p + 1, true, fgColor.value); + + if (settingsHover) { + theme.setState("hovering"); + } + + renderScope.drawTexture(Textures.SETTINGS, width - s - p, height - s - p, 0, 0, s, s, fgColor.value); + + theme.setState(null); + } + + @Override + public void click(int mouseX, int mouseY) { + int p = 10; + int s = 14; + + if (Utils.isHovering(mouseX - (width - s - p - 5), mouseY - (height - s - p - 5), s + 10, s + 10, 1.0f)) { + SaturnClient.client.setScreen(new ConfigEditor(mod.getConfig())); + } else { + mod.setEnabled(!mod.isEnabled()); + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/Sidebar.java b/src/main/java/org/saturnclient/ui2/components/Sidebar.java new file mode 100644 index 0000000..69a5d9f --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/Sidebar.java @@ -0,0 +1,143 @@ +package org.saturnclient.ui2.components; + +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.resources.Textures; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.Utils; +import org.saturnclient.ui2.screens.CloakMenu; +import org.saturnclient.ui2.screens.HatMenu; +import org.saturnclient.ui2.screens.ModMenu; +import org.saturnclient.ui2.screens.SaturnConfigEditor; + +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 bgColor = theme.property("bg-color", new Property(0x90000000)); + private static Property iconFg = theme.property("icon-fg", new Property(-1)); + private static Property iconBg = theme.property("icon-bg", new Property(0x00000000)); + + private static Property cornerRadius = theme.property("corner-radius", new Property(10)); + private static Property iconRadius = theme.property("icon-radius", new Property(10)); + private static Property padding = theme.property("padding", new Property(10)); + + static { + theme.propertyStateDefault("hovering", "icon-bg", -7643914); + } + + public static class SidebarComponent { + Runnable onClick; + boolean end; + Identifier sprite; + + public SidebarComponent(Identifier sprite, Runnable onClick, boolean end) { + this.onClick = onClick; + this.end = end; + this.sprite = sprite; + } + } + + Runnable onClose; + SidebarComponent[] components = { + new Sidebar.SidebarComponent(Textures.MODS_TAB, () -> { + SaturnClient.client.setScreen(new ModMenu()); + }, false), + new Sidebar.SidebarComponent(Textures.SETTINGS, () -> { + SaturnClient.client.setScreen(new SaturnConfigEditor()); + }, false), + + new Sidebar.SidebarComponent(Textures.CLOAK, () -> { + 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) + }; + int active = 0; + + public Sidebar(int active, Runnable onClose) { + this.width = 30; + this.height = 350; + this.active = active; + this.onClose = onClose; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + int topRow = 0; + int bottomRow = 0; + + int sp = 30 - padding.value; + int s = 30 - (padding.value * 2); + + int s2 = s + padding.value; + + renderScope.setRenderLayer(RenderLayer::getGuiTextured); + + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); + + int i = 0; + + for (SidebarComponent component : components) { + if (component.end) { + int y = (height - (sp * bottomRow)) - (s * 2); + if (ctx.isHovering(0, y - (padding.value / 2), s2, s2) || active == i) { + theme.setState("hovering"); + } else { + theme.setState(null); + } + renderScope.drawRoundedRectangle(padding.value / 2, y - (padding.value / 2), s + padding.value, s + padding.value, iconRadius.value, iconBg.value); + renderScope.drawTexture(component.sprite, padding.value, y, 0, 0, s, s, iconFg.value); + bottomRow += 1; + } else { + int y = padding.value + ((sp) * topRow); + if (ctx.isHovering(0, y - (padding.value / 2), s2, s2) || active == i) { + theme.setState("hovering"); + } else { + theme.setState(null); + } + renderScope.drawRoundedRectangle(padding.value / 2, y - (padding.value / 2), s + padding.value, s + padding.value, iconRadius.value, iconBg.value); + renderScope.drawTexture(component.sprite, padding.value, y, 0, 0, s, s, iconFg.value); + topRow += 1; + } + + i++; + } + } + + @Override + public void click(int mouseX, int mouseY) { + int topRow = 0; + int bottomRow = 0; + + int sp = 30 - padding.value; + 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)) { + component.onClick.run(); + break; + } + bottomRow += 1; + } else { + if (Utils.isHovering(mouseX, mouseY - (padding.value + ((sp) * topRow)), s2, s2, scale)) { + component.onClick.run(); + break; + } + topRow += 1; + } + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/SkinPreview.java b/src/main/java/org/saturnclient/ui2/components/SkinPreview.java new file mode 100644 index 0000000..88407c0 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/SkinPreview.java @@ -0,0 +1,87 @@ +package org.saturnclient.ui2.components; + +import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; + +import net.minecraft.client.render.DiffuseLighting; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.entity.LivingEntity; + +public class SkinPreview extends Element { + private boolean negativeAngle = false; + private float angle = 0.0f; + + public SkinPreview(float angle, boolean negativeAngle) { + this.angle = angle; + this.negativeAngle = negativeAngle; + } + + public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float f, float mouseX, + float mouseY, LivingEntity entity, float angle, boolean negativeAngle) { + float g = (float) (x1 + x2) / 2.0F; + float h = (float) (y1 + y2) / 2.0F; + renderScope.enableScissor(0, 6, x2, y2); + float i = (float) Math.atan((double) ((g - mouseX) / 40.0F)); + float j = (float) Math.atan((double) ((h - mouseY) / 40.0F)); + Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F); + float k = entity.bodyYaw; + float l = entity.getYaw(); + float m = entity.getPitch(); + float n = entity.prevHeadYaw; + float o = entity.headYaw; + entity.setYaw(angle); + entity.bodyYaw = angle; + entity.setPitch(-(j * 20.0F)); + entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F); + entity.prevHeadYaw = entity.getHeadYaw(); + entity.setCustomNameVisible(false); + + float p = entity.getScale(); + Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F); + float q = (float) size / p; + drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity); + + entity.setCustomNameVisible(true); + entity.bodyYaw = k; + entity.setYaw(l); + entity.setPitch(m); + entity.prevHeadYaw = n; + entity.headYaw = o; + renderScope.disableScissor(); + } + + public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, + Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { + renderScope.matrices.push(); + renderScope.matrices.translate((double) x, (double) y, 50.0); + renderScope.matrices.scale(size, size, -size); + renderScope.matrices.translate(vector3f.x, vector3f.y, vector3f.z); + renderScope.matrices.multiply(quaternionf); + renderScope.draw(); + DiffuseLighting.method_34742(); + EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); + + entityRenderDispatcher.setRenderShadows(false); + renderScope.draw((vertexConsumers) -> { + entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, renderScope.matrices, vertexConsumers, + 15728880); + }); + renderScope.draw(); + entityRenderDispatcher.setRenderShadows(true); + renderScope.matrices.pop(); + DiffuseLighting.enableGuiDepthLighting(); + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + LivingEntity entity = SaturnClient.client.player; + if (entity != null) { + drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, negativeAngle); + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/dialog/ColorDialog.java b/src/main/java/org/saturnclient/ui2/components/dialog/ColorDialog.java new file mode 100644 index 0000000..0031626 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/dialog/ColorDialog.java @@ -0,0 +1,184 @@ +package org.saturnclient.ui2.components.dialog; + +import java.awt.Color; + +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.mixin.DrawContextAccessor; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.SaturnScreen; + +import net.minecraft.client.gui.DrawContext; + +public class ColorDialog extends SaturnScreen { + private Property prop; + private SaturnScreen parent; + private static final int PICKER_WIDTH = 200; + private static final int PICKER_HEIGHT = 200; + private static final int SLIDER_WIDTH = 200; + private static final int SLIDER_HEIGHT = 10; + + private int selectedX = 0; + private int selectedY = 0; + + private float opacity = 1.0f; + private boolean dragging = false; + + public ColorDialog(Property prop , SaturnScreen parent) { + super("Color Dialog"); + this.prop = prop; + this.parent = parent; + + int alpha = (prop.value >> 24) & 0xFF; + if (alpha == 0) alpha = 255; // fallback if no alpha specified + this.opacity = alpha / 255.0f; + } + + @Override + public void ui() {} + + @Override + public void close() { + SaturnClient.client.setScreen(parent); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + RenderScope renderScope = new RenderScope(context.getMatrices(), + ((DrawContextAccessor) context).getVertexConsumers()); + + renderScope.matrices.push(); + + renderScope.matrices.scale(0.5f, 0.5f, 0.5f); + + int xStart = (width - PICKER_WIDTH) / 2; + int yStart = (height - PICKER_HEIGHT) / 2; + + // Draw the HSV hue/saturation square (brightness fixed at 1) + for (int x = 0; x < PICKER_WIDTH; x++) { + for (int y = 0; y < PICKER_HEIGHT; y++) { + float hue = x / (float) PICKER_WIDTH; + float saturation = y / (float) PICKER_HEIGHT; + int color = Color.HSBtoRGB(hue, saturation, 1.0f); + context.fill(xStart + x, yStart + y, xStart + x + 1, yStart + y + 1, 0xFF000000 | color); + } + } + + int x = (xStart + selectedX) - 4; + int y = (yStart + selectedY) - 4; + context.fill(x, y, x+8, y+8, 0xFF000000 | prop.value); + context.drawBorder(x, y, 8, 8, 0xFFffffff); + + renderSlider(context, mouseX, mouseY, delta); + + renderScope.matrices.pop(); + } + + public void renderSlider(DrawContext context, int mouseX, int mouseY, float delta) { + int xStart = (width - SLIDER_WIDTH) / 2; + int yStart = (height - SLIDER_HEIGHT - PICKER_HEIGHT) / 2 - 10; + + // Draw slider background (left = transparent, right = white) + for (int x = 0; x < SLIDER_WIDTH; x++) { + float localOpacity = x / (float) SLIDER_WIDTH; + int alpha = (int)(localOpacity * 255) & 0xFF; + int color = (alpha << 24) | (prop.value & 0xFFFFFF); + context.fill(xStart + x, yStart, xStart + x + 1, yStart + SLIDER_HEIGHT, color); + } + + // Draw current value as a marker (thin black line) + int knobX = xStart + (int)(opacity * SLIDER_WIDTH); + context.fill(knobX - 1, yStart - 2, knobX + 1, yStart + SLIDER_HEIGHT + 2, 0xFF000000); + + // Draw opacity text + // context.drawText(textRenderer, String.format("Opacity: %.2f", opacity), xStart, yStart - 15, 0xFFFFFF, false); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + mouseX *= 2; + mouseY *= 2; + + int xStart = (width - PICKER_WIDTH) / 2; + int yStart = (height - PICKER_HEIGHT) / 2; + + int relX = (int) mouseX - xStart; + int relY = (int) mouseY - yStart; + + if (relX >= 0 && relX < PICKER_WIDTH && relY >= 0 && relY < PICKER_HEIGHT) { + float hue = relX / (float) PICKER_WIDTH; + float saturation = relY / (float) PICKER_HEIGHT; + prop.value = Color.HSBtoRGB(hue, saturation, 1.0f); + + int alpha = (int)(opacity * 255) & 0xFF; + prop.value = (alpha << 24) | (prop.value & 0xFFFFFF); + + selectedX = relX; + selectedY = relY; + + return true; + } else if (isInSlider(mouseX, mouseY)) { + updateOpacity(mouseX); + dragging = true; + return true; + } + + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + dragging = false; + return super.mouseReleased(mouseX, mouseY, button); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + mouseX *= 2; + mouseY *= 2; + + if (dragging) { + updateOpacity(mouseX); + return true; + } else { + int xStart = (width - PICKER_WIDTH) / 2; + int yStart = (height - PICKER_HEIGHT) / 2; + + int relX = (int) mouseX - xStart; + int relY = (int) mouseY - yStart; + + if (relX >= 0 && relX < PICKER_WIDTH && relY >= 0 && relY < PICKER_HEIGHT) { + float hue = relX / (float) PICKER_WIDTH; + float saturation = relY / (float) PICKER_HEIGHT; + prop.value = Color.HSBtoRGB(hue, saturation, 1.0f); + + int alpha = (int)(opacity * 255) & 0xFF; + prop.value = (alpha << 24) | (prop.value & 0xFFFFFF); + + selectedX = relX; + selectedY = relY; + + return true; + } + } + + return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + private boolean isInSlider(double mouseX, double mouseY) { + int xStart = (width - SLIDER_WIDTH) / 2; + int yStart = (height - SLIDER_HEIGHT - PICKER_HEIGHT) / 2 - 10; + return mouseX >= xStart && mouseX <= xStart + SLIDER_WIDTH && + mouseY >= yStart && mouseY <= yStart + SLIDER_HEIGHT; + } + + private void updateOpacity(double mouseX) { + int xStart = (width - SLIDER_WIDTH) / 2; + float newOpacity = (float)((mouseX - xStart) / SLIDER_WIDTH); + opacity = Math.max(0.0f, Math.min(1.0f, newOpacity)); + + int alpha = (int)(opacity * 255) & 0xFF; + prop.value = (alpha << 24) | (prop.value & 0xFFFFFF); + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/inputs/FloatInput.java b/src/main/java/org/saturnclient/ui2/components/inputs/FloatInput.java new file mode 100644 index 0000000..e3d365f --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/inputs/FloatInput.java @@ -0,0 +1,59 @@ +package org.saturnclient.ui2.components.inputs; + +import org.saturnclient.saturnclient.config.ConfigManager; +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.ui2.resources.Fonts; + +public class FloatInput extends Input { + public Property prop; + + public FloatInput(Property prop) { + this.width = 120; + this.height = Fonts.getHeight(); + this.prop = prop; + this.text = String.valueOf(prop.value); + } + + @Override + public void charTyped(char chr) { + if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) { + if (text.equals("0") && cursorPosition == 1) { + text = "" + chr; + } else { + text = text.substring(0, cursorPosition) + + chr + + text.substring(cursorPosition); + + try { + prop.value = text.isEmpty() ? 0 : Float.parseFloat(text); + cursorPosition++; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + @Override + public void backspace() { + try { + if (text.length() == 0) { + text = "0"; + cursorPosition = 1; + } + prop.value = Float.parseFloat(text); + ConfigManager.save(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void checkReset() { + if (prop.isReset) { + this.text = String.valueOf(prop.value); + this.cursorPosition = 0; + prop.isReset = false; + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/inputs/HexInput.java b/src/main/java/org/saturnclient/ui2/components/inputs/HexInput.java new file mode 100644 index 0000000..1efcc53 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/inputs/HexInput.java @@ -0,0 +1,32 @@ +package org.saturnclient.ui2.components.inputs; + +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.SaturnScreen; +import org.saturnclient.ui2.components.dialog.ColorDialog; + +public class HexInput extends Element { + public Property prop; + public SaturnScreen screen; + + public HexInput(Property prop, SaturnScreen screen) { + this.width = 58; + this.height = 18; + this.prop = prop; + this.scale = 0.8f; + this.screen = screen; + } + + @Override + public void click(int mouseX, int mouseY) { + SaturnClient.client.setScreen(new ColorDialog(prop, screen)); + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + renderScope.drawRoundedRectangle(0, 0, width, height, 17, prop.value); + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/inputs/Input.java b/src/main/java/org/saturnclient/ui2/components/inputs/Input.java new file mode 100644 index 0000000..0236249 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/inputs/Input.java @@ -0,0 +1,110 @@ +package org.saturnclient.ui2.components.inputs; + +import org.lwjgl.glfw.GLFW; +import org.saturnclient.saturnclient.SaturnClient; +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 { + String text = ""; + public int cursorPosition = 0; + public abstract void checkReset(); + public abstract void backspace(); + public boolean validateBackspace() { + return true; + } + + @Override + public void keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { + if (cursorPosition > 0 && validateBackspace()) { + text = text.substring(0, cursorPosition - 1) + + text.substring(cursorPosition); + cursorPosition--; + backspace(); + } + } else if (keyCode == GLFW.GLFW_KEY_LEFT) { + if (cursorPosition > 0) { + cursorPosition--; + } + } else if (keyCode == GLFW.GLFW_KEY_RIGHT) { + if (cursorPosition < text.length()) { + cursorPosition++; + } + } + } + + @Override + public void click(int mouseX, int mouseY) { + int scrollOffset = getScrollOffset(); + String visibleText = text.substring(scrollOffset); + + int newCursorPos = scrollOffset; + int textWidth = 0; + + for (int i = 0; i < visibleText.length(); i++) { + textWidth = SaturnClient.client.textRenderer.getWidth(visibleText.substring(0, i + 1)); + + if (textWidth > mouseX) { + break; + } + + newCursorPos++; + } + + cursorPosition = newCursorPos; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + checkReset(); + + renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000); + + int scrollOffset = getScrollOffset(); + String visibleText = getVisibleText(scrollOffset); + int textColor = focused ? 0xFFFFFF : 0xAAAAAA; + renderScope.drawText(0.6f, visibleText, 2, 2, false, textColor); + + if (focused) { + int cursorX = 2 + + SaturnClient.client.textRenderer.getWidth( + Fonts.setFont(visibleText.substring(0, cursorPosition - scrollOffset))); + + renderScope.drawRect(cursorX, 2, 1, height - 1, 0xFFFFFFFF); + } + } + + protected int getScrollOffset() { + if (text.isEmpty()) { + return 0; + } + + int offset = 0; + int maxWidth = width - 4; // Available width for text + while (offset < cursorPosition) { // Ensure cursor remains visible + String visibleText = text.substring(offset, cursorPosition); + if (SaturnClient.client.textRenderer.getWidth(Fonts.setFont(visibleText)) > maxWidth) { + offset++; + } else { + break; + } + } + return offset; + } + + protected String getVisibleText(int scrollOffset) { + String visibleText = text.substring(scrollOffset); + + // Ensure text does not overflow past the available width + for (int i = 1; i <= visibleText.length(); i++) { + if (SaturnClient.client.textRenderer.getWidth( + Fonts.setFont(visibleText.substring(0, i))) > width - 4) { + return visibleText.substring(0, i - 1); // Trim overflow + } + } + return visibleText; + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/inputs/IntInput.java b/src/main/java/org/saturnclient/ui2/components/inputs/IntInput.java new file mode 100644 index 0000000..9a8d741 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/inputs/IntInput.java @@ -0,0 +1,59 @@ +package org.saturnclient.ui2.components.inputs; + +import org.saturnclient.saturnclient.config.ConfigManager; +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.ui2.resources.Fonts; + +public class IntInput extends Input { + public Property prop; + + public IntInput(Property prop) { + this.width = 120; + this.height = Fonts.getHeight(); + this.prop = prop; + this.text = String.valueOf(prop.value); + } + + @Override + public void charTyped(char chr) { + if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) { + if (text.equals("0") && cursorPosition == 1) { + text = "" + chr; + } else { + text = text.substring(0, cursorPosition) + + chr + + text.substring(cursorPosition); + + try { + prop.value = text.isEmpty() ? 0 : Integer.parseInt(text); + cursorPosition++; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + @Override + public void backspace() { + try { + if (text.length() == 0) { + text = "0"; + cursorPosition = 1; + } + prop.value = Integer.parseInt(text); + ConfigManager.save(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void checkReset() { + if (prop.isReset) { + this.text = String.valueOf(prop.value); + this.cursorPosition = 0; + prop.isReset = false; + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/components/inputs/Toggle.java b/src/main/java/org/saturnclient/ui2/components/inputs/Toggle.java new file mode 100644 index 0000000..be58056 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/components/inputs/Toggle.java @@ -0,0 +1,49 @@ +package org.saturnclient.ui2.components.inputs; + +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; + +public class Toggle extends Element { + private static ThemeManager theme = new ThemeManager("Toggle", "hovering", "enabled"); + private static Property bgColor = theme.property("bg-color", new Property(0xFF808080)); + private static Property fgColor = theme.property("fg-color", new Property(0xFF909090)); + private static Property cornerRadius = theme.property("corner-radius", new Property(30)); + + static { + theme.propertyStateDefault("enabled", "bg-color", 0xaf8B5CF6); + theme.propertyStateDefault("enabled", "fg-color", 0xff8B5CF6); + } + + private Property prop; + + public Toggle(Property prop) { + this.prop = prop; + this.width = 60; + this.height = 30; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + if (prop.value) { + theme.setState("enabled"); + } + + if (ctx.isHovering()) { + theme.applyState("hovering"); + } + + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); + + renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30, fgColor.value); + + theme.setState(null); + } + + @Override + public void click(int mouseX, int mouseY) { + prop.value = !prop.value; + } +} diff --git a/src/main/java/org/saturnclient/ui2/elements/Button.java b/src/main/java/org/saturnclient/ui2/elements/Button.java new file mode 100644 index 0000000..a4ae70e --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/elements/Button.java @@ -0,0 +1,49 @@ +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.resources.Fonts; + +public class Button extends Element { + private static ThemeManager theme = new ThemeManager("Button", "hovering"); + private static Property bgColor = theme.property("bg-color", new Property(0xFF000000)); + private static Property fgColor = theme.property("fg-color", new Property(0xFFFFFFFF)); + private static Property cornerRadius = theme.property("corner-radius", new Property(10)); + private static Property bold = theme.property("fg-bold", new Property(false)); + + static { + theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee); + } + + private String text; + private Runnable onClick; + + public Button(String text, Runnable onClick) { + this.text = text; + this.onClick = onClick; + this.dimensions(Fonts.getWidth(text, bold.value) + 50, 38); + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + if (ctx.isHovering()) { + theme.setState("hovering"); + } else { + theme.setState(null); + } + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); + + // renderScope.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); + } + + @Override + public void click(int mouseX, int mouseY) { + if (onClick != null) { + onClick.run(); + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/elements/ClickableTexture.java b/src/main/java/org/saturnclient/ui2/elements/ClickableTexture.java new file mode 100644 index 0000000..33f377f --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/elements/ClickableTexture.java @@ -0,0 +1,42 @@ +package org.saturnclient.ui2.elements; + +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; + +import net.minecraft.client.render.RenderLayer; +import net.minecraft.util.Identifier; + +public class ClickableTexture extends Element { + private static ThemeManager theme = new ThemeManager("ClickableTexture", "hovering"); + private static Property fgColor = theme.property("fg-color", new Property(0xFFFFFFFF)); + + Identifier sprite; + private Runnable onClick; + + public ClickableTexture(Identifier sprite, Runnable onClick) { + this.sprite = sprite; + this.onClick = onClick; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + if (ctx.isHovering()) { + theme.setState("hovering"); + } else { + theme.setState(null); + } + + renderScope.setRenderLayer(RenderLayer::getGuiTextured); + renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height, fgColor.value); + } + + @Override + public void click(int mouseX, int mouseY) { + if (onClick != null) { + onClick.run(); + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/elements/ImageTexture.java b/src/main/java/org/saturnclient/ui2/elements/ImageTexture.java new file mode 100644 index 0000000..b5d9426 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/elements/ImageTexture.java @@ -0,0 +1,22 @@ +package org.saturnclient.ui2.elements; + +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; + +import net.minecraft.client.render.RenderLayer; +import net.minecraft.util.Identifier; + +public class ImageTexture extends Element { + Identifier sprite; + + public ImageTexture(Identifier sprite) { + this.sprite = sprite; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + renderScope.setRenderLayer(RenderLayer::getGuiTextured); + renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height); + } +} diff --git a/src/main/java/org/saturnclient/ui2/elements/Scroll.java b/src/main/java/org/saturnclient/ui2/elements/Scroll.java new file mode 100644 index 0000000..b51a4b1 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/elements/Scroll.java @@ -0,0 +1,91 @@ +package org.saturnclient.ui2.elements; + +import java.util.ArrayList; +import java.util.List; + +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.components.ElementRenderer; + +public class Scroll extends Element { + private static ThemeManager theme = new ThemeManager("Scroll"); + private static Property bgColor = theme.property("bg-color", new Property(0x90000000)); + private static Property scrollBarColor = theme.property("scrollbar-color", new Property(-7643914)); + + private static Property scrollBarRadius = theme.property("scrollbar-radius", new Property(10)); + private static Property scrollBarWidth = theme.property("scrollbar-width", new Property(5)); + private static Property scrollBarPadding = theme.property("scrollbar-padding", new Property(5)); + private static Property cornerRadius = theme.property("corner-radius", new Property(10)); + + int padding = 0; + + protected List children = new ArrayList<>(); + int scroll = 0; + int maxScroll = 0; + + public Scroll(int padding) { + this.padding = padding; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); + + renderScope.enableScissor(padding, padding, width - padding, height - padding); + renderScope.matrices.push(); + renderScope.matrices.translate(padding, (-scroll) + padding, 0); + ElementRenderer.render(children, renderScope, ctx.mouseX - padding, ctx.mouseY - padding + scroll); + renderScope.matrices.pop(); + renderScope.disableScissor(); + + renderScope.drawRoundedRectangle(width - scrollBarWidth.value - scrollBarPadding.value, calculateScrollBarY(), scrollBarWidth.value, calculateScrollBarHeight(), scrollBarRadius.value, scrollBarColor.value); + } + + @Override + public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) { + scroll -= verticalAmount; + if (scroll < 0) { + scroll = 0; + } else if (scroll > maxScroll) { + scroll = maxScroll; + } + } + + @Override + public void click(int mouseX, int mouseY) { + ElementRenderer.mouseClicked(children, mouseX - padding, mouseY - padding + scroll, 0); + } + + public void draw(Element element) { + children.add(element); + + if (element.width > width) { + width = element.width; + } + + if (element.height > height) { + height = element.height; + } + + maxScroll = Math.max(maxScroll, element.y - maxScroll); + } + + int calculateScrollBarHeight() { + if (maxScroll <= 0) return height - (scrollBarPadding.value * 2); // No scrolling needed + return Math.max(20, (height * height) / (height + maxScroll)) - (scrollBarPadding.value * 2); // At least 20px tall + } + + int calculateScrollBarY() { + int scrollBarHeight = calculateScrollBarHeight(); + if (maxScroll <= 0) return scrollBarPadding.value; + return (scroll * (height - scrollBarHeight)) / maxScroll + scrollBarPadding.value; + } + + @Override + public void keyPressed(int keyCode, int scanCode, int modifiers) { + ElementRenderer.keyPressed(children, keyCode, scanCode, modifiers); + } +} diff --git a/src/main/java/org/saturnclient/ui2/elements/Text.java b/src/main/java/org/saturnclient/ui2/elements/Text.java new file mode 100644 index 0000000..96b7b03 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/elements/Text.java @@ -0,0 +1,23 @@ +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; + +public class Text extends Element { + private static ThemeManager theme = new ThemeManager("Text"); + private static Property fgColor = theme.property("fg-color", new Property(0xFFFFFFFF)); + + private String text; + + public Text(String text) { + this.text = text; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + renderScope.drawText(this.text, 0, 0, false, fgColor.value); + } +} diff --git a/src/main/java/org/saturnclient/ui2/elements/TextureButton.java b/src/main/java/org/saturnclient/ui2/elements/TextureButton.java new file mode 100644 index 0000000..f1575d4 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/elements/TextureButton.java @@ -0,0 +1,56 @@ +package org.saturnclient.ui2.elements; + +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; + +import net.minecraft.client.render.RenderLayer; +import net.minecraft.util.Identifier; + +public class TextureButton extends Element { + private static ThemeManager theme = new ThemeManager("TextureButton", "hovering"); + private static Property bgColor = theme.property("bg-color", new Property(0xFF000000)); + private static Property fgColor = theme.property("fg-color", new Property(0xFFFFFFFF)); + private static Property padding = theme.property("padding", new Property(14)); + private static Property cornerRadius = theme.property("corner-radius", new Property(10)); + + + static { + theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee); + } + + Identifier sprite; + private Runnable onClick; + + public TextureButton(Identifier sprite, Runnable onClick) { + this.sprite = sprite; + this.onClick = onClick; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + if (ctx.isHovering()) { + theme.setState("hovering"); + } else { + theme.setState(null); + } + + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); + + renderScope.setRenderLayer(RenderLayer::getGuiTextured); + + int texWidth = width - padding.value; + int texHeight = height - padding.value; + + renderScope.drawTexture(sprite, padding.value / 2, padding.value / 2, 0, 0, texWidth, texHeight, fgColor.value); + } + + @Override + public void click(int mouseX, int mouseY) { + if (onClick != null) { + onClick.run(); + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/resources/Fonts.java b/src/main/java/org/saturnclient/ui2/resources/Fonts.java new file mode 100644 index 0000000..b1697f1 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/resources/Fonts.java @@ -0,0 +1,59 @@ +package org.saturnclient.ui2.resources; + +import org.saturnclient.saturnclient.SaturnClient; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +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 Identifier getFont(boolean bold) { + if (bold) { + return INTER_BOLD; + } else { + return INTER; + } + } + + public static Text setFont(String text, Identifier font) { + return Text.literal(text).setStyle( + 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 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))); + } + + 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 centerY(int h) { + return (h - 18) / 2; + } +} diff --git a/src/main/java/org/saturnclient/ui/Textures.java b/src/main/java/org/saturnclient/ui2/resources/Textures.java similarity index 94% rename from src/main/java/org/saturnclient/ui/Textures.java rename to src/main/java/org/saturnclient/ui2/resources/Textures.java index f8b90f9..cfdf79f 100644 --- a/src/main/java/org/saturnclient/ui/Textures.java +++ b/src/main/java/org/saturnclient/ui2/resources/Textures.java @@ -1,8 +1,9 @@ -package org.saturnclient.ui; +package org.saturnclient.ui2.resources; import net.minecraft.util.Identifier; public class Textures { + public static final Identifier CROSSHAIR_RANGE = Identifier.of("saturnclient", "textures/gui/hud/crosshair_range.png"); public static final Identifier COSMETICS = Identifier.of("saturnclient", "textures/gui/components/cosmetics.png"); public static final Identifier HUD_ICON = Identifier.of("saturnclient", "textures/gui/components/hud.png"); public static final Identifier SEARCH = Identifier.of("saturnclient", "textures/gui/components/search.png"); diff --git a/src/main/java/org/saturnclient/ui2/screens/CloakMenu.java b/src/main/java/org/saturnclient/ui2/screens/CloakMenu.java new file mode 100644 index 0000000..47bfb6d --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/CloakMenu.java @@ -0,0 +1,53 @@ +package org.saturnclient.ui2.screens; + +import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.auth.SaturnPlayer; +import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; +import org.saturnclient.ui2.resources.Textures; +import org.saturnclient.ui2.SaturnScreen; +import org.saturnclient.ui2.components.CosmeticPreview; +import org.saturnclient.ui2.components.Sidebar; +import org.saturnclient.ui2.components.SkinPreview; +import org.saturnclient.ui2.elements.Scroll; + +public class CloakMenu extends SaturnScreen { + public CloakMenu() { + super("Cloaks Menu"); + } + + @Override + public void ui() { + int p = 10; + int g = 10; + + 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.availableCloaks) { + scroll.draw(new CosmeticPreview(cloak == player.cloak, Textures.getCloakPreview(cloak), () -> { + Cloaks.setCloak(Auth.uuid, cloak); + }).position((50 + g) * col, (111 + g) * row)); + + if (col == 5) { + col = 0; + row++; + } else { + col++; + } + } + } + + int scrollWidth = 480 + 10 + (g * 2) + (p * 2); + + 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 Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); + } +} diff --git a/src/main/java/org/saturnclient/ui2/screens/ConfigEditor.java b/src/main/java/org/saturnclient/ui2/screens/ConfigEditor.java new file mode 100644 index 0000000..f50dd78 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/ConfigEditor.java @@ -0,0 +1,111 @@ +package org.saturnclient.ui2.screens; + +import java.util.Map; + +import org.saturnclient.saturnclient.config.ConfigManager; +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; + +public class ConfigEditor extends SaturnScreen { + private ConfigManager config; + + public ConfigEditor(ConfigManager config) { + super("Config Editor"); + + this.config = config; + } + + @Override + public void ui() { + int p = 10; + int g = 10; + + Scroll scroll = new Scroll(p); + + drawProperties(scroll, 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(0, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); + } + + @SuppressWarnings("unchecked") + private int drawProperties(Scroll configScroll, Map> properties, int row, int col, int w) { + for (Map.Entry> 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; + + configScroll.draw( + new Text( + propName.substring(0, 1).toUpperCase() + propName.substring(1) + ).position(modX, modY + 1).scale(0.7f)); + + switch (prop.getType()) { + case BOOLEAN: + configScroll.draw( + new Toggle((Property) prop) + .position(modX + (w / 2) - 40, modY) + .scale(0.5f)); + break; + + case HEX: + configScroll.draw(new HexInput((Property) prop, this).position(w / 2, modY)); + break; + + case INTEGER: + configScroll.draw(new IntInput((Property) prop).position(w / 2, modY)); + break; + + case FLOAT: + configScroll.draw(new FloatInput((Property) prop).position(w / 2, modY)); + break; + + case NAMESPACE: + Map> nestedProperties = (Map>) prop.value; + row = drawProperties(configScroll, nestedProperties, row + 1, col, w); + break; + } + + 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; + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/screens/HatMenu.java b/src/main/java/org/saturnclient/ui2/screens/HatMenu.java new file mode 100644 index 0000000..06e89bb --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/HatMenu.java @@ -0,0 +1,53 @@ +package org.saturnclient.ui2.screens; + +import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.auth.SaturnPlayer; +import org.saturnclient.saturnclient.cosmetics.Hats; +import org.saturnclient.ui2.resources.Textures; +import org.saturnclient.ui2.SaturnScreen; +import org.saturnclient.ui2.components.CosmeticPreview; +import org.saturnclient.ui2.components.Sidebar; +import org.saturnclient.ui2.components.SkinPreview; +import org.saturnclient.ui2.elements.Scroll; + +public class HatMenu extends SaturnScreen { + public HatMenu() { + super("Hats Menu"); + } + + @Override + public void ui() { + int p = 10; + int g = 10; + + 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.availableHats) { + scroll.draw(new CosmeticPreview(hat == player.hat, Textures.getHatPreview(hat), () -> { + Hats.setHat(Auth.uuid, hat); + }).dimensions(50, 50).position((50 + g) * col, (50 + g) * row)); + + if (col == 5) { + col = 0; + row++; + } else { + col++; + } + } + } + + int scrollWidth = 480 + 10 + (g * 2) + (p * 2); + + 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 Sidebar(3, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); + } +} diff --git a/src/main/java/org/saturnclient/ui2/screens/ModMenu.java b/src/main/java/org/saturnclient/ui2/screens/ModMenu.java new file mode 100644 index 0000000..8a88883 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/ModMenu.java @@ -0,0 +1,42 @@ +package org.saturnclient.ui2.screens; + +import org.saturnclient.modules.ModManager; +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.Scroll; + +public class ModMenu extends SaturnScreen { + public ModMenu() { + super("Mod Menu"); + } + + @Override + public void ui() { + int p = 10; + int g = 10; + + Scroll scroll = new Scroll(p); + + int row = 0; + int col = 0; + + for (Module mod : ModManager.MODS) { + scroll.draw(new SaturnModule(mod).position((160 + g) * col, (50 + g) * row)); + + if (col == 2) { + col = 0; + row++; + } else { + col++; + } + } + + int scrollWidth = 480 + 10 + (g * 2) + (p * 2); + + draw(scroll.dimensions(scrollWidth, 350).center(width, height)); + + draw(new Sidebar(0, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); + } +} diff --git a/src/main/java/org/saturnclient/ui2/screens/SaturnConfigEditor.java b/src/main/java/org/saturnclient/ui2/screens/SaturnConfigEditor.java new file mode 100644 index 0000000..ef08cbe --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/SaturnConfigEditor.java @@ -0,0 +1,107 @@ +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; + +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> properties, int row, int col, int w) { + for (Map.Entry> 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; + + configScroll.draw( + new Text( + propName.substring(0, 1).toUpperCase() + propName.substring(1) + ).position(modX, modY + 1).scale(0.7f)); + + switch (prop.getType()) { + case BOOLEAN: + configScroll.draw( + new Toggle((Property) prop) + .position(modX + (w / 2) - 40, modY) + .scale(0.5f)); + break; + + case HEX: + configScroll.draw(new HexInput((Property) prop, this).position(w / 2, modY)); + break; + + case INTEGER: + configScroll.draw(new IntInput((Property) prop).position(w / 2, modY)); + break; + + case FLOAT: + configScroll.draw(new FloatInput((Property) prop).position(w / 2, modY)); + break; + + case NAMESPACE: + Map> nestedProperties = (Map>) prop.value; + row = drawProperties(configScroll, nestedProperties, row + 1, col, w); + break; + } + + 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; + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java b/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java new file mode 100644 index 0000000..0a4b29e --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java @@ -0,0 +1,39 @@ +package org.saturnclient.ui2.screens; + +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.Element; +import org.saturnclient.ui2.SaturnScreen; +import org.saturnclient.ui2.elements.Button; +import org.saturnclient.ui2.elements.ImageTexture; +import org.saturnclient.ui2.elements.TextureButton; +import org.saturnclient.ui2.anim.Fade; +import org.saturnclient.ui2.anim.SlideY; + +public class ShiftMenu extends SaturnScreen { + public ShiftMenu() { + super("Shift Menu"); + } + + @Override + public void ui() { + draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -36).animation(new Fade(700))); + draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -80).animation(new SlideY(700, -20))); + + Element button = new Button("Settings", () -> { + SaturnClient.client.setScreen(new ModMenu()); + }).center(width, height); + + draw(button); + + draw(new TextureButton(Textures.COSMETICS, () -> { + client.setScreen(new CloakMenu()); + }).dimensions(button.height, button.height).centerOffset(width, height, (button.width / 2) + (button.height / 2) + 4, 0)); + + draw(new TextureButton(Textures.HUD_ICON, () -> { + client.setScreen(new HudEditor()); + }).dimensions(button.height, button.height).centerOffset(width, height, -((button.width / 2) + (button.height / 2) + 4), 0)); + } +} diff --git a/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java b/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java new file mode 100644 index 0000000..05e99c0 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java @@ -0,0 +1,61 @@ +package org.saturnclient.ui2.screens; + +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.SaturnScreen; +import org.saturnclient.ui2.anim.Fade; +import org.saturnclient.ui2.anim.SlideY; +import org.saturnclient.ui2.elements.Button; +import org.saturnclient.ui2.elements.ImageTexture; +import org.saturnclient.ui2.elements.TextureButton; +import org.saturnclient.ui2.resources.Fonts; + +import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; +import net.minecraft.client.gui.screen.option.OptionsScreen; +import net.minecraft.client.gui.screen.world.SelectWorldScreen; + +public class TitleMenu extends SaturnScreen { + public TitleMenu() { + super("Tile Menu"); + } + + @Override + public void ui() { + backgroundBlur = 0; + + draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -36).animation(new Fade(700))); + draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -82).animation(new SlideY(700, -20))); + + draw(new Button("SINGLEPLAYER", () -> { + client.setScreen(new SelectWorldScreen(new TitleMenu())); + }).scale(0.69f).dimensions(420, 52).centerOffset(width, height, 0, 0)); + + draw(new Button("MULTIPLAYER", () -> { + client.setScreen(new MultiplayerScreen(new TitleMenu())); + }).scale(0.69f).dimensions(420, 52).centerOffset(width, height, 0, 40)); + + draw(new Button("OPTIONS", () -> { + client.setScreen(new OptionsScreen(new TitleMenu(), SaturnClient.client.options)); + }).scale(0.69f).dimensions(206, 52).centerOffset(width, height, -73, 80)); + + draw(new Button("QUIT", () -> { + client.scheduleStop(); + }).scale(0.69f).dimensions(206, 52).centerOffset(width, height, 73, 80)); + + int s = Fonts.getHeight() + 20; + + draw(new TextureButton(Textures.HUD_ICON, () -> { + client.setScreen(new HudEditor()); + }).dimensions(s, s).centerHorizontal(width, height, -(s + 2), 8).animation(new SlideY(700, s + 8))); + + draw(new TextureButton(Textures.SETTINGS, () -> { + SaturnClient.client.setScreen(new ModMenu()); + }).dimensions(s, s).centerHorizontal(width, height, 0, 8).animation(new SlideY(700, s + 8))); + + draw(new TextureButton(Textures.CLOAK, () -> { + client.setScreen(new CloakMenu()); + }).dimensions(s, s).centerHorizontal(width, height, s + 2, 8).animation(new SlideY(700, s + 8))); + } +} diff --git a/src/main/resources/assets/minecraft/font/fonts.json b/src/main/resources/assets/minecraft/font/fonts.json index f6f22a0..7606077 100644 --- a/src/main/resources/assets/minecraft/font/fonts.json +++ b/src/main/resources/assets/minecraft/font/fonts.json @@ -2,11 +2,11 @@ "providers": [ { "type": "reference", - "id": "saturnclient:panton" + "id": "saturnclient:inter" }, { "type": "reference", - "id": "saturnclient:panton_bold" + "id": "saturnclient:inter_bold" } ] } diff --git a/src/main/resources/assets/saturnclient/font/Panton-Trial-Bold.ttf b/src/main/resources/assets/saturnclient/font/Panton-Trial-Bold.ttf deleted file mode 100644 index 19d9074..0000000 Binary files a/src/main/resources/assets/saturnclient/font/Panton-Trial-Bold.ttf and /dev/null differ diff --git a/src/main/resources/assets/saturnclient/font/README.md b/src/main/resources/assets/saturnclient/font/README.md index ed50ac4..4af02e8 100644 --- a/src/main/resources/assets/saturnclient/font/README.md +++ b/src/main/resources/assets/saturnclient/font/README.md @@ -1,3 +1 @@ -This font was designed by Ivan Petrov and published by Fontfabric. - -The panton font is the regular version of: https://www.dafont.com/panton.font +Here is the font download: https://fonts.google.com/specimen/Inter \ No newline at end of file diff --git a/src/main/resources/assets/saturnclient/font/panton.json b/src/main/resources/assets/saturnclient/font/inter.json similarity index 56% rename from src/main/resources/assets/saturnclient/font/panton.json rename to src/main/resources/assets/saturnclient/font/inter.json index 8990556..8ffca49 100644 --- a/src/main/resources/assets/saturnclient/font/panton.json +++ b/src/main/resources/assets/saturnclient/font/inter.json @@ -2,10 +2,10 @@ "providers": [ { "type": "ttf", - "file": "saturnclient:panton.ttf", + "file": "saturnclient:inter.ttf", "shift": [0, 0], - "size": 9, - "oversample": 5.0, + "size": 18, + "oversample": 12.0, "skip_missing": true } ] diff --git a/src/main/resources/assets/saturnclient/font/inter.ttf b/src/main/resources/assets/saturnclient/font/inter.ttf new file mode 100644 index 0000000..acae361 Binary files /dev/null and b/src/main/resources/assets/saturnclient/font/inter.ttf differ diff --git a/src/main/resources/assets/saturnclient/font/panton_bold.json b/src/main/resources/assets/saturnclient/font/inter_bold.json similarity index 55% rename from src/main/resources/assets/saturnclient/font/panton_bold.json rename to src/main/resources/assets/saturnclient/font/inter_bold.json index af08781..ff7a168 100644 --- a/src/main/resources/assets/saturnclient/font/panton_bold.json +++ b/src/main/resources/assets/saturnclient/font/inter_bold.json @@ -2,10 +2,10 @@ "providers": [ { "type": "ttf", - "file": "saturnclient:panton_bold.ttf", + "file": "saturnclient:inter_bold.ttf", "shift": [0, 0], - "size": 9, - "oversample": 5.0, + "size": 18, + "oversample": 8.0, "skip_missing": true } ] diff --git a/src/main/resources/assets/saturnclient/font/inter_bold.ttf b/src/main/resources/assets/saturnclient/font/inter_bold.ttf new file mode 100644 index 0000000..cd13f60 Binary files /dev/null and b/src/main/resources/assets/saturnclient/font/inter_bold.ttf differ diff --git a/src/main/resources/assets/saturnclient/font/panton.ttf b/src/main/resources/assets/saturnclient/font/panton.ttf deleted file mode 100644 index c76e356..0000000 Binary files a/src/main/resources/assets/saturnclient/font/panton.ttf and /dev/null differ diff --git a/src/main/resources/assets/saturnclient/font/panton_bold.ttf b/src/main/resources/assets/saturnclient/font/panton_bold.ttf deleted file mode 100644 index b3bbda8..0000000 Binary files a/src/main/resources/assets/saturnclient/font/panton_bold.ttf and /dev/null differ diff --git a/src/main/resources/assets/saturnclient/icon.png b/src/main/resources/assets/saturnclient/icon.png index b4a7316..6b96974 100644 Binary files a/src/main/resources/assets/saturnclient/icon.png and b/src/main/resources/assets/saturnclient/icon.png differ diff --git a/src/main/resources/assets/saturnclient/models/item/horns/black.json b/src/main/resources/assets/saturnclient/models/item/horns/black.json index 7b77ac4..effa342 100644 --- a/src/main/resources/assets/saturnclient/models/item/horns/black.json +++ b/src/main/resources/assets/saturnclient/models/item/horns/black.json @@ -1,13 +1,13 @@ -{ - "parent": "special-model-loader:builtin/obj", - "model": "saturnclient:models/item/horns/horns.obj", - "mtl_override": "saturnclient:models/item/black.mtl", - "flip_v": true, - "display": { - "thirdperson_righthand": { - "rotation": [0, 0, 0], - "translation": [-5.08, 8.3, -0.1], - "scale": [0.065, 0.065, 0.065] - } - } -} +{ + "parent": "special-model-loader:builtin/obj", + "model": "saturnclient:models/item/horns/horns.obj", + "mtl_override": "saturnclient:models/item/black.mtl", + "flip_v": true, + "display": { + "thirdperson_righthand": { + "rotation": [0, 0, 0], + "translation": [2, 6, 2], + "scale": [0.25, 0.25, 0.25] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/saturnclient/models/item/horns/horns.obj b/src/main/resources/assets/saturnclient/models/item/horns/horns.obj index a05f572..ae6f75c 100644 --- a/src/main/resources/assets/saturnclient/models/item/horns/horns.obj +++ b/src/main/resources/assets/saturnclient/models/item/horns/horns.obj @@ -1,298 +1,297 @@ # Blender 4.4.0 # www.blender.org -mtllib halo.mtl -o Cylinder -v 9.939158 1.061044 0.424000 -v 9.856778 1.053577 0.415853 -v 9.777563 1.046397 0.391725 -v 9.704558 1.039780 0.352543 -v 9.640570 1.033980 0.299813 -v 9.588055 1.029220 0.235562 -v 9.549033 1.025683 0.162258 -v 9.525003 1.023504 0.082718 -v 9.516890 1.022769 0.000000 -v 9.525003 1.023504 -0.082718 -v 9.549033 1.025683 -0.162258 -v 9.588055 1.029220 -0.235562 -v 9.640570 1.033980 -0.299813 -v 9.704558 1.039780 -0.352543 -v 9.777563 1.046397 -0.391725 -v 9.856778 1.053577 -0.415853 -v 9.939158 1.061044 -0.424000 -v 10.021539 1.068512 -0.415853 -v 10.100754 1.075692 -0.391725 -v 10.173759 1.082309 -0.352543 -v 10.237747 1.088109 -0.299813 -v 10.290262 1.092869 -0.235562 -v 10.329284 1.096406 -0.162258 -v 10.353313 1.098584 -0.082718 -v 10.361427 1.099320 -0.000000 -v 10.353313 1.098584 0.082718 -v 10.329284 1.096406 0.162258 -v 10.290262 1.092869 0.235562 -v 10.237747 1.088109 0.299813 -v 10.173759 1.082309 0.352543 -v 10.100754 1.075692 0.391725 -v 10.021539 1.068512 0.415853 -v 9.065714 1.888010 0.180929 -v 9.038785 1.859407 0.189071 -v 9.010890 1.830575 0.189411 -v 8.983102 1.802619 0.181935 -v 8.956489 1.776615 0.166932 -v 8.932073 1.753563 0.144978 -v 8.910791 1.734347 0.116917 -v 8.893464 1.719707 0.083826 -v 8.880756 1.710204 0.046978 -v 8.873156 1.706205 0.007789 -v 8.870955 1.707863 -0.032235 -v 8.874238 1.715113 -0.071557 -v 8.882880 1.727679 -0.108665 -v 8.896547 1.745076 -0.142133 -v 8.914716 1.766636 -0.170675 -v 8.936687 1.791530 -0.193194 -v 8.961616 1.818803 -0.208824 -v 8.988545 1.847405 -0.216966 -v 9.016439 1.876238 -0.217306 -v 9.044228 1.904193 -0.209831 -v 9.070841 1.930197 -0.194828 -v 9.095258 1.953250 -0.172874 -v 9.116538 1.972466 -0.144812 -v 9.133865 1.987106 -0.111722 -v 9.146574 1.996608 -0.074874 -v 9.154174 2.000608 -0.035684 -v 9.156375 1.998950 0.004340 -v 9.153091 1.991699 0.043662 -v 9.144450 1.979134 0.080770 -v 9.130782 1.961737 0.114238 -v 9.112614 1.940177 0.142780 -v 9.090643 1.915282 0.165299 -v 8.720341 2.137514 0.013948 -v 8.808750 -1.595378 0.614293 -v 9.794410 -0.677613 0.670575 -v 8.725459 -1.504030 0.583397 -v 9.711119 -0.586265 0.639680 -v 8.648616 -1.418167 0.529000 -v 9.634275 -0.500401 0.585283 -v 8.581174 -1.341087 0.453193 -v 9.566833 -0.423321 0.509476 -v 8.525725 -1.275753 0.358889 -v 9.511385 -0.357987 0.415171 -v 8.484401 -1.224676 0.249711 -v 9.470060 -0.306910 0.305993 -v 8.458788 -1.189818 0.129855 -v 9.444448 -0.272052 0.186138 -v 8.449872 -1.172520 0.003928 -v 9.435532 -0.254754 0.060210 -v 8.457994 -1.173445 -0.123232 -v 9.443654 -0.255679 -0.066949 -v 8.482844 -1.192559 -0.246738 -v 9.468504 -0.274793 -0.190455 -v 8.523466 -1.229126 -0.361842 -v 9.509125 -0.311361 -0.305560 -v 8.578298 -1.281743 -0.464123 -v 9.563957 -0.363977 -0.407841 -v 8.645233 -1.348385 -0.549650 -v 9.630894 -0.430620 -0.493367 -v 8.721701 -1.426494 -0.615135 -v 9.707360 -0.508728 -0.558852 -v 8.804761 -1.513065 -0.658062 -v 9.790421 -0.595300 -0.601780 -v 8.891222 -1.604774 -0.676782 -v 9.876882 -0.687009 -0.620499 -v 8.977761 -1.698096 -0.670575 -v 9.963420 -0.780330 -0.614292 -v 9.061052 -1.789444 -0.639680 -v 10.046712 -0.871678 -0.583397 -v 9.137896 -1.875308 -0.585283 -v 10.123555 -0.957542 -0.529000 -v 9.205338 -1.952388 -0.509476 -v 10.190997 -1.034622 -0.453193 -v 9.260786 -2.017721 -0.415171 -v 10.246446 -1.099956 -0.358889 -v 9.302111 -2.068799 -0.305993 -v 10.287770 -1.151033 -0.249711 -v 9.327724 -2.103656 -0.186138 -v 10.313383 -1.185891 -0.129855 -v 9.336639 -2.120955 -0.060210 -v 10.322299 -1.203189 -0.003928 -v 9.328517 -2.120029 0.066949 -v 10.314177 -1.202264 0.123232 -v 9.303667 -2.100915 0.190455 -v 10.289327 -1.183150 0.246738 -v 9.263046 -2.064348 0.305560 -v 10.248706 -1.146582 0.361843 -v 9.208214 -2.011732 0.407841 -v 10.193873 -1.093966 0.464124 -v 9.141277 -1.945089 0.493367 -v 10.126937 -1.027323 0.549650 -v 9.064811 -1.866981 0.558852 -v 10.050470 -0.949215 0.615135 -v 8.981750 -1.780409 0.601780 -v 9.967410 -0.862643 0.658062 -v 8.895289 -1.688700 0.620500 -v 9.880949 -0.770934 0.676782 -v 8.498793 -1.883986 0.596593 -v 8.415501 -1.792638 0.565698 -v 8.338657 -1.706774 0.511301 -v 8.271215 -1.629695 0.435494 -v 8.215767 -1.564361 0.341190 -v 8.174442 -1.513284 0.232012 -v 8.148829 -1.478426 0.112156 -v 8.139914 -1.461128 -0.013771 -v 8.148036 -1.462053 -0.140931 -v 8.172886 -1.481167 -0.264437 -v 8.213508 -1.517735 -0.379542 -v 8.268339 -1.570351 -0.481823 -v 8.335276 -1.636993 -0.567349 -v 8.411743 -1.715101 -0.632834 -v 8.494802 -1.801673 -0.675761 -v 8.581264 -1.893382 -0.694481 -v 8.667803 -1.986704 -0.688274 -v 8.751094 -2.078052 -0.657379 -v 8.827937 -2.163915 -0.602982 -v 8.895379 -2.240995 -0.527175 -v 8.950828 -2.306329 -0.432870 -v 8.992152 -2.357407 -0.323692 -v 9.017765 -2.392264 -0.203837 -v 9.026681 -2.409563 -0.077909 -v 9.018559 -2.408637 0.049250 -v 8.993709 -2.389524 0.172756 -v 8.953088 -2.352956 0.287861 -v 8.898255 -2.300339 0.390142 -v 8.831320 -2.233697 0.475668 -v 8.754852 -2.155589 0.541153 -v 8.671792 -2.069017 0.584081 -v 8.585331 -1.977308 0.602800 -vn -0.0122 0.1414 0.9899 -vn -0.2452 0.1525 0.9574 -vn -0.4644 0.1522 0.8725 -vn -0.6520 0.1413 0.7450 -vn -0.7978 0.1230 0.5902 -vn -0.9004 0.1018 0.4230 -vn -0.9638 0.0823 0.2535 -vn -0.9939 0.0680 0.0865 -vn -0.9952 0.0610 -0.0770 -vn -0.9692 0.0620 -0.2385 -vn -0.9144 0.0700 -0.3988 -vn -0.8266 0.0831 -0.5567 -vn -0.7007 0.0980 -0.7067 -vn -0.5340 0.1107 -0.8382 -vn -0.3297 0.1173 -0.9368 -vn -0.0999 0.1150 -0.9883 -vn 0.1364 0.1036 -0.9852 -vn 0.3587 0.0849 -0.9296 -vn 0.5522 0.0623 -0.8314 -vn 0.7094 0.0392 -0.7037 -vn 0.8297 0.0184 -0.5579 -vn 0.9154 0.0015 -0.4026 -vn 0.9699 -0.0102 -0.2432 -vn 0.9964 -0.0163 -0.0826 -vn 0.9969 -0.0163 0.0771 -vn 0.9720 -0.0104 0.2348 -vn 0.9212 0.0015 0.3891 -vn 0.8428 0.0191 0.5378 -vn 0.7345 0.0415 0.6773 -vn 0.5938 0.0676 0.8018 -vn -0.4586 -0.2508 0.8525 -vn 0.4196 0.0952 0.9027 -vn 0.2146 0.1211 0.9692 -vn -0.1496 0.3985 0.9049 -vn -0.2701 0.2722 0.9235 -vn -0.3925 0.1474 0.9079 -vn -0.5121 0.0288 0.8584 -vn -0.6243 -0.0790 0.7772 -vn -0.7247 -0.1719 0.6673 -vn -0.8095 -0.2463 0.5329 -vn -0.8756 -0.2994 0.3792 -vn -0.9202 -0.3291 0.2121 -vn -0.9417 -0.3342 0.0379 -vn -0.9394 -0.3146 -0.1365 -vn -0.9131 -0.2711 -0.3044 -vn -0.8641 -0.2052 -0.4596 -vn -0.7941 -0.1196 -0.5958 -vn -0.7059 -0.0175 -0.7081 -vn -0.6028 0.0972 -0.7919 -vn -0.4889 0.2200 -0.8442 -vn -0.3684 0.3462 -0.8628 -vn -0.2460 0.4710 -0.8471 -vn -0.1264 0.5896 -0.7977 -vn -0.0143 0.6974 -0.7165 -vn 0.0862 0.7903 -0.6066 -vn 0.1710 0.8648 -0.4722 -vn 0.2371 0.9178 -0.3184 -vn 0.2817 0.9475 -0.1513 -vn 0.3032 0.9526 0.0228 -vn 0.3009 0.9331 0.1972 -vn 0.2746 0.8895 0.3652 -vn 0.2256 0.8237 0.5203 -vn 0.1556 0.7380 0.6566 -vn -0.3239 -0.0787 0.9428 -vn 0.0674 0.6359 0.7688 -vn -0.0357 0.5213 0.8526 -vn -0.5652 -0.4014 0.7208 -vn -0.6410 -0.5208 0.5637 -vn -0.6895 -0.6066 0.3956 -vn -0.7164 -0.6604 0.2252 -vn -0.7265 -0.6849 0.0559 -vn -0.7225 -0.6822 -0.1121 -vn -0.7043 -0.6525 -0.2797 -vn -0.6689 -0.5942 -0.4466 -vn -0.6116 -0.5049 -0.6091 -vn -0.5272 -0.3831 -0.7585 -vn -0.4130 -0.2313 -0.8809 -vn -0.2722 -0.0586 -0.9604 -vn -0.1154 0.1201 -0.9860 -vn 0.0429 0.2885 -0.9565 -vn 0.1893 0.4347 -0.8805 -vn 0.3152 0.5534 -0.7709 -vn 0.4173 0.6450 -0.6402 -vn 0.4953 0.7123 -0.4973 -vn 0.5505 0.7587 -0.3484 -vn 0.5845 0.7872 -0.1967 -vn 0.5985 0.7999 -0.0443 -vn 0.5931 0.7979 0.1076 -vn 0.5686 0.7811 0.2580 -vn 0.5243 0.7487 0.4055 -vn 0.4595 0.6987 0.5482 -vn 0.3731 0.6284 0.6826 -vn 0.2643 0.5345 0.8028 -vn 0.1340 0.4143 0.9002 -vn -0.0140 0.2677 0.9634 -vn -0.1710 0.0995 0.9802 -vn -0.1950 0.1500 0.9693 -vn -0.3188 0.2870 0.9033 -vn -0.4303 0.4129 0.8027 -vn -0.5253 0.5230 0.6712 -vn -0.6001 0.6130 0.5139 -vn -0.6518 0.6794 0.3369 -vn -0.6785 0.7197 0.1469 -vn -0.6792 0.7324 -0.0487 -vn -0.6537 0.7169 -0.2425 -vn -0.6031 0.6739 -0.4269 -vn -0.5293 0.6049 -0.5949 -vn -0.4352 0.5127 -0.7401 -vn -0.3243 0.4008 -0.8568 -vn -0.2010 0.2736 -0.9406 -vn -0.0700 0.1358 -0.9883 -vn 0.0637 -0.0073 -0.9979 -vn 0.1950 -0.1500 -0.9693 -vn 0.3188 -0.2870 -0.9033 -vn 0.4303 -0.4129 -0.8027 -vn 0.5253 -0.5230 -0.6712 -vn 0.6001 -0.6130 -0.5139 -vn 0.6518 -0.6794 -0.3369 -vn 0.6785 -0.7197 -0.1469 -vn 0.6792 -0.7324 0.0487 -vn 0.6537 -0.7169 0.2425 -vn 0.6031 -0.6739 0.4269 -vn 0.5293 -0.6049 0.5949 -vn 0.4352 -0.5127 0.7401 -vn 0.3243 -0.4009 0.8568 -vn 0.2010 -0.2736 0.9406 -vn 0.0700 -0.1358 0.9883 -vn -0.0637 0.0073 0.9979 -vn -0.7312 -0.6809 -0.0418 -vn 0.3243 -0.4008 0.8568 +mtllib horns.mtl +o Cylinder.002 +v -1.242236 1.125547 0.100000 +v -0.992896 1.414159 0.021275 +v -1.261081 1.130596 0.098079 +v -0.996905 1.415234 0.020866 +v -1.279201 1.135451 0.092388 +v -1.000761 1.416267 0.019656 +v -1.295900 1.139926 0.083147 +v -1.004313 1.417219 0.017690 +v -1.310538 1.143848 0.070711 +v -1.007428 1.418053 0.015044 +v -1.322550 1.147067 0.055557 +v -1.009983 1.418738 0.011820 +v -1.331476 1.149459 0.038268 +v -1.011882 1.419247 0.008142 +v -1.336973 1.150931 0.019509 +v -1.013052 1.419560 0.004151 +v -1.338829 1.151429 0.000000 +v -1.013447 1.419666 -0.000000 +v -1.336973 1.150931 -0.019509 +v -1.013052 1.419560 -0.004151 +v -1.331476 1.149459 -0.038268 +v -1.011882 1.419247 -0.008142 +v -1.322550 1.147067 -0.055557 +v -1.009983 1.418738 -0.011820 +v -1.310538 1.143848 -0.070711 +v -1.007428 1.418053 -0.015044 +v -1.295900 1.139926 -0.083147 +v -1.004313 1.417219 -0.017690 +v -1.279201 1.135451 -0.092388 +v -1.000761 1.416267 -0.019656 +v -1.261081 1.130596 -0.098079 +v -0.996905 1.415234 -0.020866 +v -1.242236 1.125547 -0.100000 +v -0.992896 1.414159 -0.021275 +v -1.223392 1.120497 -0.098079 +v -0.988887 1.413085 -0.020866 +v -1.205272 1.115642 -0.092388 +v -0.985032 1.412052 -0.019656 +v -1.188572 1.111168 -0.083147 +v -0.981479 1.411100 -0.017690 +v -1.173935 1.107245 -0.070711 +v -0.978365 1.410266 -0.015044 +v -1.161923 1.104027 -0.055557 +v -0.975809 1.409581 -0.011820 +v -1.152996 1.101635 -0.038268 +v -0.973910 1.409072 -0.008142 +v -1.147500 1.100162 -0.019509 +v -0.972741 1.408759 -0.004151 +v -1.145644 1.099665 -0.000000 +v -0.972346 1.408653 -0.000000 +v -1.147500 1.100162 0.019509 +v -0.972741 1.408759 0.004151 +v -1.152996 1.101635 0.038268 +v -0.973910 1.409072 0.008142 +v -1.161923 1.104027 0.055557 +v -0.975809 1.409581 0.011820 +v -1.173935 1.107245 0.070711 +v -0.978365 1.410266 0.015044 +v -1.188572 1.111168 0.083147 +v -0.981479 1.411100 0.017690 +v -1.205272 1.115642 0.092388 +v -0.985032 1.412052 0.019656 +v -1.223392 1.120497 0.098079 +v -0.988887 1.413085 0.020866 +v -1.211112 0.788704 0.150000 +v -1.235372 0.772340 0.147118 +v -1.258701 0.756605 0.138582 +v -1.280200 0.742103 0.124720 +v -1.299044 0.729392 0.106066 +v -1.314510 0.718961 0.083336 +v -1.326001 0.711210 0.057403 +v -1.333078 0.706437 0.029264 +v -1.335467 0.704825 0.000000 +v -1.333078 0.706437 -0.029264 +v -1.326001 0.711210 -0.057403 +v -1.314510 0.718961 -0.083336 +v -1.299044 0.729392 -0.106066 +v -1.280200 0.742103 -0.124720 +v -1.258701 0.756605 -0.138582 +v -1.235372 0.772340 -0.147118 +v -1.211112 0.788704 -0.150000 +v -1.186851 0.805068 -0.147118 +v -1.163523 0.820803 -0.138582 +v -1.142023 0.835304 -0.124720 +v -1.123179 0.848015 -0.106066 +v -1.107714 0.858447 -0.083336 +v -1.096222 0.866198 -0.057403 +v -1.089146 0.870971 -0.029264 +v -1.086756 0.872583 -0.000000 +v -1.089146 0.870971 0.029264 +v -1.096222 0.866198 0.057403 +v -1.107714 0.858447 0.083336 +v -1.123179 0.848015 0.106066 +v -1.142023 0.835304 0.124720 +v -1.163523 0.820803 0.138582 +v -1.186851 0.805068 0.147118 +v -0.880525 0.487694 0.190000 +v -1.067972 0.630938 0.190000 +v -0.901786 0.457330 0.186349 +v -1.089233 0.600574 0.186349 +v -0.922230 0.428133 0.175537 +v -1.109677 0.571377 0.175537 +v -0.941071 0.401225 0.157979 +v -1.128518 0.544469 0.157979 +v -0.957585 0.377640 0.134350 +v -1.145033 0.520884 0.134350 +v -0.971138 0.358285 0.105558 +v -1.158586 0.501529 0.105558 +v -0.981209 0.343902 0.072710 +v -1.168656 0.487146 0.072710 +v -0.987411 0.335045 0.037067 +v -1.174858 0.478289 0.037067 +v -0.989505 0.332055 -0.000000 +v -1.176952 0.475299 -0.000000 +v -0.987411 0.335045 -0.037067 +v -1.174858 0.478289 -0.037067 +v -0.981209 0.343902 -0.072710 +v -1.168656 0.487146 -0.072710 +v -0.971138 0.358285 -0.105558 +v -1.158586 0.501529 -0.105558 +v -0.957585 0.377640 -0.134350 +v -1.145033 0.520884 -0.134350 +v -0.941071 0.401225 -0.157979 +v -1.128518 0.544469 -0.157979 +v -0.922230 0.428133 -0.175537 +v -1.109677 0.571377 -0.175537 +v -0.901786 0.457330 -0.186349 +v -1.089233 0.600574 -0.186349 +v -0.880525 0.487694 -0.190000 +v -1.067972 0.630938 -0.190000 +v -0.859264 0.518057 -0.186349 +v -1.046712 0.661301 -0.186349 +v -0.838820 0.547254 -0.175537 +v -1.026268 0.690498 -0.175537 +v -0.819979 0.574162 -0.157979 +v -1.007427 0.717406 -0.157979 +v -0.803465 0.597747 -0.134350 +v -0.990912 0.740991 -0.134350 +v -0.789912 0.617103 -0.105558 +v -0.977359 0.760347 -0.105558 +v -0.779841 0.631485 -0.072710 +v -0.967288 0.774729 -0.072710 +v -0.773640 0.640342 -0.037067 +v -0.961087 0.783586 -0.037067 +v -0.771546 0.643333 -0.000000 +v -0.958993 0.786576 -0.000000 +v -0.773640 0.640342 0.037067 +v -0.961087 0.783586 0.037067 +v -0.779841 0.631485 0.072710 +v -0.967288 0.774729 0.072710 +v -0.789912 0.617103 0.105558 +v -0.977359 0.760347 0.105558 +v -0.803465 0.597747 0.134350 +v -0.990912 0.740991 0.134350 +v -0.819979 0.574162 0.157979 +v -1.007427 0.717406 0.157979 +v -0.838820 0.547254 0.175537 +v -1.026268 0.690498 0.175537 +v -0.859264 0.518057 0.186349 +v -1.046712 0.661301 0.186349 +vn -0.0225 0.2811 0.9594 +vn -0.1736 0.4046 0.8979 +vn -0.3068 0.5120 0.8023 +vn -0.4181 0.6006 0.6815 +vn -0.5061 0.6697 0.5434 +vn -0.5708 0.7202 0.3943 +vn -0.6132 0.7530 0.2388 +vn -0.6341 0.7691 0.0799 +vn -0.6341 0.7691 -0.0799 +vn -0.6132 0.7530 -0.2388 +vn -0.5708 0.7202 -0.3943 +vn -0.5061 0.6697 -0.5434 +vn -0.4181 0.6006 -0.6815 +vn -0.3068 0.5120 -0.8023 +vn -0.1736 0.4046 -0.8979 +vn -0.0225 0.2811 -0.9594 +vn 0.1392 0.1469 -0.9793 +vn 0.3019 0.0096 -0.9533 +vn 0.4554 -0.1219 -0.8819 +vn 0.5905 -0.2396 -0.7706 +vn 0.7015 -0.3374 -0.6277 +vn 0.7851 -0.4120 -0.4624 +vn 0.8407 -0.4620 -0.2826 +vn 0.8682 -0.4870 -0.0950 +vn 0.8682 -0.4870 0.0950 +vn 0.8407 -0.4620 0.2826 +vn 0.7851 -0.4120 0.4624 +vn 0.7015 -0.3374 0.6277 +vn 0.5905 -0.2396 0.7706 +vn 0.4554 -0.1219 0.8819 +vn 0.2588 0.9659 -0.0000 +vn 0.3019 0.0096 0.9533 +vn 0.1392 0.1469 0.9793 +vn 0.0687 0.1567 0.9853 +vn 0.0722 0.3343 0.9397 +vn -0.0596 -0.0779 0.9952 +vn -0.1764 -0.2308 0.9569 +vn -0.2864 -0.3748 0.8818 +vn -0.3854 -0.5043 0.7727 +vn -0.4695 -0.6144 0.6341 +vn -0.5356 -0.7009 0.4711 +vn -0.5811 -0.7604 0.2901 +vn -0.6043 -0.7907 0.0979 +vn -0.6043 -0.7907 -0.0979 +vn -0.5811 -0.7604 -0.2901 +vn -0.5356 -0.7009 -0.4711 +vn -0.4695 -0.6144 -0.6341 +vn -0.3854 -0.5043 -0.7727 +vn -0.2864 -0.3748 -0.8818 +vn -0.1764 -0.2308 -0.9569 +vn -0.0596 -0.0779 -0.9952 +vn 0.0596 0.0779 -0.9952 +vn 0.1764 0.2308 -0.9569 +vn 0.2864 0.3748 -0.8818 +vn 0.3854 0.5043 -0.7727 +vn 0.4695 0.6144 -0.6341 +vn 0.5356 0.7009 -0.4711 +vn 0.5811 0.7604 -0.2901 +vn 0.6043 0.7907 -0.0979 +vn 0.6043 0.7907 0.0979 +vn 0.5811 0.7604 0.2901 +vn 0.5356 0.7009 0.4711 +vn 0.4695 0.6144 0.6341 +vn 0.3854 0.5043 0.7727 +vn 0.2864 0.3748 0.8818 +vn -0.0628 0.1980 0.9782 +vn 0.1764 0.2308 0.9569 +vn 0.0596 0.0779 0.9952 +vn 0.8192 -0.5736 -0.0000 +vn 0.1987 0.4621 0.8642 +vn 0.3116 0.5764 0.7554 +vn 0.4067 0.6728 0.6180 +vn 0.4805 0.7479 0.4579 +vn 0.5310 0.7993 0.2814 +vn 0.5565 0.8254 0.0949 +vn 0.5565 0.8254 -0.0949 +vn 0.5310 0.7993 -0.2814 +vn 0.4805 0.7479 -0.4579 +vn 0.4067 0.6728 -0.6180 +vn 0.3116 0.5764 -0.7554 +vn 0.1987 0.4621 -0.8642 +vn 0.0722 0.3343 -0.9397 +vn -0.0628 0.1980 -0.9782 +vn -0.2008 0.0589 -0.9779 +vn -0.3357 -0.0772 -0.9388 +vn -0.4620 -0.2046 -0.8629 +vn -0.5747 -0.3184 -0.7539 +vn -0.6696 -0.4141 -0.6166 +vn -0.7434 -0.4887 -0.4567 +vn -0.7938 -0.5396 -0.2806 +vn -0.8194 -0.5654 -0.0946 +vn -0.8194 -0.5654 0.0946 +vn -0.7938 -0.5396 0.2806 +vn -0.7434 -0.4887 0.4567 +vn -0.6696 -0.4141 0.6166 +vn -0.5747 -0.3184 0.7539 +vn -0.4620 -0.2046 0.8629 +vn -0.3357 -0.0772 0.9388 +vn -0.2008 0.0589 0.9779 +vn 0.2759 0.1827 0.9437 +vn 0.4667 0.2045 0.8604 +vn 0.6317 0.2217 0.7429 +vn 0.7653 0.2341 0.5996 +vn 0.8653 0.2424 0.4388 +vn 0.9314 0.2474 0.2671 +vn 0.9642 0.2497 0.0896 +vn 0.9642 0.2497 -0.0896 +vn 0.9314 0.2474 -0.2671 +vn 0.8653 0.2424 -0.4388 +vn 0.7653 0.2341 -0.5996 +vn 0.6317 0.2217 -0.7429 +vn 0.4667 0.2045 -0.8604 +vn 0.2759 0.1827 -0.9437 +vn 0.0687 0.1567 -0.9853 +vn -0.1430 0.1281 -0.9814 +vn -0.3462 0.0988 -0.9330 +vn -0.5298 0.0708 -0.8452 +vn -0.6862 0.0458 -0.7260 +vn -0.8115 0.0249 -0.5838 +vn -0.9046 0.0090 -0.4262 +vn -0.9659 -0.0018 -0.2591 +vn -0.9962 -0.0072 -0.0869 +vn -0.9962 -0.0072 0.0869 +vn -0.9659 -0.0018 0.2591 +vn -0.9046 0.0090 0.4262 +vn -0.8115 0.0249 0.5838 +vn -0.6862 0.0458 0.7260 +vn -0.5298 0.0708 0.8452 +vn -0.3462 0.0988 0.9330 +vn -0.1430 0.1281 0.9814 vt 1.000000 0.500000 vt 1.000000 1.000000 vt 0.968750 1.000000 @@ -355,43 +354,42 @@ vt 0.093750 1.000000 vt 0.093750 0.500000 vt 0.062500 1.000000 vt 0.062500 0.500000 -vt 0.419706 0.419706 +vt 0.296822 0.485388 +vt 0.250000 0.490000 +vt 0.203178 0.485388 +vt 0.158156 0.471731 +vt 0.116663 0.449553 +vt 0.080294 0.419706 +vt 0.050447 0.383337 +vt 0.028269 0.341844 +vt 0.014612 0.296822 +vt 0.010000 0.250000 +vt 0.014612 0.203178 +vt 0.028269 0.158156 +vt 0.050447 0.116663 +vt 0.080294 0.080294 +vt 0.116663 0.050447 +vt 0.158156 0.028269 +vt 0.203178 0.014612 +vt 0.250000 0.010000 +vt 0.296822 0.014612 +vt 0.341844 0.028269 +vt 0.383337 0.050447 +vt 0.419706 0.080294 +vt 0.449553 0.116663 +vt 0.471731 0.158156 +vt 0.485388 0.203178 +vt 0.490000 0.250000 +vt 0.485388 0.296822 +vt 0.471731 0.341844 vt 0.449553 0.383337 +vt 0.419706 0.419706 +vt 0.383337 0.449553 +vt 0.341844 0.471731 vt 0.031250 1.000000 vt 0.031250 0.500000 vt 0.000000 1.000000 vt 0.000000 0.500000 -vt 0.250000 0.490000 -vt 0.250000 0.250000 -vt 0.296822 0.485388 -vt 0.341844 0.471731 -vt 0.383337 0.449553 -vt 0.471731 0.341844 -vt 0.485388 0.296822 -vt 0.490000 0.250000 -vt 0.485388 0.203178 -vt 0.471731 0.158156 -vt 0.449553 0.116663 -vt 0.419706 0.080294 -vt 0.383337 0.050447 -vt 0.341844 0.028269 -vt 0.296822 0.014612 -vt 0.250000 0.010000 -vt 0.203178 0.014612 -vt 0.158156 0.028269 -vt 0.116663 0.050447 -vt 0.080294 0.080294 -vt 0.050447 0.116663 -vt 0.028269 0.158156 -vt 0.014612 0.203178 -vt 0.010000 0.250000 -vt 0.014612 0.296822 -vt 0.028269 0.341844 -vt 0.050447 0.383337 -vt 0.080294 0.419706 -vt 0.116663 0.449553 -vt 0.158156 0.471731 -vt 0.203178 0.485388 vt 0.750000 0.490000 vt 0.796822 0.485388 vt 0.841844 0.471731 @@ -426,471 +424,427 @@ vt 0.658156 0.471731 vt 0.703178 0.485388 usemtl tex s off -f 129/1/1 1/2/1 2/3/1 67/4/1 -f 67/4/2 2/3/2 3/5/2 69/6/2 -f 69/6/3 3/5/3 4/7/3 71/8/3 -f 71/8/4 4/7/4 5/9/4 73/10/4 -f 73/10/5 5/9/5 6/11/5 75/12/5 -f 75/12/6 6/11/6 7/13/6 77/14/6 -f 77/14/7 7/13/7 8/15/7 79/16/7 -f 79/16/8 8/15/8 9/17/8 81/18/8 -f 81/18/9 9/17/9 10/19/9 83/20/9 -f 83/20/10 10/19/10 11/21/10 85/22/10 -f 85/22/11 11/21/11 12/23/11 87/24/11 -f 87/24/12 12/23/12 13/25/12 89/26/12 -f 89/26/13 13/25/13 14/27/13 91/28/13 -f 91/28/14 14/27/14 15/29/14 93/30/14 -f 93/30/15 15/29/15 16/31/15 95/32/15 -f 95/32/16 16/31/16 17/33/16 97/34/16 -f 97/34/17 17/33/17 18/35/17 99/36/17 -f 99/36/18 18/35/18 19/37/18 101/38/18 -f 101/38/19 19/37/19 20/39/19 103/40/19 -f 103/40/20 20/39/20 21/41/20 105/42/20 -f 105/42/21 21/41/21 22/43/21 107/44/21 -f 107/44/22 22/43/22 23/45/22 109/46/22 -f 109/46/23 23/45/23 24/47/23 111/48/23 -f 111/48/24 24/47/24 25/49/24 113/50/24 -f 113/50/25 25/49/25 26/51/25 115/52/25 -f 115/52/26 26/51/26 27/53/26 117/54/26 -f 117/54/27 27/53/27 28/55/27 119/56/27 -f 119/56/28 28/55/28 29/57/28 121/58/28 -f 121/58/29 29/57/29 30/59/29 123/60/29 -f 123/60/30 30/59/30 31/61/30 125/62/30 -f 37/63/31 38/64/31 4/7/31 3/5/31 -f 125/62/32 31/61/32 32/65/32 127/66/32 -f 127/66/33 32/65/33 1/67/33 129/68/33 -f 33/69/34 65/70/34 34/71/34 -f 34/71/35 65/70/35 35/72/35 -f 35/72/36 65/70/36 36/73/36 -f 36/73/37 65/70/37 37/63/37 -f 37/63/38 65/70/38 38/64/38 -f 38/64/39 65/70/39 39/74/39 -f 39/74/40 65/70/40 40/75/40 -f 40/75/41 65/70/41 41/76/41 -f 41/76/42 65/70/42 42/77/42 -f 42/77/43 65/70/43 43/78/43 -f 43/78/44 65/70/44 44/79/44 -f 44/79/45 65/70/45 45/80/45 -f 45/80/46 65/70/46 46/81/46 -f 46/81/47 65/70/47 47/82/47 -f 47/82/48 65/70/48 48/83/48 -f 48/83/49 65/70/49 49/84/49 -f 49/84/50 65/70/50 50/85/50 -f 50/85/51 65/70/51 51/86/51 -f 51/86/52 65/70/52 52/87/52 -f 52/87/53 65/70/53 53/88/53 -f 53/88/54 65/70/54 54/89/54 -f 54/89/55 65/70/55 55/90/55 -f 55/90/56 65/70/56 56/91/56 -f 56/91/57 65/70/57 57/92/57 -f 57/92/58 65/70/58 58/93/58 -f 58/93/59 65/70/59 59/94/59 -f 59/94/60 65/70/60 60/95/60 -f 60/95/61 65/70/61 61/96/61 -f 61/96/62 65/70/62 62/97/62 -f 62/97/63 65/70/63 63/98/63 -f 36/73/64 37/63/64 3/5/64 2/3/64 -f 63/98/65 65/70/65 64/99/65 -f 64/99/66 65/70/66 33/69/66 -f 38/64/67 39/74/67 5/9/67 4/7/67 -f 39/74/68 40/75/68 6/11/68 5/9/68 -f 40/75/69 41/76/69 7/13/69 6/11/69 -f 41/76/70 42/77/70 8/15/70 7/13/70 -f 42/77/71 43/78/71 9/17/71 8/15/71 -f 43/78/72 44/79/72 10/19/72 9/17/72 -f 44/79/73 45/80/73 11/21/73 10/19/73 -f 45/80/74 46/81/74 12/23/74 11/21/74 -f 46/81/75 47/82/75 13/25/75 12/23/75 -f 47/82/76 48/83/76 14/27/76 13/25/76 -f 48/83/77 49/84/77 15/29/77 14/27/77 -f 49/84/78 50/85/78 16/31/78 15/29/78 -f 50/85/79 51/86/79 17/33/79 16/31/79 -f 51/86/80 52/87/80 18/35/80 17/33/80 -f 52/87/81 53/88/81 19/37/81 18/35/81 -f 53/88/82 54/89/82 20/39/82 19/37/82 -f 54/89/83 55/90/83 21/41/83 20/39/83 -f 55/90/84 56/91/84 22/43/84 21/41/84 -f 56/91/85 57/92/85 23/45/85 22/43/85 -f 57/92/86 58/93/86 24/47/86 23/45/86 -f 58/93/87 59/94/87 25/49/87 24/47/87 -f 59/94/88 60/95/88 26/51/88 25/49/88 -f 60/95/89 61/96/89 27/53/89 26/51/89 -f 61/96/90 62/97/90 28/55/90 27/53/90 -f 62/97/91 63/98/91 29/57/91 28/55/91 -f 63/98/92 64/99/92 30/59/92 29/57/92 -f 64/99/93 33/69/93 31/61/93 30/59/93 -f 33/69/94 34/71/94 32/65/94 31/61/94 -f 34/71/95 35/72/95 1/67/95 32/65/95 -f 35/72/96 36/73/96 2/3/96 1/2/96 -f 66/1/97 67/2/97 69/3/97 68/4/97 -f 68/4/98 69/3/98 71/5/98 70/6/98 -f 70/6/99 71/5/99 73/7/99 72/8/99 -f 72/8/100 73/7/100 75/9/100 74/10/100 -f 74/10/101 75/9/101 77/11/101 76/12/101 -f 76/12/102 77/11/102 79/13/102 78/14/102 -f 78/14/103 79/13/103 81/15/103 80/16/103 -f 80/16/104 81/15/104 83/17/104 82/18/104 -f 82/18/105 83/17/105 85/19/105 84/20/105 -f 84/20/106 85/19/106 87/21/106 86/22/106 -f 86/22/107 87/21/107 89/23/107 88/24/107 -f 88/24/108 89/23/108 91/25/108 90/26/108 -f 90/26/109 91/25/109 93/27/109 92/28/109 -f 92/28/110 93/27/110 95/29/110 94/30/110 -f 94/30/111 95/29/111 97/31/111 96/32/111 -f 96/32/112 97/31/112 99/33/112 98/34/112 -f 98/34/113 99/33/113 101/35/113 100/36/113 -f 100/36/114 101/35/114 103/37/114 102/38/114 -f 102/38/115 103/37/115 105/39/115 104/40/115 -f 104/40/116 105/39/116 107/41/116 106/42/116 -f 106/42/117 107/41/117 109/43/117 108/44/117 -f 108/44/118 109/43/118 111/45/118 110/46/118 -f 110/46/119 111/45/119 113/47/119 112/48/119 -f 112/48/120 113/47/120 115/49/120 114/50/120 -f 114/50/121 115/49/121 117/51/121 116/52/121 -f 116/52/122 117/51/122 119/53/122 118/54/122 -f 118/54/123 119/53/123 121/55/123 120/56/123 -f 120/56/124 121/55/124 123/57/124 122/58/124 -f 122/58/125 123/57/125 125/59/125 124/60/125 -f 124/60/126 125/59/126 127/61/126 126/62/126 -f 126/62/127 127/61/127 129/65/127 128/66/127 -f 128/66/128 129/65/128 67/67/128 66/68/128 -f 74/10/101 76/12/101 135/12/101 134/10/101 -f 130/100/129 131/101/129 132/102/129 133/103/129 134/104/129 135/105/129 136/106/129 137/107/129 138/108/129 139/109/129 140/110/129 141/111/129 142/112/129 143/113/129 144/114/129 145/115/129 146/116/129 147/117/129 148/118/129 149/119/129 150/120/129 151/121/129 152/122/129 153/123/129 154/124/129 155/125/129 156/126/129 157/127/129 158/128/129 159/129/129 160/130/129 161/131/129 -f 92/28/110 94/30/110 144/30/110 143/28/110 -f 110/46/119 112/48/119 153/48/119 152/46/119 -f 66/1/97 68/4/97 131/4/97 130/1/97 -f 128/66/128 66/68/128 130/68/128 161/66/128 -f 84/20/106 86/22/106 140/22/106 139/20/106 -f 102/38/115 104/40/115 149/40/115 148/38/115 -f 120/56/124 122/58/124 158/58/124 157/56/124 -f 76/12/102 78/14/102 136/14/102 135/12/102 -f 94/30/111 96/32/111 145/32/111 144/30/111 -f 112/48/120 114/50/120 154/50/120 153/48/120 -f 68/4/98 70/6/98 132/6/98 131/4/98 -f 86/22/107 88/24/107 141/24/107 140/22/107 -f 104/40/116 106/42/116 150/42/116 149/40/116 -f 122/58/130 124/60/130 159/60/130 158/58/130 -f 78/14/103 80/16/103 137/16/103 136/14/103 -f 96/32/112 98/34/112 146/34/112 145/32/112 -f 114/50/121 116/52/121 155/52/121 154/50/121 -f 70/6/99 72/8/99 133/8/99 132/6/99 -f 88/24/108 90/26/108 142/26/108 141/24/108 -f 106/42/117 108/44/117 151/44/117 150/42/117 -f 124/60/126 126/62/126 160/62/126 159/60/126 -f 80/16/104 82/18/104 138/18/104 137/16/104 -f 98/34/113 100/36/113 147/36/113 146/34/113 -f 116/52/122 118/54/122 156/54/122 155/52/122 -f 72/8/100 74/10/100 134/10/100 133/8/100 -f 90/26/109 92/28/109 143/28/109 142/26/109 -f 108/44/118 110/46/118 152/46/118 151/44/118 -f 126/62/127 128/66/127 161/66/127 160/62/127 -f 82/18/105 84/20/105 139/20/105 138/18/105 -f 100/36/114 102/38/114 148/38/114 147/36/114 -f 118/54/123 120/56/123 157/56/123 156/54/123 -o Cylinder.001 -v 0.894254 1.061044 -0.424000 -v 0.976634 1.053577 -0.415853 -v 1.055849 1.046397 -0.391725 -v 1.128854 1.039780 -0.352543 -v 1.192843 1.033980 -0.299813 -v 1.245357 1.029220 -0.235562 -v 1.284379 1.025683 -0.162258 -v 1.308409 1.023504 -0.082718 -v 1.316523 1.022769 0.000000 -v 1.308409 1.023504 0.082718 -v 1.284379 1.025683 0.162258 -v 1.245357 1.029220 0.235562 -v 1.192843 1.033980 0.299813 -v 1.128854 1.039780 0.352543 -v 1.055849 1.046397 0.391725 -v 0.976634 1.053577 0.415853 -v 0.894254 1.061044 0.424000 -v 0.811873 1.068512 0.415853 -v 0.732658 1.075692 0.391725 -v 0.659654 1.082309 0.352543 -v 0.595665 1.088109 0.299813 -v 0.543150 1.092869 0.235562 -v 0.504128 1.096406 0.162258 -v 0.480099 1.098584 0.082718 -v 0.471985 1.099320 0.000000 -v 0.480099 1.098584 -0.082718 -v 0.504128 1.096406 -0.162258 -v 0.543150 1.092869 -0.235562 -v 0.595665 1.088109 -0.299813 -v 0.659654 1.082309 -0.352543 -v 0.732658 1.075692 -0.391725 -v 0.811873 1.068512 -0.415853 -v 1.767698 1.888010 -0.180929 -v 1.794627 1.859407 -0.189071 -v 1.822522 1.830575 -0.189411 -v 1.850310 1.802619 -0.181935 -v 1.876923 1.776615 -0.166932 -v 1.901340 1.753563 -0.144978 -v 1.922621 1.734347 -0.116917 -v 1.939948 1.719707 -0.083826 -v 1.952656 1.710204 -0.046978 -v 1.960256 1.706205 -0.007789 -v 1.962457 1.707863 0.032236 -v 1.959174 1.715113 0.071557 -v 1.950532 1.727679 0.108665 -v 1.936865 1.745076 0.142133 -v 1.918696 1.766636 0.170675 -v 1.896726 1.791530 0.193194 -v 1.871796 1.818803 0.208825 -v 1.844867 1.847405 0.216966 -v 1.816972 1.876238 0.217306 -v 1.789184 1.904193 0.209831 -v 1.762571 1.930197 0.194828 -v 1.738155 1.953250 0.172874 -v 1.716874 1.972466 0.144812 -v 1.699547 1.987106 0.111722 -v 1.686839 1.996608 0.074874 -v 1.679238 2.000608 0.035684 -v 1.677037 1.998950 -0.004340 -v 1.680321 1.991699 -0.043662 -v 1.688962 1.979134 -0.080770 -v 1.702630 1.961737 -0.114238 -v 1.720798 1.940177 -0.142780 -v 1.742769 1.915282 -0.165299 -v 2.113071 2.137514 -0.013948 -v 2.024662 -1.595378 -0.614292 -v 1.039002 -0.677613 -0.670575 -v 2.107953 -1.504030 -0.583397 -v 1.122294 -0.586265 -0.639680 -v 2.184796 -1.418167 -0.529000 -v 1.199137 -0.500401 -0.585283 -v 2.252238 -1.341087 -0.453193 -v 1.266579 -0.423321 -0.509476 -v 2.307687 -1.275753 -0.358889 -v 1.322027 -0.357987 -0.415171 -v 2.349011 -1.224676 -0.249711 -v 1.363352 -0.306910 -0.305993 -v 2.374624 -1.189818 -0.129855 -v 1.388965 -0.272052 -0.186138 -v 2.383540 -1.172520 -0.003928 -v 1.397881 -0.254754 -0.060210 -v 2.375418 -1.173445 0.123232 -v 1.389758 -0.255679 0.066949 -v 2.350568 -1.192559 0.246738 -v 1.364908 -0.274793 0.190455 -v 2.309947 -1.229126 0.361843 -v 1.324287 -0.311361 0.305560 -v 2.255114 -1.281743 0.464124 -v 1.269455 -0.363977 0.407841 -v 2.188179 -1.348385 0.549650 -v 1.202519 -0.430620 0.493367 -v 2.111711 -1.426494 0.615135 -v 1.126052 -0.508728 0.558852 -v 2.028651 -1.513065 0.658062 -v 1.042992 -0.595300 0.601780 -v 1.942190 -1.604774 0.676782 -v 0.956531 -0.687009 0.620499 -v 1.855651 -1.698096 0.670575 -v 0.869992 -0.780330 0.614292 -v 1.772360 -1.789444 0.639680 -v 0.786700 -0.871678 0.583397 -v 1.695517 -1.875308 0.585283 -v 0.709857 -0.957542 0.529000 -v 1.628075 -1.952388 0.509476 -v 0.642415 -1.034622 0.453193 -v 1.572626 -2.017721 0.415171 -v 0.586967 -1.099956 0.358889 -v 1.531301 -2.068799 0.305993 -v 0.545642 -1.151033 0.249711 -v 1.505689 -2.103656 0.186138 -v 0.520029 -1.185891 0.129855 -v 1.496773 -2.120955 0.060210 -v 0.511113 -1.203189 0.003928 -v 1.504895 -2.120029 -0.066949 -v 0.519236 -1.202264 -0.123232 -v 1.529745 -2.100915 -0.190455 -v 0.544085 -1.183150 -0.246738 -v 1.570366 -2.064348 -0.305560 -v 0.584707 -1.146582 -0.361843 -v 1.625199 -2.011732 -0.407841 -v 0.639539 -1.093966 -0.464124 -v 1.692134 -1.945089 -0.493367 -v 0.706475 -1.027323 -0.549650 -v 1.768602 -1.866981 -0.558852 -v 0.782942 -0.949215 -0.615135 -v 1.851662 -1.780409 -0.601780 -v 0.866002 -0.862643 -0.658062 -v 1.938123 -1.688700 -0.620499 -v 0.952463 -0.770934 -0.676782 -v 2.334620 -1.883986 -0.596593 -v 2.417911 -1.792638 -0.565698 -v 2.494755 -1.706774 -0.511301 -v 2.562196 -1.629694 -0.435494 -v 2.617645 -1.564361 -0.341189 -v 2.658970 -1.513283 -0.232011 -v 1.673310 -0.595518 -0.288294 -v 2.684582 -1.478426 -0.112156 -v 2.693499 -1.461127 0.013772 -v 2.685376 -1.462053 0.140931 -v 2.660526 -1.481167 0.264437 -v 2.619905 -1.517734 0.379542 -v 2.565073 -1.570350 0.481823 -v 2.498137 -1.636993 0.567349 -v 2.421669 -1.715101 0.632834 -v 2.338609 -1.801673 0.675762 -v 2.252149 -1.893382 0.694481 -v 2.165610 -1.986704 0.688274 -v 2.082318 -2.078052 0.657379 -v 2.005475 -2.163915 0.602982 -v 1.019815 -1.246150 0.546699 -v 1.938033 -2.240995 0.527175 -v 0.952374 -1.323230 0.470892 -v 1.882584 -2.306329 0.432870 -v 1.841260 -2.357406 0.323692 -v 1.815647 -2.392264 0.203837 -v 1.806731 -2.409563 0.077909 -v 1.814854 -2.408637 -0.049250 -v 1.839703 -2.389523 -0.172756 -v 1.880325 -2.352956 -0.287861 -v 0.894665 -1.435190 -0.344144 -v 1.935157 -2.300339 -0.390142 -v 0.949497 -1.382574 -0.446425 -v 2.002093 -2.233697 -0.475668 -v 2.078560 -2.155589 -0.541153 -v 1.092901 -1.237823 -0.597436 -v 2.161620 -2.069016 -0.584081 -v 2.248081 -1.977308 -0.602800 -vn 0.0122 0.1414 -0.9899 -vn 0.2452 0.1525 -0.9574 -vn 0.4644 0.1522 -0.8725 -vn 0.6520 0.1413 -0.7450 -vn 0.7978 0.1230 -0.5902 -vn 0.9004 0.1018 -0.4230 -vn 0.9638 0.0823 -0.2535 -vn 0.9939 0.0680 -0.0865 -vn 0.9952 0.0610 0.0770 -vn 0.9692 0.0620 0.2385 -vn 0.9144 0.0700 0.3988 -vn 0.8266 0.0831 0.5567 -vn 0.7007 0.0980 0.7067 -vn 0.5340 0.1107 0.8382 -vn 0.3297 0.1173 0.9368 -vn 0.0999 0.1150 0.9883 -vn -0.1364 0.1036 0.9852 -vn -0.3587 0.0849 0.9296 -vn -0.5522 0.0623 0.8314 -vn -0.7094 0.0392 0.7037 -vn -0.8297 0.0184 0.5579 -vn -0.9154 0.0015 0.4026 -vn -0.9699 -0.0102 0.2432 -vn -0.9964 -0.0163 0.0826 -vn -0.9969 -0.0163 -0.0771 -vn -0.9720 -0.0104 -0.2349 -vn -0.9212 0.0015 -0.3891 -vn -0.8428 0.0191 -0.5378 -vn -0.7345 0.0415 -0.6773 -vn -0.5938 0.0676 -0.8018 -vn 0.4586 -0.2508 -0.8525 -vn -0.4196 0.0952 -0.9027 -vn -0.2146 0.1211 -0.9692 -vn 0.1496 0.3985 -0.9049 -vn 0.2701 0.2722 -0.9235 -vn 0.3925 0.1474 -0.9079 -vn 0.5121 0.0288 -0.8584 -vn 0.6243 -0.0790 -0.7772 -vn 0.7247 -0.1719 -0.6673 -vn 0.8095 -0.2463 -0.5329 -vn 0.8756 -0.2994 -0.3792 -vn 0.9202 -0.3291 -0.2120 -vn 0.9417 -0.3342 -0.0379 -vn 0.9394 -0.3146 0.1365 -vn 0.9131 -0.2711 0.3044 -vn 0.8641 -0.2052 0.4596 -vn 0.7941 -0.1196 0.5958 -vn 0.7059 -0.0175 0.7081 -vn 0.6028 0.0972 0.7919 -vn 0.4889 0.2200 0.8442 -vn 0.3684 0.3462 0.8628 -vn 0.2460 0.4710 0.8471 -vn 0.1264 0.5896 0.7977 -vn 0.0143 0.6974 0.7165 -vn -0.0862 0.7903 0.6066 -vn -0.1710 0.8648 0.4722 -vn -0.2371 0.9178 0.3184 -vn -0.2817 0.9475 0.1513 -vn -0.3032 0.9526 -0.0228 -vn -0.3009 0.9331 -0.1972 -vn -0.2746 0.8895 -0.3652 -vn -0.2256 0.8237 -0.5203 -vn -0.1556 0.7380 -0.6566 -vn 0.3239 -0.0787 -0.9428 -vn -0.0674 0.6359 -0.7688 -vn 0.0357 0.5213 -0.8526 -vn 0.5652 -0.4014 -0.7208 -vn 0.6410 -0.5208 -0.5637 -vn 0.6895 -0.6066 -0.3956 -vn 0.7164 -0.6604 -0.2252 -vn 0.7265 -0.6849 -0.0559 -vn 0.7225 -0.6822 0.1121 -vn 0.7043 -0.6525 0.2797 -vn 0.6689 -0.5942 0.4466 -vn 0.6116 -0.5049 0.6091 -vn 0.5272 -0.3831 0.7585 -vn 0.4130 -0.2313 0.8809 -vn 0.2722 -0.0586 0.9604 -vn 0.1154 0.1201 0.9860 -vn -0.0429 0.2885 0.9565 -vn -0.1893 0.4347 0.8805 -vn -0.3152 0.5534 0.7709 -vn -0.4173 0.6450 0.6402 -vn -0.4953 0.7123 0.4973 -vn -0.5505 0.7587 0.3484 -vn -0.5845 0.7872 0.1967 -vn -0.5985 0.7999 0.0443 -vn -0.5931 0.7979 -0.1076 -vn -0.5686 0.7811 -0.2580 -vn -0.5243 0.7487 -0.4055 -vn -0.4595 0.6987 -0.5482 -vn -0.3731 0.6284 -0.6826 -vn -0.2643 0.5345 -0.8028 -vn -0.1340 0.4143 -0.9002 -vn 0.0140 0.2677 -0.9634 -vn 0.1710 0.0995 -0.9802 -vn 0.1950 0.1500 -0.9693 -vn 0.3188 0.2870 -0.9033 -vn 0.4303 0.4129 -0.8027 -vn 0.5253 0.5230 -0.6712 -vn 0.6001 0.6130 -0.5139 -vn 0.6518 0.6794 -0.3369 -vn 0.6785 0.7197 -0.1469 -vn 0.6792 0.7324 0.0487 -vn 0.6537 0.7169 0.2425 -vn 0.6031 0.6739 0.4269 -vn 0.5293 0.6049 0.5949 -vn 0.4352 0.5127 0.7401 -vn 0.3243 0.4008 0.8568 -vn 0.2010 0.2736 0.9406 -vn 0.0700 0.1358 0.9883 -vn -0.0637 -0.0073 0.9979 -vn -0.1950 -0.1500 0.9693 -vn -0.3188 -0.2870 0.9033 -vn -0.4303 -0.4129 0.8027 -vn -0.5253 -0.5230 0.6712 -vn -0.6001 -0.6130 0.5139 -vn -0.6518 -0.6794 0.3369 -vn -0.6785 -0.7197 0.1469 -vn -0.6792 -0.7324 -0.0487 -vn -0.6537 -0.7169 -0.2425 -vn -0.6031 -0.6739 -0.4269 -vn -0.5293 -0.6049 -0.5949 -vn -0.4352 -0.5127 -0.7401 -vn -0.3243 -0.4009 -0.8568 -vn -0.2010 -0.2736 -0.9406 -vn -0.0700 -0.1358 -0.9883 -vn 0.0637 0.0073 -0.9979 -vn 0.7312 -0.6809 0.0418 -vn 0.2532 0.5001 0.8281 -vn 0.3243 0.4009 0.8568 -vn 0.3471 0.4782 0.8068 -vn 0.1526 0.5179 0.8417 -vn 0.6903 0.7235 -0.0000 -vn 0.2415 -0.0219 0.9701 -vn -0.3243 -0.4008 -0.8568 +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 6/5/2 5/6/2 +f 5/6/3 6/5/3 8/7/3 7/8/3 +f 7/8/4 8/7/4 10/9/4 9/10/4 +f 9/10/5 10/9/5 12/11/5 11/12/5 +f 11/12/6 12/11/6 14/13/6 13/14/6 +f 13/14/7 14/13/7 16/15/7 15/16/7 +f 15/16/8 16/15/8 18/17/8 17/18/8 +f 17/18/9 18/17/9 20/19/9 19/20/9 +f 19/20/10 20/19/10 22/21/10 21/22/10 +f 21/22/11 22/21/11 24/23/11 23/24/11 +f 23/24/12 24/23/12 26/25/12 25/26/12 +f 25/26/13 26/25/13 28/27/13 27/28/13 +f 27/28/14 28/27/14 30/29/14 29/30/14 +f 29/30/15 30/29/15 32/31/15 31/32/15 +f 31/32/16 32/31/16 34/33/16 33/34/16 +f 33/34/17 34/33/17 36/35/17 35/36/17 +f 35/36/18 36/35/18 38/37/18 37/38/18 +f 37/38/19 38/37/19 40/39/19 39/40/19 +f 39/40/20 40/39/20 42/41/20 41/42/20 +f 41/42/21 42/41/21 44/43/21 43/44/21 +f 43/44/22 44/43/22 46/45/22 45/46/22 +f 45/46/23 46/45/23 48/47/23 47/48/23 +f 47/48/24 48/47/24 50/49/24 49/50/24 +f 49/50/25 50/49/25 52/51/25 51/52/25 +f 51/52/26 52/51/26 54/53/26 53/54/26 +f 53/54/27 54/53/27 56/55/27 55/56/27 +f 55/56/28 56/55/28 58/57/28 57/58/28 +f 57/58/29 58/57/29 60/59/29 59/60/29 +f 59/60/30 60/59/30 62/61/30 61/62/30 +f 4/63/31 2/64/31 64/65/31 62/66/31 60/67/31 58/68/31 56/69/31 54/70/31 52/71/31 50/72/31 48/73/31 46/74/31 44/75/31 42/76/31 40/77/31 38/78/31 36/79/31 34/80/31 32/81/31 30/82/31 28/83/31 26/84/31 24/85/31 22/86/31 20/87/31 18/88/31 16/89/31 14/90/31 12/91/31 10/92/31 8/93/31 6/94/31 +f 61/62/32 62/61/32 64/95/32 63/96/32 +f 63/96/33 64/95/33 2/97/33 1/98/33 +f 65/98/34 96/96/34 63/96/34 1/98/34 +f 160/95/35 158/61/35 95/62/35 96/96/35 +f 97/1/36 98/2/36 100/3/36 99/4/36 +f 99/4/37 100/3/37 102/5/37 101/6/37 +f 101/6/38 102/5/38 104/7/38 103/8/38 +f 103/8/39 104/7/39 106/9/39 105/10/39 +f 105/10/40 106/9/40 108/11/40 107/12/40 +f 107/12/41 108/11/41 110/13/41 109/14/41 +f 109/14/42 110/13/42 112/15/42 111/16/42 +f 111/16/43 112/15/43 114/17/43 113/18/43 +f 113/18/44 114/17/44 116/19/44 115/20/44 +f 115/20/45 116/19/45 118/21/45 117/22/45 +f 117/22/46 118/21/46 120/23/46 119/24/46 +f 119/24/47 120/23/47 122/25/47 121/26/47 +f 121/26/48 122/25/48 124/27/48 123/28/48 +f 123/28/49 124/27/49 126/29/49 125/30/49 +f 125/30/50 126/29/50 128/31/50 127/32/50 +f 127/32/51 128/31/51 130/33/51 129/34/51 +f 129/34/52 130/33/52 132/35/52 131/36/52 +f 131/36/53 132/35/53 134/37/53 133/38/53 +f 133/38/54 134/37/54 136/39/54 135/40/54 +f 135/40/55 136/39/55 138/41/55 137/42/55 +f 137/42/56 138/41/56 140/43/56 139/44/56 +f 139/44/57 140/43/57 142/45/57 141/46/57 +f 141/46/58 142/45/58 144/47/58 143/48/58 +f 143/48/59 144/47/59 146/49/59 145/50/59 +f 145/50/60 146/49/60 148/51/60 147/52/60 +f 147/52/61 148/51/61 150/53/61 149/54/61 +f 149/54/62 150/53/62 152/55/62 151/56/62 +f 151/56/63 152/55/63 154/57/63 153/58/63 +f 153/58/64 154/57/64 156/59/64 155/60/64 +f 155/60/65 156/59/65 158/61/65 157/62/65 +f 98/97/66 160/95/66 96/96/66 65/98/66 +f 157/62/67 158/61/67 160/95/67 159/96/67 +f 159/96/68 160/95/68 98/97/68 97/98/68 +f 97/99/69 99/100/69 101/101/69 103/102/69 105/103/69 107/104/69 109/105/69 111/106/69 113/107/69 115/108/69 117/109/69 119/110/69 121/111/69 123/112/69 125/113/69 127/114/69 129/115/69 131/116/69 133/117/69 135/118/69 137/119/69 139/120/69 141/121/69 143/122/69 145/123/69 147/124/69 149/125/69 151/126/69 153/127/69 155/128/69 157/129/69 159/130/69 +f 158/61/70 156/59/70 94/60/70 95/62/70 +f 156/59/71 154/57/71 93/58/71 94/60/71 +f 154/57/72 152/55/72 92/56/72 93/58/72 +f 152/55/73 150/53/73 91/54/73 92/56/73 +f 150/53/74 148/51/74 90/52/74 91/54/74 +f 148/51/75 146/49/75 89/50/75 90/52/75 +f 146/49/76 144/47/76 88/48/76 89/50/76 +f 144/47/77 142/45/77 87/46/77 88/48/77 +f 142/45/78 140/43/78 86/44/78 87/46/78 +f 140/43/79 138/41/79 85/42/79 86/44/79 +f 138/41/80 136/39/80 84/40/80 85/42/80 +f 136/39/81 134/37/81 83/38/81 84/40/81 +f 134/37/82 132/35/82 82/36/82 83/38/82 +f 132/35/83 130/33/83 81/34/83 82/36/83 +f 130/33/84 128/31/84 80/32/84 81/34/84 +f 128/31/85 126/29/85 79/30/85 80/32/85 +f 126/29/86 124/27/86 78/28/86 79/30/86 +f 124/27/87 122/25/87 77/26/87 78/28/87 +f 122/25/88 120/23/88 76/24/88 77/26/88 +f 120/23/89 118/21/89 75/22/89 76/24/89 +f 118/21/90 116/19/90 74/20/90 75/22/90 +f 116/19/91 114/17/91 73/18/91 74/20/91 +f 114/17/92 112/15/92 72/16/92 73/18/92 +f 112/15/93 110/13/93 71/14/93 72/16/93 +f 110/13/94 108/11/94 70/12/94 71/14/94 +f 108/11/95 106/9/95 69/10/95 70/12/95 +f 106/9/96 104/7/96 68/8/96 69/10/96 +f 104/7/97 102/5/97 67/6/97 68/8/97 +f 102/5/98 100/3/98 66/4/98 67/6/98 +f 100/3/99 98/2/99 65/1/99 66/4/99 +f 96/96/100 95/62/100 61/62/100 63/96/100 +f 95/62/101 94/60/101 59/60/101 61/62/101 +f 94/60/102 93/58/102 57/58/102 59/60/102 +f 93/58/103 92/56/103 55/56/103 57/58/103 +f 92/56/104 91/54/104 53/54/104 55/56/104 +f 91/54/105 90/52/105 51/52/105 53/54/105 +f 90/52/106 89/50/106 49/50/106 51/52/106 +f 89/50/107 88/48/107 47/48/107 49/50/107 +f 88/48/108 87/46/108 45/46/108 47/48/108 +f 87/46/109 86/44/109 43/44/109 45/46/109 +f 86/44/110 85/42/110 41/42/110 43/44/110 +f 85/42/111 84/40/111 39/40/111 41/42/111 +f 84/40/112 83/38/112 37/38/112 39/40/112 +f 83/38/113 82/36/113 35/36/113 37/38/113 +f 82/36/114 81/34/114 33/34/114 35/36/114 +f 81/34/115 80/32/115 31/32/115 33/34/115 +f 80/32/116 79/30/116 29/30/116 31/32/116 +f 79/30/117 78/28/117 27/28/117 29/30/117 +f 78/28/118 77/26/118 25/26/118 27/28/118 +f 77/26/119 76/24/119 23/24/119 25/26/119 +f 76/24/120 75/22/120 21/22/120 23/24/120 +f 75/22/121 74/20/121 19/20/121 21/22/121 +f 74/20/122 73/18/122 17/18/122 19/20/122 +f 73/18/123 72/16/123 15/16/123 17/18/123 +f 72/16/124 71/14/124 13/14/124 15/16/124 +f 71/14/125 70/12/125 11/12/125 13/14/125 +f 70/12/126 69/10/126 9/10/126 11/12/126 +f 69/10/127 68/8/127 7/8/127 9/10/127 +f 68/8/128 67/6/128 5/6/128 7/8/128 +f 67/6/129 66/4/129 3/4/129 5/6/129 +f 66/4/130 65/1/130 1/1/130 3/4/130 +o Cylinder.003 +v 1.242236 1.125547 -0.100000 +v 0.992896 1.414159 -0.021275 +v 1.261081 1.130596 -0.098079 +v 0.996905 1.415234 -0.020866 +v 1.279201 1.135451 -0.092388 +v 1.000761 1.416267 -0.019656 +v 1.295900 1.139926 -0.083147 +v 1.004313 1.417219 -0.017690 +v 1.310538 1.143848 -0.070711 +v 1.007428 1.418053 -0.015044 +v 1.322550 1.147067 -0.055557 +v 1.009983 1.418738 -0.011820 +v 1.331476 1.149459 -0.038268 +v 1.011882 1.419247 -0.008142 +v 1.336973 1.150931 -0.019509 +v 1.013052 1.419560 -0.004151 +v 1.338829 1.151429 0.000000 +v 1.013447 1.419666 0.000000 +v 1.336973 1.150931 0.019509 +v 1.013052 1.419560 0.004151 +v 1.331476 1.149459 0.038268 +v 1.011882 1.419247 0.008142 +v 1.322550 1.147067 0.055557 +v 1.009983 1.418738 0.011820 +v 1.310538 1.143848 0.070711 +v 1.007428 1.418053 0.015044 +v 1.295900 1.139926 0.083147 +v 1.004313 1.417219 0.017690 +v 1.279201 1.135451 0.092388 +v 1.000761 1.416267 0.019656 +v 1.261081 1.130596 0.098079 +v 0.996905 1.415234 0.020866 +v 1.242236 1.125547 0.100000 +v 0.992896 1.414159 0.021275 +v 1.223392 1.120497 0.098079 +v 0.988887 1.413085 0.020866 +v 1.205272 1.115642 0.092388 +v 0.985032 1.412052 0.019656 +v 1.188572 1.111168 0.083147 +v 0.981479 1.411100 0.017690 +v 1.173935 1.107245 0.070711 +v 0.978365 1.410266 0.015044 +v 1.161923 1.104027 0.055557 +v 0.975809 1.409581 0.011820 +v 1.152996 1.101635 0.038268 +v 0.973910 1.409072 0.008142 +v 1.147500 1.100162 0.019509 +v 0.972741 1.408759 0.004151 +v 1.145644 1.099665 0.000000 +v 0.972346 1.408653 0.000000 +v 1.147500 1.100162 -0.019509 +v 0.972741 1.408759 -0.004151 +v 1.152996 1.101635 -0.038268 +v 0.973910 1.409072 -0.008142 +v 1.161923 1.104027 -0.055557 +v 0.975809 1.409581 -0.011820 +v 1.173935 1.107245 -0.070711 +v 0.978365 1.410266 -0.015044 +v 1.188572 1.111168 -0.083147 +v 0.981479 1.411100 -0.017690 +v 1.205272 1.115642 -0.092388 +v 0.985032 1.412052 -0.019656 +v 1.223392 1.120497 -0.098079 +v 0.988887 1.413085 -0.020866 +v 1.211112 0.788704 -0.150000 +v 1.235372 0.772340 -0.147118 +v 1.258701 0.756605 -0.138582 +v 1.280200 0.742103 -0.124720 +v 1.299044 0.729392 -0.106066 +v 1.314510 0.718961 -0.083336 +v 1.326001 0.711210 -0.057403 +v 1.333078 0.706437 -0.029264 +v 1.335467 0.704825 0.000000 +v 1.333078 0.706437 0.029264 +v 1.326001 0.711210 0.057403 +v 1.314510 0.718961 0.083336 +v 1.299044 0.729392 0.106066 +v 1.280200 0.742103 0.124720 +v 1.258701 0.756605 0.138582 +v 1.235372 0.772340 0.147118 +v 1.211112 0.788704 0.150000 +v 1.186851 0.805068 0.147118 +v 1.163523 0.820803 0.138582 +v 1.142023 0.835304 0.124720 +v 1.123179 0.848015 0.106066 +v 1.107714 0.858447 0.083336 +v 1.096222 0.866198 0.057403 +v 1.089146 0.870971 0.029264 +v 1.086756 0.872583 0.000000 +v 1.089146 0.870971 -0.029264 +v 1.096222 0.866198 -0.057403 +v 1.107714 0.858447 -0.083336 +v 1.123179 0.848015 -0.106066 +v 1.142023 0.835304 -0.124720 +v 1.163523 0.820803 -0.138582 +v 1.186851 0.805068 -0.147118 +v 0.880525 0.487694 -0.190000 +v 1.067972 0.630938 -0.190000 +v 0.901786 0.457330 -0.186349 +v 1.089233 0.600574 -0.186349 +v 0.922230 0.428133 -0.175537 +v 1.109677 0.571377 -0.175537 +v 0.941071 0.401225 -0.157979 +v 1.128518 0.544469 -0.157979 +v 0.957585 0.377640 -0.134350 +v 1.145033 0.520884 -0.134350 +v 0.971138 0.358285 -0.105558 +v 1.158586 0.501529 -0.105558 +v 0.981209 0.343902 -0.072710 +v 1.168656 0.487146 -0.072710 +v 0.987411 0.335045 -0.037067 +v 1.174858 0.478289 -0.037067 +v 0.989505 0.332055 -0.000000 +v 1.176952 0.475299 0.000000 +v 0.987411 0.335045 0.037067 +v 1.174858 0.478289 0.037067 +v 0.981209 0.343902 0.072710 +v 1.168656 0.487146 0.072710 +v 0.971138 0.358285 0.105558 +v 1.158586 0.501529 0.105558 +v 0.957585 0.377640 0.134350 +v 1.145033 0.520884 0.134350 +v 0.941071 0.401225 0.157979 +v 1.128518 0.544469 0.157979 +v 0.922230 0.428133 0.175537 +v 1.109677 0.571377 0.175537 +v 0.901786 0.457330 0.186349 +v 1.089233 0.600574 0.186349 +v 0.880525 0.487694 0.190000 +v 1.067972 0.630938 0.190000 +v 0.859264 0.518057 0.186349 +v 1.046712 0.661301 0.186349 +v 0.838820 0.547254 0.175537 +v 1.026268 0.690498 0.175537 +v 0.819979 0.574162 0.157979 +v 1.007427 0.717406 0.157979 +v 0.803465 0.597747 0.134350 +v 0.990912 0.740991 0.134350 +v 0.789912 0.617103 0.105558 +v 0.977359 0.760347 0.105558 +v 0.779841 0.631485 0.072710 +v 0.967288 0.774729 0.072710 +v 0.773640 0.640342 0.037067 +v 0.961087 0.783586 0.037067 +v 0.771546 0.643333 -0.000000 +v 0.958993 0.786576 0.000000 +v 0.773640 0.640342 -0.037067 +v 0.961087 0.783586 -0.037067 +v 0.779841 0.631485 -0.072710 +v 0.967288 0.774729 -0.072710 +v 0.789912 0.617103 -0.105558 +v 0.977359 0.760347 -0.105558 +v 0.803465 0.597747 -0.134350 +v 0.990912 0.740991 -0.134350 +v 0.819979 0.574162 -0.157979 +v 1.007427 0.717406 -0.157979 +v 0.838820 0.547254 -0.175537 +v 1.026268 0.690498 -0.175537 +v 0.859264 0.518057 -0.186349 +v 1.046712 0.661301 -0.186349 +vn 0.0225 0.2811 -0.9594 +vn 0.1736 0.4046 -0.8979 +vn 0.3068 0.5120 -0.8023 +vn 0.4181 0.6006 -0.6815 +vn 0.5061 0.6697 -0.5434 +vn 0.5708 0.7202 -0.3943 +vn 0.6132 0.7530 -0.2388 +vn 0.6341 0.7691 -0.0799 +vn 0.6341 0.7691 0.0799 +vn 0.6132 0.7530 0.2388 +vn 0.5708 0.7202 0.3943 +vn 0.5061 0.6697 0.5434 +vn 0.4181 0.6006 0.6815 +vn 0.3068 0.5120 0.8023 +vn 0.1736 0.4046 0.8979 +vn 0.0225 0.2811 0.9594 +vn -0.1392 0.1469 0.9793 +vn -0.3019 0.0096 0.9533 +vn -0.4554 -0.1219 0.8819 +vn -0.5905 -0.2396 0.7706 +vn -0.7015 -0.3374 0.6277 +vn -0.7851 -0.4120 0.4624 +vn -0.8407 -0.4620 0.2826 +vn -0.8682 -0.4870 0.0950 +vn -0.8682 -0.4870 -0.0950 +vn -0.8407 -0.4620 -0.2826 +vn -0.7851 -0.4120 -0.4624 +vn -0.7015 -0.3374 -0.6277 +vn -0.5905 -0.2396 -0.7706 +vn -0.4554 -0.1219 -0.8819 +vn -0.2588 0.9659 -0.0000 +vn -0.3019 0.0096 -0.9533 +vn -0.1392 0.1469 -0.9793 +vn -0.0687 0.1567 -0.9853 +vn -0.0722 0.3343 -0.9397 +vn 0.0596 -0.0779 -0.9952 +vn 0.1764 -0.2308 -0.9569 +vn 0.2864 -0.3748 -0.8818 +vn 0.3854 -0.5043 -0.7727 +vn 0.4695 -0.6144 -0.6341 +vn 0.5356 -0.7009 -0.4711 +vn 0.5811 -0.7604 -0.2901 +vn 0.6043 -0.7907 -0.0979 +vn 0.6043 -0.7907 0.0979 +vn 0.5811 -0.7604 0.2901 +vn 0.5356 -0.7009 0.4711 +vn 0.4695 -0.6144 0.6341 +vn 0.3854 -0.5043 0.7727 +vn 0.2864 -0.3748 0.8818 +vn 0.1764 -0.2308 0.9569 +vn 0.0596 -0.0779 0.9952 +vn -0.0596 0.0779 0.9952 +vn -0.1764 0.2308 0.9569 +vn -0.2864 0.3748 0.8818 +vn -0.3854 0.5043 0.7727 +vn -0.4695 0.6144 0.6341 +vn -0.5356 0.7009 0.4711 +vn -0.5811 0.7604 0.2901 +vn -0.6043 0.7907 0.0979 +vn -0.6043 0.7907 -0.0979 +vn -0.5811 0.7604 -0.2901 +vn -0.5356 0.7009 -0.4711 +vn -0.4695 0.6144 -0.6341 +vn -0.3854 0.5043 -0.7727 +vn -0.2864 0.3748 -0.8818 +vn 0.0628 0.1980 -0.9782 +vn -0.1764 0.2308 -0.9569 +vn -0.0596 0.0779 -0.9952 +vn -0.8192 -0.5736 -0.0000 +vn -0.1987 0.4621 -0.8642 +vn -0.3116 0.5764 -0.7554 +vn -0.4067 0.6728 -0.6180 +vn -0.4805 0.7479 -0.4579 +vn -0.5310 0.7993 -0.2814 +vn -0.5565 0.8254 -0.0949 +vn -0.5565 0.8254 0.0949 +vn -0.5310 0.7993 0.2814 +vn -0.4805 0.7479 0.4579 +vn -0.4067 0.6728 0.6180 +vn -0.3116 0.5764 0.7554 +vn -0.1987 0.4621 0.8642 +vn -0.0722 0.3343 0.9397 +vn 0.0628 0.1980 0.9782 +vn 0.2008 0.0589 0.9779 +vn 0.3357 -0.0772 0.9388 +vn 0.4620 -0.2046 0.8629 +vn 0.5747 -0.3184 0.7539 +vn 0.6696 -0.4141 0.6166 +vn 0.7434 -0.4887 0.4567 +vn 0.7938 -0.5396 0.2806 +vn 0.8194 -0.5654 0.0946 +vn 0.8194 -0.5654 -0.0946 +vn 0.7938 -0.5396 -0.2806 +vn 0.7434 -0.4887 -0.4567 +vn 0.6696 -0.4141 -0.6166 +vn 0.5747 -0.3184 -0.7539 +vn 0.4620 -0.2046 -0.8629 +vn 0.3357 -0.0772 -0.9388 +vn 0.2008 0.0589 -0.9779 +vn -0.2759 0.1827 -0.9437 +vn -0.4667 0.2045 -0.8604 +vn -0.6317 0.2217 -0.7429 +vn -0.7653 0.2341 -0.5996 +vn -0.8653 0.2424 -0.4388 +vn -0.9314 0.2474 -0.2671 +vn -0.9642 0.2497 -0.0896 +vn -0.9642 0.2497 0.0896 +vn -0.9314 0.2474 0.2671 +vn -0.8653 0.2424 0.4388 +vn -0.7653 0.2341 0.5996 +vn -0.6317 0.2217 0.7429 +vn -0.4667 0.2045 0.8604 +vn -0.2759 0.1827 0.9437 +vn -0.0687 0.1567 0.9853 +vn 0.1430 0.1281 0.9814 +vn 0.3462 0.0988 0.9330 +vn 0.5298 0.0708 0.8452 +vn 0.6862 0.0458 0.7260 +vn 0.8115 0.0249 0.5838 +vn 0.9046 0.0090 0.4262 +vn 0.9659 -0.0018 0.2591 +vn 0.9962 -0.0072 0.0869 +vn 0.9962 -0.0072 -0.0869 +vn 0.9659 -0.0018 -0.2591 +vn 0.9046 0.0090 -0.4262 +vn 0.8115 0.0249 -0.5838 +vn 0.6862 0.0458 -0.7260 +vn 0.5298 0.0708 -0.8452 +vn 0.3462 0.0988 -0.9330 +vn 0.1430 0.1281 -0.9814 vt 1.000000 0.500000 vt 1.000000 1.000000 vt 0.968750 1.000000 @@ -953,43 +907,42 @@ vt 0.093750 1.000000 vt 0.093750 0.500000 vt 0.062500 1.000000 vt 0.062500 0.500000 -vt 0.419706 0.419706 +vt 0.296822 0.485388 +vt 0.250000 0.490000 +vt 0.203178 0.485388 +vt 0.158156 0.471731 +vt 0.116663 0.449553 +vt 0.080294 0.419706 +vt 0.050447 0.383337 +vt 0.028269 0.341844 +vt 0.014612 0.296822 +vt 0.010000 0.250000 +vt 0.014612 0.203178 +vt 0.028269 0.158156 +vt 0.050447 0.116663 +vt 0.080294 0.080294 +vt 0.116663 0.050447 +vt 0.158156 0.028269 +vt 0.203178 0.014612 +vt 0.250000 0.010000 +vt 0.296822 0.014612 +vt 0.341844 0.028269 +vt 0.383337 0.050447 +vt 0.419706 0.080294 +vt 0.449553 0.116663 +vt 0.471731 0.158156 +vt 0.485388 0.203178 +vt 0.490000 0.250000 +vt 0.485388 0.296822 +vt 0.471731 0.341844 vt 0.449553 0.383337 +vt 0.419706 0.419706 +vt 0.383337 0.449553 +vt 0.341844 0.471731 vt 0.031250 1.000000 vt 0.031250 0.500000 vt 0.000000 1.000000 vt 0.000000 0.500000 -vt 0.250000 0.490000 -vt 0.250000 0.250000 -vt 0.296822 0.485388 -vt 0.341844 0.471731 -vt 0.383337 0.449553 -vt 0.471731 0.341844 -vt 0.485388 0.296822 -vt 0.490000 0.250000 -vt 0.485388 0.203178 -vt 0.471731 0.158156 -vt 0.449553 0.116663 -vt 0.419706 0.080294 -vt 0.383337 0.050447 -vt 0.341844 0.028269 -vt 0.296822 0.014612 -vt 0.250000 0.010000 -vt 0.203178 0.014612 -vt 0.158156 0.028269 -vt 0.116663 0.050447 -vt 0.080294 0.080294 -vt 0.050447 0.116663 -vt 0.028269 0.158156 -vt 0.014612 0.203178 -vt 0.010000 0.250000 -vt 0.014612 0.296822 -vt 0.028269 0.341844 -vt 0.050447 0.383337 -vt 0.080294 0.419706 -vt 0.116663 0.449553 -vt 0.158156 0.471731 -vt 0.203178 0.485388 vt 0.750000 0.490000 vt 0.796822 0.485388 vt 0.841844 0.471731 @@ -1024,170 +977,133 @@ vt 0.658156 0.471731 vt 0.703178 0.485388 usemtl tex s off -f 290/132/131 162/133/131 163/134/131 228/135/131 -f 228/135/132 163/134/132 164/136/132 230/137/132 -f 230/137/133 164/136/133 165/138/133 232/139/133 -f 232/139/134 165/138/134 166/140/134 234/141/134 -f 234/141/135 166/140/135 167/142/135 236/143/135 -f 236/143/136 167/142/136 168/144/136 238/145/136 -f 238/145/137 168/144/137 169/146/137 240/147/137 -f 240/147/138 169/146/138 170/148/138 242/149/138 -f 242/149/139 170/148/139 171/150/139 244/151/139 -f 244/151/140 171/150/140 172/152/140 246/153/140 -f 246/153/141 172/152/141 173/154/141 248/155/141 -f 248/155/142 173/154/142 174/156/142 250/157/142 -f 250/157/143 174/156/143 175/158/143 252/159/143 -f 252/159/144 175/158/144 176/160/144 254/161/144 -f 254/161/145 176/160/145 177/162/145 256/163/145 -f 256/163/146 177/162/146 178/164/146 258/165/146 -f 258/165/147 178/164/147 179/166/147 260/167/147 -f 260/167/148 179/166/148 180/168/148 262/169/148 -f 262/169/149 180/168/149 181/170/149 264/171/149 -f 264/171/150 181/170/150 182/172/150 266/173/150 -f 266/173/151 182/172/151 183/174/151 268/175/151 -f 268/175/152 183/174/152 184/176/152 270/177/152 -f 270/177/153 184/176/153 185/178/153 272/179/153 -f 272/179/154 185/178/154 186/180/154 274/181/154 -f 274/181/155 186/180/155 187/182/155 276/183/155 -f 276/183/156 187/182/156 188/184/156 278/185/156 -f 278/185/157 188/184/157 189/186/157 280/187/157 -f 280/187/158 189/186/158 190/188/158 282/189/158 -f 282/189/159 190/188/159 191/190/159 284/191/159 -f 284/191/160 191/190/160 192/192/160 286/193/160 -f 198/194/161 199/195/161 165/138/161 164/136/161 -f 286/193/162 192/192/162 193/196/162 288/197/162 -f 288/197/163 193/196/163 162/198/163 290/199/163 -f 194/200/164 226/201/164 195/202/164 -f 195/202/165 226/201/165 196/203/165 -f 196/203/166 226/201/166 197/204/166 -f 197/204/167 226/201/167 198/194/167 -f 198/194/168 226/201/168 199/195/168 -f 199/195/169 226/201/169 200/205/169 -f 200/205/170 226/201/170 201/206/170 -f 201/206/171 226/201/171 202/207/171 -f 202/207/172 226/201/172 203/208/172 -f 203/208/173 226/201/173 204/209/173 -f 204/209/174 226/201/174 205/210/174 -f 205/210/175 226/201/175 206/211/175 -f 206/211/176 226/201/176 207/212/176 -f 207/212/177 226/201/177 208/213/177 -f 208/213/178 226/201/178 209/214/178 -f 209/214/179 226/201/179 210/215/179 -f 210/215/180 226/201/180 211/216/180 -f 211/216/181 226/201/181 212/217/181 -f 212/217/182 226/201/182 213/218/182 -f 213/218/183 226/201/183 214/219/183 -f 214/219/184 226/201/184 215/220/184 -f 215/220/185 226/201/185 216/221/185 -f 216/221/186 226/201/186 217/222/186 -f 217/222/187 226/201/187 218/223/187 -f 218/223/188 226/201/188 219/224/188 -f 219/224/189 226/201/189 220/225/189 -f 220/225/190 226/201/190 221/226/190 -f 221/226/191 226/201/191 222/227/191 -f 222/227/192 226/201/192 223/228/192 -f 223/228/193 226/201/193 224/229/193 -f 197/204/194 198/194/194 164/136/194 163/134/194 -f 224/229/195 226/201/195 225/230/195 -f 225/230/196 226/201/196 194/200/196 -f 199/195/197 200/205/197 166/140/197 165/138/197 -f 200/205/198 201/206/198 167/142/198 166/140/198 -f 201/206/199 202/207/199 168/144/199 167/142/199 -f 202/207/200 203/208/200 169/146/200 168/144/200 -f 203/208/201 204/209/201 170/148/201 169/146/201 -f 204/209/202 205/210/202 171/150/202 170/148/202 -f 205/210/203 206/211/203 172/152/203 171/150/203 -f 206/211/204 207/212/204 173/154/204 172/152/204 -f 207/212/205 208/213/205 174/156/205 173/154/205 -f 208/213/206 209/214/206 175/158/206 174/156/206 -f 209/214/207 210/215/207 176/160/207 175/158/207 -f 210/215/208 211/216/208 177/162/208 176/160/208 -f 211/216/209 212/217/209 178/164/209 177/162/209 -f 212/217/210 213/218/210 179/166/210 178/164/210 -f 213/218/211 214/219/211 180/168/211 179/166/211 -f 214/219/212 215/220/212 181/170/212 180/168/212 -f 215/220/213 216/221/213 182/172/213 181/170/213 -f 216/221/214 217/222/214 183/174/214 182/172/214 -f 217/222/215 218/223/215 184/176/215 183/174/215 -f 218/223/216 219/224/216 185/178/216 184/176/216 -f 219/224/217 220/225/217 186/180/217 185/178/217 -f 220/225/218 221/226/218 187/182/218 186/180/218 -f 221/226/219 222/227/219 188/184/219 187/182/219 -f 222/227/220 223/228/220 189/186/220 188/184/220 -f 223/228/221 224/229/221 190/188/221 189/186/221 -f 224/229/222 225/230/222 191/190/222 190/188/222 -f 225/230/223 194/200/223 192/192/223 191/190/223 -f 194/200/224 195/202/224 193/196/224 192/192/224 -f 195/202/225 196/203/225 162/198/225 193/196/225 -f 196/203/226 197/204/226 163/134/226 162/133/226 -f 227/132/227 228/133/227 230/134/227 229/135/227 -f 229/135/228 230/134/228 232/136/228 231/137/228 -f 231/137/229 232/136/229 234/138/229 233/139/229 -f 233/139/230 234/138/230 236/140/230 235/141/230 -f 235/141/231 236/140/231 238/142/231 237/143/231 -f 237/143/232 238/142/232 240/144/232 239/145/232 -f 239/145/233 240/144/233 242/146/233 241/147/233 -f 241/147/234 242/146/234 244/148/234 243/149/234 -f 243/149/235 244/148/235 246/150/235 245/151/235 -f 245/151/236 246/150/236 248/152/236 247/153/236 -f 247/153/237 248/152/237 250/154/237 249/155/237 -f 249/155/238 250/154/238 252/156/238 251/157/238 -f 251/157/239 252/156/239 254/158/239 253/159/239 -f 253/159/240 254/158/240 256/160/240 255/161/240 -f 255/161/241 256/160/241 258/162/241 257/163/241 -f 257/163/242 258/162/242 260/164/242 259/165/242 -f 259/165/243 260/164/243 262/166/243 261/167/243 -f 261/167/244 262/166/244 264/168/244 263/169/244 -f 263/169/245 264/168/245 266/170/245 265/171/245 -f 265/171/246 266/170/246 268/172/246 267/173/246 -f 267/173/247 268/172/247 270/174/247 269/175/247 -f 269/175/248 270/174/248 272/176/248 271/177/248 -f 271/177/249 272/176/249 274/178/249 273/179/249 -f 273/179/250 274/178/250 276/180/250 275/181/250 -f 275/181/251 276/180/251 278/182/251 277/183/251 -f 277/183/252 278/182/252 280/184/252 279/185/252 -f 279/185/253 280/184/253 282/186/253 281/187/253 -f 281/187/254 282/186/254 284/188/254 283/189/254 -f 283/189/255 284/188/255 286/190/255 285/191/255 -f 285/191/256 286/190/256 288/192/256 287/193/256 -f 287/193/257 288/192/257 290/196/257 289/197/257 -f 289/197/258 290/196/258 228/198/258 227/199/258 -f 239/145/233 241/147/233 299/147/233 298/145/233 -f 291/231/259 292/232/259 293/233/259 294/234/259 295/235/259 296/236/259 298/237/259 299/238/259 300/239/259 301/240/259 302/241/259 303/242/259 304/243/259 305/244/259 306/245/259 307/246/259 308/247/259 309/248/259 310/249/259 312/250/259 314/251/259 315/252/259 316/253/259 317/254/259 318/255/259 319/256/259 320/257/259 322/258/259 324/259/259 325/260/259 327/261/259 328/262/259 -f 257/163/242 259/165/242 308/165/242 307/163/242 -f 275/181/251 277/183/251 319/183/251 318/181/251 -f 286/190/260 285/191/260 325/191/260 326/190/260 -f 231/137/229 233/139/229 294/139/229 293/137/229 -f 249/155/238 251/157/238 304/157/238 303/155/238 -f 267/173/247 269/175/247 315/175/247 314/173/247 -f 285/191/256 287/193/256 327/193/256 325/191/256 -f 241/147/234 243/149/234 300/149/234 299/147/234 -f 259/165/243 261/167/243 309/167/243 308/165/243 -f 277/183/252 279/185/252 320/185/252 319/183/252 -f 233/139/230 235/141/230 295/141/230 294/139/230 -f 251/157/261 253/159/261 305/159/261 304/157/261 -f 269/175/248 271/177/248 316/177/248 315/175/248 -f 287/193/257 289/197/257 328/197/257 327/193/257 -f 280/184/262 279/185/262 320/185/262 321/184/262 -f 243/149/235 245/151/235 301/151/235 300/149/235 -f 261/167/244 263/169/244 310/169/244 309/167/244 -f 279/185/253 281/187/253 322/187/253 320/185/253 -f 235/141/231 237/143/231 296/143/231 295/141/231 -f 253/159/240 255/161/240 306/161/240 305/159/240 -f 271/177/249 273/179/249 317/179/249 316/177/249 -f 227/132/227 229/135/227 292/135/227 291/132/227 -f 289/197/258 227/199/258 291/199/258 328/197/258 -f 264/168/262 263/169/262 310/169/262 311/168/262 -f 282/186/263 281/187/263 322/187/263 323/186/263 -f 245/151/236 247/153/236 302/153/236 301/151/236 -f 263/169/245 265/171/245 312/171/245 310/169/245 -f 281/187/254 283/189/254 324/189/254 322/187/254 -f 238/142/264 237/143/264 296/143/264 297/142/264 -f 237/143/232 239/145/232 298/145/232 296/143/232 -f 255/161/241 257/163/241 307/163/241 306/161/241 -f 273/179/250 275/181/250 318/181/250 317/179/250 -f 266/170/265 265/171/265 312/171/265 313/170/265 -f 229/135/228 231/137/228 293/137/228 292/135/228 -f 247/153/237 249/155/237 303/155/237 302/153/237 -f 265/171/246 267/173/246 314/173/246 312/171/246 -f 283/189/266 285/191/266 325/191/266 324/189/266 +f 161/131/131 162/132/131 164/133/131 163/134/131 +f 163/134/132 164/133/132 166/135/132 165/136/132 +f 165/136/133 166/135/133 168/137/133 167/138/133 +f 167/138/134 168/137/134 170/139/134 169/140/134 +f 169/140/135 170/139/135 172/141/135 171/142/135 +f 171/142/136 172/141/136 174/143/136 173/144/136 +f 173/144/137 174/143/137 176/145/137 175/146/137 +f 175/146/138 176/145/138 178/147/138 177/148/138 +f 177/148/139 178/147/139 180/149/139 179/150/139 +f 179/150/140 180/149/140 182/151/140 181/152/140 +f 181/152/141 182/151/141 184/153/141 183/154/141 +f 183/154/142 184/153/142 186/155/142 185/156/142 +f 185/156/143 186/155/143 188/157/143 187/158/143 +f 187/158/144 188/157/144 190/159/144 189/160/144 +f 189/160/145 190/159/145 192/161/145 191/162/145 +f 191/162/146 192/161/146 194/163/146 193/164/146 +f 193/164/147 194/163/147 196/165/147 195/166/147 +f 195/166/148 196/165/148 198/167/148 197/168/148 +f 197/168/149 198/167/149 200/169/149 199/170/149 +f 199/170/150 200/169/150 202/171/150 201/172/150 +f 201/172/151 202/171/151 204/173/151 203/174/151 +f 203/174/152 204/173/152 206/175/152 205/176/152 +f 205/176/153 206/175/153 208/177/153 207/178/153 +f 207/178/154 208/177/154 210/179/154 209/180/154 +f 209/180/155 210/179/155 212/181/155 211/182/155 +f 211/182/156 212/181/156 214/183/156 213/184/156 +f 213/184/157 214/183/157 216/185/157 215/186/157 +f 215/186/158 216/185/158 218/187/158 217/188/158 +f 217/188/159 218/187/159 220/189/159 219/190/159 +f 219/190/160 220/189/160 222/191/160 221/192/160 +f 164/193/161 162/194/161 224/195/161 222/196/161 220/197/161 218/198/161 216/199/161 214/200/161 212/201/161 210/202/161 208/203/161 206/204/161 204/205/161 202/206/161 200/207/161 198/208/161 196/209/161 194/210/161 192/211/161 190/212/161 188/213/161 186/214/161 184/215/161 182/216/161 180/217/161 178/218/161 176/219/161 174/220/161 172/221/161 170/222/161 168/223/161 166/224/161 +f 221/192/162 222/191/162 224/225/162 223/226/162 +f 223/226/163 224/225/163 162/227/163 161/228/163 +f 225/228/164 256/226/164 223/226/164 161/228/164 +f 320/225/165 318/191/165 255/192/165 256/226/165 +f 257/131/166 258/132/166 260/133/166 259/134/166 +f 259/134/167 260/133/167 262/135/167 261/136/167 +f 261/136/168 262/135/168 264/137/168 263/138/168 +f 263/138/169 264/137/169 266/139/169 265/140/169 +f 265/140/170 266/139/170 268/141/170 267/142/170 +f 267/142/171 268/141/171 270/143/171 269/144/171 +f 269/144/172 270/143/172 272/145/172 271/146/172 +f 271/146/173 272/145/173 274/147/173 273/148/173 +f 273/148/174 274/147/174 276/149/174 275/150/174 +f 275/150/175 276/149/175 278/151/175 277/152/175 +f 277/152/176 278/151/176 280/153/176 279/154/176 +f 279/154/177 280/153/177 282/155/177 281/156/177 +f 281/156/178 282/155/178 284/157/178 283/158/178 +f 283/158/179 284/157/179 286/159/179 285/160/179 +f 285/160/180 286/159/180 288/161/180 287/162/180 +f 287/162/181 288/161/181 290/163/181 289/164/181 +f 289/164/182 290/163/182 292/165/182 291/166/182 +f 291/166/183 292/165/183 294/167/183 293/168/183 +f 293/168/184 294/167/184 296/169/184 295/170/184 +f 295/170/185 296/169/185 298/171/185 297/172/185 +f 297/172/186 298/171/186 300/173/186 299/174/186 +f 299/174/187 300/173/187 302/175/187 301/176/187 +f 301/176/188 302/175/188 304/177/188 303/178/188 +f 303/178/189 304/177/189 306/179/189 305/180/189 +f 305/180/190 306/179/190 308/181/190 307/182/190 +f 307/182/191 308/181/191 310/183/191 309/184/191 +f 309/184/192 310/183/192 312/185/192 311/186/192 +f 311/186/193 312/185/193 314/187/193 313/188/193 +f 313/188/194 314/187/194 316/189/194 315/190/194 +f 315/190/195 316/189/195 318/191/195 317/192/195 +f 258/227/196 320/225/196 256/226/196 225/228/196 +f 317/192/197 318/191/197 320/225/197 319/226/197 +f 319/226/198 320/225/198 258/227/198 257/228/198 +f 257/229/199 259/230/199 261/231/199 263/232/199 265/233/199 267/234/199 269/235/199 271/236/199 273/237/199 275/238/199 277/239/199 279/240/199 281/241/199 283/242/199 285/243/199 287/244/199 289/245/199 291/246/199 293/247/199 295/248/199 297/249/199 299/250/199 301/251/199 303/252/199 305/253/199 307/254/199 309/255/199 311/256/199 313/257/199 315/258/199 317/259/199 319/260/199 +f 318/191/200 316/189/200 254/190/200 255/192/200 +f 316/189/201 314/187/201 253/188/201 254/190/201 +f 314/187/202 312/185/202 252/186/202 253/188/202 +f 312/185/203 310/183/203 251/184/203 252/186/203 +f 310/183/204 308/181/204 250/182/204 251/184/204 +f 308/181/205 306/179/205 249/180/205 250/182/205 +f 306/179/206 304/177/206 248/178/206 249/180/206 +f 304/177/207 302/175/207 247/176/207 248/178/207 +f 302/175/208 300/173/208 246/174/208 247/176/208 +f 300/173/209 298/171/209 245/172/209 246/174/209 +f 298/171/210 296/169/210 244/170/210 245/172/210 +f 296/169/211 294/167/211 243/168/211 244/170/211 +f 294/167/212 292/165/212 242/166/212 243/168/212 +f 292/165/213 290/163/213 241/164/213 242/166/213 +f 290/163/214 288/161/214 240/162/214 241/164/214 +f 288/161/215 286/159/215 239/160/215 240/162/215 +f 286/159/216 284/157/216 238/158/216 239/160/216 +f 284/157/217 282/155/217 237/156/217 238/158/217 +f 282/155/218 280/153/218 236/154/218 237/156/218 +f 280/153/219 278/151/219 235/152/219 236/154/219 +f 278/151/220 276/149/220 234/150/220 235/152/220 +f 276/149/221 274/147/221 233/148/221 234/150/221 +f 274/147/222 272/145/222 232/146/222 233/148/222 +f 272/145/223 270/143/223 231/144/223 232/146/223 +f 270/143/224 268/141/224 230/142/224 231/144/224 +f 268/141/225 266/139/225 229/140/225 230/142/225 +f 266/139/226 264/137/226 228/138/226 229/140/226 +f 264/137/227 262/135/227 227/136/227 228/138/227 +f 262/135/228 260/133/228 226/134/228 227/136/228 +f 260/133/229 258/132/229 225/131/229 226/134/229 +f 256/226/230 255/192/230 221/192/230 223/226/230 +f 255/192/231 254/190/231 219/190/231 221/192/231 +f 254/190/232 253/188/232 217/188/232 219/190/232 +f 253/188/233 252/186/233 215/186/233 217/188/233 +f 252/186/234 251/184/234 213/184/234 215/186/234 +f 251/184/235 250/182/235 211/182/235 213/184/235 +f 250/182/236 249/180/236 209/180/236 211/182/236 +f 249/180/237 248/178/237 207/178/237 209/180/237 +f 248/178/238 247/176/238 205/176/238 207/178/238 +f 247/176/239 246/174/239 203/174/239 205/176/239 +f 246/174/240 245/172/240 201/172/240 203/174/240 +f 245/172/241 244/170/241 199/170/241 201/172/241 +f 244/170/242 243/168/242 197/168/242 199/170/242 +f 243/168/243 242/166/243 195/166/243 197/168/243 +f 242/166/244 241/164/244 193/164/244 195/166/244 +f 241/164/245 240/162/245 191/162/245 193/164/245 +f 240/162/246 239/160/246 189/160/246 191/162/246 +f 239/160/247 238/158/247 187/158/247 189/160/247 +f 238/158/248 237/156/248 185/156/248 187/158/248 +f 237/156/249 236/154/249 183/154/249 185/156/249 +f 236/154/250 235/152/250 181/152/250 183/154/250 +f 235/152/251 234/150/251 179/150/251 181/152/251 +f 234/150/252 233/148/252 177/148/252 179/150/252 +f 233/148/253 232/146/253 175/146/253 177/148/253 +f 232/146/254 231/144/254 173/144/254 175/146/254 +f 231/144/255 230/142/255 171/142/255 173/144/255 +f 230/142/256 229/140/256 169/140/256 171/142/256 +f 229/140/257 228/138/257 167/138/257 169/140/257 +f 228/138/258 227/136/258 165/136/258 167/138/258 +f 227/136/259 226/134/259 163/134/259 165/136/259 +f 226/134/260 225/131/260 161/131/260 163/134/260 diff --git a/src/main/resources/assets/saturnclient/models/item/horns/white.json b/src/main/resources/assets/saturnclient/models/item/horns/white.json index d5c9072..1001f92 100644 --- a/src/main/resources/assets/saturnclient/models/item/horns/white.json +++ b/src/main/resources/assets/saturnclient/models/item/horns/white.json @@ -1,13 +1,13 @@ -{ - "parent": "special-model-loader:builtin/obj", - "model": "saturnclient:models/item/horns/horns.obj", - "mtl_override": "saturnclient:models/item/white.mtl", - "flip_v": true, - "display": { - "thirdperson_righthand": { - "rotation": [0, 0, 0], - "translation": [-5.08, 8.3, -0.1], - "scale": [0.065, 0.065, 0.065] - } - } -} +{ + "parent": "special-model-loader:builtin/obj", + "model": "saturnclient:models/item/horns/horns.obj", + "mtl_override": "saturnclient:models/item/white.mtl", + "flip_v": true, + "display": { + "thirdperson_righthand": { + "rotation": [0, 0, 0], + "translation": [2, 6, 2], + "scale": [0.25, 0.25, 0.25] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/saturnclient/textures/gui/mod/sprint.png b/src/main/resources/assets/saturnclient/textures/gui/mod/sprint.png new file mode 100644 index 0000000..c1c507c Binary files /dev/null and b/src/main/resources/assets/saturnclient/textures/gui/mod/sprint.png differ diff --git a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_0.png b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_0.png index eed3a8d..6653bad 100644 Binary files a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_0.png and b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_0.png differ diff --git a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_1.png b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_1.png index d02d31d..523b7a4 100644 Binary files a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_1.png and b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_1.png differ diff --git a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_2.png b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_2.png index 2215b75..354c1b1 100644 Binary files a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_2.png and b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_2.png differ diff --git a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_3.png b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_3.png index 88f96ee..da74054 100644 Binary files a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_3.png and b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_3.png differ diff --git a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_4.png b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_4.png index b2a3215..f0c51f7 100644 Binary files a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_4.png and b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_4.png differ diff --git a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_5.png b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_5.png index 111576e..93663f5 100644 Binary files a/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_5.png and b/src/main/resources/assets/saturnclient/textures/gui/title/background/panorama_5.png differ diff --git a/src/main/resources/assets/saturnclient/textures/logo/text.png b/src/main/resources/assets/saturnclient/textures/logo/text.png index b976fde..6fd0bf1 100644 Binary files a/src/main/resources/assets/saturnclient/textures/logo/text.png and b/src/main/resources/assets/saturnclient/textures/logo/text.png differ diff --git a/src/main/resources/saturnclient.mixins.json b/src/main/resources/saturnclient.mixins.json index 8aaefd3..bd16a89 100644 --- a/src/main/resources/saturnclient.mixins.json +++ b/src/main/resources/saturnclient.mixins.json @@ -2,17 +2,15 @@ "required": true, "minVersion": "0.8", "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "client": [ "TabListMixin", "NameTagMixin", "PlayerEntityRendererMixin", "WhoAmI", "SaturnReload", - "TotemParticleMixin", - "Crosshair", - "EntityMixin", - "CameraMixin" + "DrawContextAccessor", + "TitleScreenMixin" ], "injectors": { "defaultRequire": 1