aboutsummaryrefslogtreecommitdiff
path: root/mod/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'mod/src/main')
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java21
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java2
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknameColor.java18
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknamePrefix.java18
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetButton.java63
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetColorButton.java103
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknameColor.java141
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknamePrefix.java196
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java10
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java4
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java1
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java2
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/UnconstrainedBox.java4
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java2
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button.gui27
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button2.gui28
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknameColor.gui103
-rw-r--r--mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknamePrefix.gui119
18 files changed, 833 insertions, 29 deletions
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java
index 1dae8679..ea5dba43 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CosmeticsManager.java
@@ -274,19 +274,30 @@ public class CosmeticsManager {
if (replacementContext.getUsername().isEmpty()) continue;
List<ActiveCosmetic> activeCosmetics = getActiveCosmeticByPlayerNameLowerCase()
.get(replacementContext.getUsername().toLowerCase());
- String color=null, prefix=null;
+ String color=null, rawPrefix=null, rawPrefixColor=null;
if (activeCosmetics != null) {
for (ActiveCosmetic activeCosmetic : activeCosmetics) {
CosmeticData cosmeticData = getCosmeticDataMap().get(activeCosmetic.getCosmeticData());
- if (cosmeticData != null && cosmeticData.getCosmeticType().equals("color")) {
+ if (cosmeticData != null && cosmeticData.getCosmeticType().equals("ncolor")) {
color = cosmeticData.getData().replace("&", "§");
- } else if (cosmeticData != null && cosmeticData.getCosmeticType().equals("prefix")) {
- prefix = cosmeticData.getData().replace("&", "§");
+ } else if (cosmeticData != null && cosmeticData.getCosmeticType().equals("nprefix")) {
+ rawPrefix = cosmeticData.getData().replace("&", "§");
+ } else if (cosmeticData != null && cosmeticData.getCosmeticType().equals("bracket_color")) {
+ rawPrefixColor = cosmeticData.getData().replace("&", "§");
}
}
}
- if (color == null && prefix == null) continue;
+ if (color == null && rawPrefix == null) continue;
+
+ String prefix = null;
+ if (rawPrefix != null) {
+ prefix = rawPrefix.substring(1);
+ if (!rawPrefix.startsWith("T")) {
+ if (rawPrefixColor != null)
+ prefix = rawPrefixColor+"["+prefix+"§r"+rawPrefixColor+"]";
+ }
+ }
StringBuilder sb = new StringBuilder();
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java
index 86bded25..de4c3fd5 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java
@@ -93,7 +93,7 @@ public class CustomNetworkPlayerInfo extends NetworkPlayerInfo {
for (ActiveCosmetic activeCosmetic : activeCosmetics) {
CosmeticData cosmeticData = DungeonsGuide.getDungeonsGuide().getCosmeticsManager().getCosmeticDataMap().get(activeCosmetic.getCosmeticData());
if (cosmeticData == null) continue;
- if (cosmeticData.getCosmeticType().equals("color")) color = cosmeticData;
+ if (cosmeticData.getCosmeticType().equals("ncolor")) color = cosmeticData;
}
if (color != null) {
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknameColor.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknameColor.java
index 1d8af9dc..c481c05e 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknameColor.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknameColor.java
@@ -19,6 +19,7 @@
package kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics;
import kr.syeyoung.dungeonsguide.mod.features.SimpleFeature;
+import kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics.widget.WidgetNicknameColor;
import kr.syeyoung.dungeonsguide.mod.guiv2.Widget;
import kr.syeyoung.dungeonsguide.mod.guiv2.elements.CompatLayer;
@@ -29,14 +30,15 @@ public class FeatureNicknameColor extends SimpleFeature {
@Override
public Widget getConfigureWidget() {
- return new CompatLayer( new PrefixSelectorGUI("color", new String[] {
- "§9Party §8> §r§a[RANK§6+§a] %prefix%%name%§f: TEST",
- "§2Guild > §r§a[RANK§6+§a] %prefix%%name% §3[Vet]§f: TEST",
- "§dTo §r§r§a[RANK§r§6+§r§a] %prefix%%name%§r§7: §r§7TEST§r",
- "§dFrom §r§r§a[RANK§r§6+§r§a] %prefix%%name%§r§7: §r§7TEST§r",
- "§r§b[RANK§c+§b] %prefix%%name%§f: TEST",
- "§r§bCo-op > §r§a[RANK§6+§a] %prefix%%name%§f: §rTEST§r"
- }, a -> (a.replace("&", "§")+"Color "+(a.replace("&", "§").equals("§z") ? "(Rainbow on sba)" : ""))));
+// return new CompatLayer( new PrefixSelectorGUI("color", new String[] {
+// "§9Party §8> §r§a[RANK§6+§a] %prefix%%name%§f: TEST",
+// "§2Guild > §r§a[RANK§6+§a] %prefix%%name% §3[Vet]§f: TEST",
+// "§dTo §r§r§a[RANK§r§6+§r§a] %prefix%%name%§r§7: §r§7TEST§r",
+// "§dFrom §r§r§a[RANK§r§6+§r§a] %prefix%%name%§r§7: §r§7TEST§r",
+// "§r§b[RANK§c+§b] %prefix%%name%§f: TEST",
+// "§r§bCo-op > §r§a[RANK§6+§a] %prefix%%name%§f: §rTEST§r"
+// }, a -> (a.replace("&", "§")+"Color "+(a.replace("&", "§").equals("§z") ? "(Rainbow on sba)" : ""))));
+ return new WidgetNicknameColor();
}
@Override
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknamePrefix.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknamePrefix.java
index 52ef5396..2b7510ee 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknamePrefix.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/FeatureNicknamePrefix.java
@@ -21,6 +21,7 @@ package kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics;
import kr.syeyoung.dungeonsguide.mod.config.types.TCString;
import kr.syeyoung.dungeonsguide.mod.features.FeatureParameter;
import kr.syeyoung.dungeonsguide.mod.features.SimpleFeature;
+import kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics.widget.WidgetNicknamePrefix;
import kr.syeyoung.dungeonsguide.mod.guiv2.Widget;
import kr.syeyoung.dungeonsguide.mod.guiv2.elements.CompatLayer;
@@ -32,14 +33,15 @@ public class FeatureNicknamePrefix extends SimpleFeature {
@Override
public Widget getConfigureWidget() {
- return new CompatLayer(new PrefixSelectorGUI("prefix", new String[] {
- "§9Party §8> §r%prefix% §a[RANK§6+§a] %name%§f: TEST",
- "§2Guild > §r%prefix% §a[RANK§6+§a] %name% §3[Vet]§f: TEST",
- "§dTo §r%prefix% §r§a[RANK§r§6+§r§a] %name%§r§7: §r§7TEST§r",
- "§dFrom §r%prefix% §r§a[RANK§r§6+§r§a] %name%§r§7: §r§7TEST§r",
- "§r%prefix% §b[RANK§c+§b] %name%§f: TEST",
- "§r§bCo-op > §r%prefix% §a[RANK§6+§a] %name%§f: §rTEST§r"
- }, a->a.replace("&", "§")));
+// return new CompatLayer(new PrefixSelectorGUI("prefix", new String[] {
+// "§9Party §8> §r%prefix% §a[RANK§6+§a] %name%§f: TEST",
+// "§2Guild > §r%prefix% §a[RANK§6+§a] %name% §3[Vet]§f: TEST",
+// "§dTo §r%prefix% §r§a[RANK§r§6+§r§a] %name%§r§7: §r§7TEST§r",
+// "§dFrom §r%prefix% §r§a[RANK§r§6+§r§a] %name%§r§7: §r§7TEST§r",
+// "§r%prefix% §b[RANK§c+§b] %name%§f: TEST",
+// "§r§bCo-op > §r%prefix% §a[RANK§6+§a] %name%§f: §rTEST§r"
+// }, a->a.replace("&", "§")));
+ return new WidgetNicknamePrefix();
}
@Override
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetButton.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetButton.java
new file mode 100644
index 00000000..dc6f38ec
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetButton.java
@@ -0,0 +1,63 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics.widget;
+
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement;
+import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer;
+import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext;
+import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.SingleChildRenderer;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import net.minecraft.util.ResourceLocation;
+
+import java.util.Locale;
+
+public class WidgetButton extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "text")
+ public final BindableAttribute<String> text = new BindableAttribute<>(String.class);
+ @Bind(variableName = "normal")
+ public final BindableAttribute<Integer> normal = new BindableAttribute<>(Integer.class);
+ @Bind(variableName = "hover")
+ public final BindableAttribute<Integer> hover = new BindableAttribute<>(Integer.class);
+ @Bind(variableName = "press")
+ public final BindableAttribute<Integer> press = new BindableAttribute<>(Integer.class);
+
+ @Bind(variableName = "disabled")
+ public final BindableAttribute<Boolean> _ = new BindableAttribute<>(Boolean.class, false);
+
+ @Bind(variableName = "click")
+ public final BindableAttribute<Runnable> onClick = new BindableAttribute<>(Runnable.class);
+
+ public WidgetButton(boolean enabled, String prefix, Runnable onClick) {
+ super(new ResourceLocation("dungeonsguide:gui/config/cosmetics/button2.gui"));
+ text.setValue(prefix);
+ this.onClick.setValue(onClick);
+ if (enabled) {
+ normal.setValue(0xFF1E387A);
+ hover.setValue(0xFF356091);
+ press.setValue(0xFF50799E);
+ } else {
+ normal.setValue(0xFF2E2D2C);
+ hover.setValue(RenderUtils.blendAlpha(0xFF2E2D2C, 0.2f));
+ press.setValue(RenderUtils.blendAlpha(0xFF2E2D2C, 0.4f));
+ }
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetColorButton.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetColorButton.java
new file mode 100644
index 00000000..c4ab59d5
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetColorButton.java
@@ -0,0 +1,103 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics.widget;
+
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement;
+import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer;
+import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext;
+import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.SingleChildRenderer;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import net.minecraft.util.ResourceLocation;
+
+import java.util.Locale;
+
+public class WidgetColorButton extends AnnotatedImportOnlyWidget implements Renderer {
+ @Bind(variableName = "text")
+ public final BindableAttribute<String> text = new BindableAttribute<>(String.class);
+ @Bind(variableName = "disabled")
+ public final BindableAttribute<Boolean> disabled = new BindableAttribute<>(Boolean.class);
+ @Bind(variableName = "normal")
+ public final BindableAttribute<Integer> normal = new BindableAttribute<>(Integer.class);
+ @Bind(variableName = "hover")
+ public final BindableAttribute<Integer> hover = new BindableAttribute<>(Integer.class);
+ @Bind(variableName = "press")
+ public final BindableAttribute<Integer> press = new BindableAttribute<>(Integer.class);
+
+ @Bind(variableName = "click")
+ public final BindableAttribute<Runnable> onClick = new BindableAttribute<>(Runnable.class);
+
+ private static final int[] colorCode = new int[32];
+ static {
+ for(int i = 0; i < 32; ++i) {
+ int j = (i >> 3 & 1) * 85;
+ int k = (i >> 2 & 1) * 170 + j;
+ int l = (i >> 1 & 1) * 170 + j;
+ int i1 = (i & 1) * 170 + j;
+ if (i == 6) {
+ k += 85;
+ }
+
+ if (i >= 16) {
+ k /= 4;
+ l /= 4;
+ i1 /= 4;
+ }
+
+ colorCode[i] = (k & 255) << 16 | (l & 255) << 8 | i1 & 255;
+ }
+ }
+
+ private boolean chroma = false;
+ public WidgetColorButton(boolean enabled, String colorcode, Runnable onClick) {
+ super(new ResourceLocation("dungeonsguide:gui/config/cosmetics/button.gui"));
+ text.setValue(enabled ? "Available" : "Locked");
+ disabled.setValue(false);
+ this.onClick.setValue(onClick);
+ int i1 = "0123456789abcdefz".indexOf(colorcode.toLowerCase(Locale.ENGLISH).charAt(0));
+
+ if (i1 == 16) {
+ chroma = true;
+
+ int color =RenderUtils.getChromaColorAt(0, 0, 0.5f, 1, 1, 1.0f);
+ normal.setValue(color);
+ hover.setValue(RenderUtils.blendAlpha(color, 0.2f));
+ press.setValue(RenderUtils.blendAlpha(color, 0.4f));
+ } else {
+ int color = colorCode[i1] | 0xFF000000;
+ normal.setValue(color);
+ hover.setValue(RenderUtils.blendAlpha(color, 0.2f));
+ press.setValue(RenderUtils.blendAlpha(color, 0.4f));
+ }
+ }
+
+ @Override
+ public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext context, DomElement buildContext) {
+ if (chroma) {
+ int color =RenderUtils.getChromaColorAt(0, 0, 0.3f, 1, 1, 1.0f);
+ normal.setValue(color);
+ hover.setValue(RenderUtils.blendAlpha(color, 0.2f));
+ press.setValue(RenderUtils.blendAlpha(color, 0.4f));
+ }
+
+ SingleChildRenderer.INSTANCE.doRender(absMouseX, absMouseY, relMouseX, relMouseY, partialTicks, context, buildContext);
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknameColor.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknameColor.java
new file mode 100644
index 00000000..5a174b74
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknameColor.java
@@ -0,0 +1,141 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics.widget;
+
+import kr.syeyoung.dungeonsguide.mod.DungeonsGuide;
+import kr.syeyoung.dungeonsguide.mod.cosmetics.ActiveCosmetic;
+import kr.syeyoung.dungeonsguide.mod.cosmetics.CosmeticData;
+import kr.syeyoung.dungeonsguide.mod.cosmetics.CosmeticsManager;
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.data.WidgetList;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.util.ResourceLocation;
+
+import java.awt.*;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WidgetNicknameColor extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "preview")
+ public final BindableAttribute<String> preview = new BindableAttribute<>(String.class);
+ @Bind(variableName = "colors")
+ public final BindableAttribute colors = new BindableAttribute<>(WidgetList.class);
+
+ @Bind(variableName = "disabled")
+ public final BindableAttribute<Boolean> disabled = new BindableAttribute<>(Boolean.class, false);
+
+ private CosmeticData previouslySelected;
+ private CosmeticData currentSelected;
+
+ public WidgetNicknameColor() {
+ super(new ResourceLocation("dungeonsguide:gui/config/cosmetics/nicknameColor.gui"));
+
+
+ ArrayList<Widget> list = new ArrayList<>();
+
+ CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
+ for (CosmeticData value : cosmeticsManager.getCosmeticDataMap().values()) {
+ if (value.getCosmeticType().equals("ncolor")) {
+ list.add(new WidgetColorButton(cosmeticsManager.getPerms().contains(value.getReqPerm()), value.getData().substring(1), () -> {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ currentSelected = value;
+ update();
+ }));
+ }
+ }
+ List<ActiveCosmetic> activeCosmeticList = cosmeticsManager.getActiveCosmeticByPlayer().computeIfAbsent(Minecraft.getMinecraft().thePlayer.getGameProfile().getId(), (a) -> new ArrayList<>());
+ for (ActiveCosmetic activeCosmetic : activeCosmeticList) {
+ CosmeticData cosmeticData = cosmeticsManager.getCosmeticDataMap().get(activeCosmetic.getCosmeticData());
+ if (cosmeticData != null && cosmeticData.getCosmeticType().equals("ncolor")) {
+ currentSelected = cosmeticData;
+ previouslySelected = cosmeticData;
+ }
+ }
+ update();
+
+ colors.setValue(list);
+ }
+
+ private void update() {
+ CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
+ preview.setValue(String.join("\n",new String[] {
+ "§9Party §8> §r§a[RANK§6+§a] %prefix%%name%§f: TEST",
+ "§2Guild > §r§a[RANK§6+§a] %prefix%%name% §3[Vet]§f: TEST",
+ "§dTo §r§r§a[RANK§r§6+§r§a] %prefix%%name%§r§7: §r§7TEST§r",
+ "§dFrom §r§r§a[RANK§r§6+§r§a] %prefix%%name%§r§7: §r§7TEST§r",
+ "§r§b[RANK§c+§b] %prefix%%name%§f: TEST",
+ "§r§bCo-op > §r§a[RANK§6+§a] %prefix%%name%§f: §rTEST§r"
+ }).replace("%name%", Minecraft.getMinecraft().getSession().getUsername())
+ .replace("%prefix%", currentSelected == null ? "" : currentSelected.getData()));
+
+ boolean disable = currentSelected == previouslySelected
+ || (currentSelected != null && !cosmeticsManager.getPerms().contains(currentSelected.getReqPerm()));
+ disabled.setValue(disable);
+ }
+
+ @On(functionName = "apply")
+ public void onApply() {
+ CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
+ boolean disable = currentSelected == previouslySelected
+ || (currentSelected != null && !cosmeticsManager.getPerms().contains(currentSelected.getReqPerm()));
+ if (disable) return;
+
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+
+ if (previouslySelected != null) {
+ List<ActiveCosmetic> activeCosmeticList = cosmeticsManager.getActiveCosmeticByPlayer().computeIfAbsent(Minecraft.getMinecraft().thePlayer.getGameProfile().getId(), (a) -> new ArrayList<>());
+ for (ActiveCosmetic activeCosmetic : activeCosmeticList) {
+ if (activeCosmetic.getCosmeticData().equals(previouslySelected.getId())) {
+ cosmeticsManager.removeCosmetic(activeCosmetic);
+ }
+ }
+ }
+ if (currentSelected != null)
+ cosmeticsManager.setCosmetic(currentSelected);
+
+ previouslySelected = currentSelected;
+
+ update();
+ }
+
+ @On(functionName = "clear")
+ public void onClear() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ currentSelected = null;
+ update();
+ }
+
+ @On(functionName = "shop")
+ public void openShop() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ try {
+ Desktop.getDesktop().browse(new URI("https://store.dungeons.guide/"));
+ } catch (IOException | URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknamePrefix.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknamePrefix.java
new file mode 100644
index 00000000..f69c4efb
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/cosmetics/widget/WidgetNicknamePrefix.java
@@ -0,0 +1,196 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.features.impl.cosmetics.widget;
+
+import kr.syeyoung.dungeonsguide.mod.DungeonsGuide;
+import kr.syeyoung.dungeonsguide.mod.cosmetics.ActiveCosmetic;
+import kr.syeyoung.dungeonsguide.mod.cosmetics.CosmeticData;
+import kr.syeyoung.dungeonsguide.mod.cosmetics.CosmeticsManager;
+import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute;
+import kr.syeyoung.dungeonsguide.mod.guiv2.Widget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On;
+import kr.syeyoung.dungeonsguide.mod.guiv2.xml.data.WidgetList;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.util.ResourceLocation;
+
+import java.awt.*;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WidgetNicknamePrefix extends AnnotatedImportOnlyWidget {
+ @Bind(variableName = "preview")
+ public final BindableAttribute<String> preview = new BindableAttribute<>(String.class);
+ @Bind(variableName = "prefixes")
+ public final BindableAttribute prefixes = new BindableAttribute<>(WidgetList.class);
+ @Bind(variableName = "colors")
+ public final BindableAttribute colors = new BindableAttribute<>(WidgetList.class);
+
+ @Bind(variableName = "disabled")
+ public final BindableAttribute<Boolean> disabled = new BindableAttribute<>(Boolean.class, false);
+
+ private CosmeticData previouslySelectedColor;
+ private CosmeticData currentSelectedColor;
+
+
+ private CosmeticData previouslySelectedPrefix;
+ private CosmeticData currentSelectedPrefix;
+
+ public WidgetNicknamePrefix() {
+ super(new ResourceLocation("dungeonsguide:gui/config/cosmetics/nicknamePrefix.gui"));
+
+
+ ArrayList<Widget> list = new ArrayList<>();
+ ArrayList<Widget> list2 = new ArrayList<>();
+
+ CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
+ for (CosmeticData value : cosmeticsManager.getCosmeticDataMap().values()) {
+ if (value.getCosmeticType().equals("bracket_color")) {
+ list.add(new WidgetColorButton(cosmeticsManager.getPerms().contains(value.getReqPerm()), value.getData().substring(1), () -> {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ currentSelectedColor = value;
+ update();
+ }));
+ } else if (value.getCosmeticType().equals("nprefix")) {
+ list2.add(new WidgetButton(cosmeticsManager.getPerms().contains(value.getReqPerm()), value.getData().substring(1), () -> {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ currentSelectedPrefix = value;
+ update();
+ }));
+ }
+ }
+ List<ActiveCosmetic> activeCosmeticList = cosmeticsManager.getActiveCosmeticByPlayer().computeIfAbsent(Minecraft.getMinecraft().thePlayer.getGameProfile().getId(), (a) -> new ArrayList<>());
+ for (ActiveCosmetic activeCosmetic : activeCosmeticList) {
+ CosmeticData cosmeticData = cosmeticsManager.getCosmeticDataMap().get(activeCosmetic.getCosmeticData());
+ if (cosmeticData != null && cosmeticData.getCosmeticType().equals("bracket_color")) {
+ currentSelectedColor = cosmeticData;
+ previouslySelectedColor = cosmeticData;
+ } else if (cosmeticData != null && cosmeticData.getCosmeticType().equals("nprefix")) {
+ currentSelectedPrefix = cosmeticData;
+ previouslySelectedPrefix = cosmeticData;
+ }
+ }
+
+ if (currentSelectedColor == null) {
+ for (CosmeticData value : cosmeticsManager.getCosmeticDataMap().values()) {
+ if (value.getCosmeticType().equals("bracket_color") && cosmeticsManager.getPerms().contains(value.getReqPerm())) {
+ currentSelectedColor = value;
+ break;
+ }
+ }
+ }
+ update();
+
+ colors.setValue(list);
+ prefixes.setValue(list2);
+ }
+
+ private void update() {
+ CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
+ String prefix = currentSelectedPrefix == null ? "" : currentSelectedPrefix.getData().substring(1);
+ if (currentSelectedColor != null && currentSelectedPrefix != null && currentSelectedPrefix.getData().startsWith("F"))
+ prefix = currentSelectedColor.getData()+"["+prefix+"§r"+currentSelectedColor.getData()+"]";
+
+ if (!prefix.isEmpty()) prefix += " ";
+
+ preview.setValue(String.join("\n",new String[] {
+ "§9Party §8> §r§a[RANK§6+§a] %prefix%§a%name%§f: TEST",
+ "§2Guild > §r§a[RANK§6+§a] %prefix%§a%name% §3[Vet]§f: TEST",
+ "§dTo §r§r§a[RANK§r§6+§r§a] %prefix%§a%name%§r§7: §r§7TEST§r",
+ "§dFrom §r§r§a[RANK§r§6+§r§a] %prefix%§a%name%§r§7: §r§7TEST§r",
+ "§r§b[RANK§c+§b] %prefix%§a%name%§f: TEST",
+ "§r§bCo-op > §r§a[RANK§6+§a] %prefix%§a%name%§f: §rTEST§r"
+ }).replace("%name%", Minecraft.getMinecraft().getSession().getUsername())
+ .replace("%prefix%", prefix));
+
+ boolean disable = (currentSelectedColor == previouslySelectedColor && currentSelectedPrefix == previouslySelectedPrefix)
+ || (currentSelectedColor != null && !cosmeticsManager.getPerms().contains(currentSelectedColor.getReqPerm()))
+ || (currentSelectedPrefix != null && !cosmeticsManager.getPerms().contains(currentSelectedPrefix.getReqPerm()));
+ disabled.setValue(disable);
+ }
+
+ @On(functionName = "apply")
+ public void onApply() {
+ CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
+ boolean disable = (currentSelectedColor == previouslySelectedColor && currentSelectedPrefix == previouslySelectedPrefix)
+ || (currentSelectedColor != null && !cosmeticsManager.getPerms().contains(currentSelectedColor.getReqPerm()))
+ || (currentSelectedPrefix != null && !cosmeticsManager.getPerms().contains(currentSelectedPrefix.getReqPerm()));
+ if (disable) return;
+
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+
+ if (previouslySelectedColor != null) {
+ List<ActiveCosmetic> activeCosmeticList = cosmeticsManager.getActiveCosmeticByPlayer().computeIfAbsent(Minecraft.getMinecraft().thePlayer.getGameProfile().getId(), (a) -> new ArrayList<>());
+ for (ActiveCosmetic activeCosmetic : activeCosmeticList) {
+ if (activeCosmetic.getCosmeticData().equals(previouslySelectedColor.getId())) {
+ cosmeticsManager.removeCosmetic(activeCosmetic);
+ }
+ }
+ }
+ if (previouslySelectedPrefix != null) {
+ List<ActiveCosmetic> activeCosmeticList = cosmeticsManager.getActiveCosmeticByPlayer().computeIfAbsent(Minecraft.getMinecraft().thePlayer.getGameProfile().getId(), (a) -> new ArrayList<>());
+ for (ActiveCosmetic activeCosmetic : activeCosmeticList) {
+ if (activeCosmetic.getCosmeticData().equals(previouslySelectedPrefix.getId())) {
+ cosmeticsManager.removeCosmetic(activeCosmetic);
+ }
+ }
+ }
+ if (currentSelectedColor != null)
+ cosmeticsManager.setCosmetic(currentSelectedColor);
+ if (currentSelectedPrefix != null)
+ cosmeticsManager.setCosmetic(currentSelectedPrefix);
+
+ previouslySelectedColor = currentSelectedColor;
+ previouslySelectedPrefix = currentSelectedPrefix;
+
+ update();
+ }
+
+ @On(functionName = "clear")
+ public void onClear() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ currentSelectedColor = null;
+ currentSelectedPrefix = null;
+
+ CosmeticsManager cosmeticsManager = DungeonsGuide.getDungeonsGuide().getCosmeticsManager();
+ for (CosmeticData value : cosmeticsManager.getCosmeticDataMap().values()) {
+ if (value.getCosmeticType().equals("bracket_color") && cosmeticsManager.getPerms().contains(value.getReqPerm())) {
+ currentSelectedColor = value;
+ break;
+ }
+ }
+
+ update();
+ }
+
+ @On(functionName = "shop")
+ public void openShop() {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ try {
+ Desktop.getDesktop().browse(new URI("https://store.dungeons.guide/"));
+ } catch (IOException | URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java
index cfdbe89f..92169925 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java
@@ -55,13 +55,17 @@ public class Align extends AnnotatedExportOnlyWidget implements Layouter {
0, constraintBox.getMaxWidth(), 0, constraintBox.getMaxHeight()
));
- double x = hAlign.getValue() == Alignment.START ? 0 : hAlign.getValue() == Alignment.CENTER ? (constraintBox.getMaxWidth() - size.getWidth())/2 : constraintBox.getMaxWidth() - size.getWidth();
- double y = vAlign.getValue() == Alignment.START ? 0 : vAlign.getValue() == Alignment.CENTER ? (constraintBox.getMaxHeight() - size.getHeight())/2 : constraintBox.getMaxHeight() - size.getHeight();
+ double maxW = constraintBox.getMaxWidth() == Double.POSITIVE_INFINITY ? size.getWidth() : constraintBox.getMaxWidth();
+ double maxH = constraintBox.getMaxHeight() == Double.POSITIVE_INFINITY ? size.getHeight() : constraintBox.getMaxHeight();
+
+
+ double x = hAlign.getValue() == Alignment.START ? 0 : hAlign.getValue() == Alignment.CENTER ? (maxW - size.getWidth())/2 : maxW - size.getWidth();
+ double y = vAlign.getValue() == Alignment.START ? 0 : vAlign.getValue() == Alignment.CENTER ? (maxH - size.getHeight())/2 : maxH - size.getHeight();
theOnly.setRelativeBound(new Rect(x, y,
size.getWidth(), size.getHeight()
));
- return new Size(constraintBox.getMaxWidth(), constraintBox.getMaxHeight());
+ return new Size(maxW, maxH);
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java
index 83f01c52..ee9804ce 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java
@@ -107,11 +107,13 @@ public class Button extends AnnotatedWidget implements Renderer {
@Override
public void mouseReleased(int absMouseX, int absMouseY, double relMouseX, double relMouseY, int state) {
+ boolean wasPressed = isPressed;
isPressed = false;
+
if (isDisabled.getValue()) return;
- if (getDomElement().getAbsBounds().contains(absMouseX, absMouseY)) {
+ if (getDomElement().getAbsBounds().contains(absMouseX, absMouseY) && wasPressed) {
if (onClick.getValue() != null) onClick.getValue().run();
}
super.mouseReleased(absMouseX, absMouseY, relMouseX, relMouseY, state);
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java
index acdac07e..bfe8aea2 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicHeight.java
@@ -44,6 +44,7 @@ public class IntrinsicHeight extends AnnotatedExportOnlyWidget implements Layout
public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
DomElement elem = buildContext.getChildren().get(0);
double height = elem.getLayouter().getMaxIntrinsicHeight(elem, constraintBox.getMaxWidth() == Double.POSITIVE_INFINITY ? 0 : constraintBox.getMaxWidth());
+ height = Layouter.clamp(height, constraintBox.getMinHeight(), constraintBox.getMaxHeight());
Size size = elem.getLayouter().layout(elem, new ConstraintBox(
constraintBox.getMinWidth(), constraintBox.getMaxWidth(), height, height
));
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java
index 4c1c8f6c..1c761b0a 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/IntrinsicWidth.java
@@ -44,6 +44,8 @@ public class IntrinsicWidth extends AnnotatedExportOnlyWidget implements Layoute
public Size layout(DomElement buildContext, ConstraintBox constraintBox) {
DomElement elem = buildContext.getChildren().get(0);
double width = elem.getLayouter().getMaxIntrinsicWidth(elem, constraintBox.getMaxHeight() == Double.POSITIVE_INFINITY ? 0 : constraintBox.getMaxHeight());
+ width = Layouter.clamp(width, constraintBox.getMinWidth(), constraintBox.getMaxWidth());
+
Size size = elem.getLayouter().layout(elem, new ConstraintBox(
width, width, constraintBox.getMinHeight(), constraintBox.getMaxHeight()
));
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/UnconstrainedBox.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/UnconstrainedBox.java
index ab379465..e66a011b 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/UnconstrainedBox.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/UnconstrainedBox.java
@@ -61,11 +61,11 @@ public class UnconstrainedBox extends AnnotatedExportOnlyWidget implements Layou
@Override
public double getMaxIntrinsicWidth(DomElement buildContext, double height) {
- return buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicWidth(buildContext.getChildren().get(0), height);
+ return buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicWidth(buildContext.getChildren().get(0), direction.getValue().isVertical() ? 0 : height);
}
@Override
public double getMaxIntrinsicHeight(DomElement buildContext, double width) {
- return buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicHeight(buildContext.getChildren().get(0), width);
+ return buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicHeight(buildContext.getChildren().get(0), direction.getValue().isHorizontal() ? 0 : width);
}
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java
index d7c50aad..3e818fa2 100644
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java
@@ -101,6 +101,7 @@ public class Wrap extends AnnotatedExportOnlyWidget implements Layouter {
public double getMaxIntrinsicHeight(DomElement buildContext, double width) {
List<DomElement> elements = buildContext.getChildren();
if (elements.isEmpty()) return 0;
+ if (width == 0) width = Double.POSITIVE_INFINITY;
int itemPerRow = (int) ((width+gap.getValue()) / (minimumWidth.getValue() + gap.getValue()));
if (itemPerRow == 0) itemPerRow = 1;
if (itemPerRow == Integer.MAX_VALUE) itemPerRow = elements.size();
@@ -120,7 +121,6 @@ public class Wrap extends AnnotatedExportOnlyWidget implements Layouter {
}
sum -= gap.getValue();
if (sum < 0) sum = 0;
-
return sum;
}
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button.gui b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button.gui
new file mode 100644
index 00000000..d01d4d96
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button.gui
@@ -0,0 +1,27 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<size width="50" height="20">
+ <RoundButton bind:text="text" bind:disabled="disabled"
+ bind:click="click"
+ bind:backgroundColor="normal"
+ bind:hoveredBackgroundColor="hover"
+ bind:pressedBackgroundColor="press"
+ textColor="#FF484848" hoveredTextColor="#FF484848" disabledTextColor="#FF484848" pressedTextColor="#FF484848"
+ bind:disabledBackgroundColor="normal"/>
+</size> \ No newline at end of file
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button2.gui b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button2.gui
new file mode 100644
index 00000000..f58295f8
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/button2.gui
@@ -0,0 +1,28 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+<padding bottom="5">
+ <size height="11">
+ <RoundButton bind:text="text" bind:disabled="disabled"
+ bind:click="click"
+ bind:backgroundColor="normal"
+ bind:hoveredBackgroundColor="hover"
+ bind:pressedBackgroundColor="press"
+ textColor="#FF484848" hoveredTextColor="#FF484848" disabledTextColor="#FF484848" pressedTextColor="#FF484848"
+ bind:disabledBackgroundColor="normal"/>
+ </size>
+</padding> \ No newline at end of file
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknameColor.gui b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknameColor.gui
new file mode 100644
index 00000000..59b2082d
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknameColor.gui
@@ -0,0 +1,103 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<bgcolor backgroundColor="#FF111111">
+ <col crossAlign="START">
+ <padding left="10" top="10" right="10">
+ <Text text="Choose Nickname Color" color="#FFFFFFFF" size="12"/>
+ </padding>
+ <flexible>
+ <row>
+ <ConstrainedBox maxWidth="260">
+ <padding top="5" left="5" bottom="5" right="5">
+ <col>
+ <bgcolor backgroundColor="#FF000000">
+ <col crossAlign="CENTER">
+ <Text text="Preview" size="8" color="#FFFFFFFF"/>
+ <padding top="1" left="1" right="1" bottom="1">
+ <bgcolor backgroundColor="#FF222222">
+ <IntrinsicHeight>
+ <ScrollablePanel direction="HORIZONTAL">
+ <padding top="5" right="5" bottom="5" left="5">
+ <Text bind:text="preview" size="8" />
+ </padding>
+ </ScrollablePanel>
+ </IntrinsicHeight>
+ </bgcolor>
+ </padding>
+ </col>
+ </bgcolor>
+ <col mainAlign="CENTER">
+ <size height="3"/>
+ <row mainAlign="CENTER">
+ <Text text="Visit " color="#FFFFFFFF"/>
+ <Text text="Dungeons Guide Store" color="#FF74A0C6"/>
+ <Text text=" at " color="#FFFFFFFF"/>
+ <size height="16" width="16">
+ <IconButton location="dungeonsguide:textures/dglogox128round.png" width="128" height="128" on:click="shop"/>
+ </size>
+ </row>
+ <row mainAlign="CENTER">
+ <Text text="to purchase" color="#FFFFFFFF" align="CENTER"/>
+ <Text text=" cosmetics" color="#FFFFFF00" align="CENTER"/>
+ </row>
+ <size height="3"/>
+ <row mainAlign="CENTER">
+ <Text text="and " color="#FFFFFFFF" align="CENTER"/>
+ <Text text="support " color="#FFFFFF00" align="CENTER"/>
+ <Text text="Dungeons Guide!" color="#FFFFFFFF" align="CENTER"/>
+ </row>
+ </col>
+ </col>
+ </padding>
+ </ConstrainedBox>
+ <flexible>
+ <col>
+ <size height="5"/>
+ <Text text="Nickname Color" size="8" color="#FFFFFFFF"/>
+ <size height="5"/>
+ <line color="#FFFFFFFF"/>
+ <flexible fit="LOOSE">
+ <IntrinsicHeight>
+ <ScrollablePanel direction="VERTICAL">
+ <bgcolor backgroundColor="#FF000000">
+ <padding top="5" left="5" bottom="5" right="5">
+ <WrapGrid minimumWidth="50" gap="5" bind:_="colors"/>
+ </padding>
+ </bgcolor>
+ </ScrollablePanel>
+ </IntrinsicHeight>
+ </flexible>
+ <line color="#FFFFFFFF"/>
+ <padding top="5" left="5" bottom="5" right="5">
+ <row mainAlign="END">
+ <size width="60" height="20">
+ <RoundButton text="Clear" on:click="clear"/>
+ </size>
+ <size width="5" height="0"/>
+ <size width="60" height="20">
+ <RoundButton text="Apply" on:click="apply" bind:disabled="disabled"/>
+ </size>
+ </row>
+ </padding>
+ </col>
+ </flexible>
+ </row>
+ </flexible>
+ </col>
+</bgcolor> \ No newline at end of file
diff --git a/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknamePrefix.gui b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknamePrefix.gui
new file mode 100644
index 00000000..32bdd38e
--- /dev/null
+++ b/mod/src/main/resources/assets/dungeonsguide/gui/config/cosmetics/nicknamePrefix.gui
@@ -0,0 +1,119 @@
+<!--
+ ~ Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ ~ Copyright (C) 2023 cyoung06 (syeyoung)
+ ~
+ ~ This program is free software: you can redistribute it and/or modify
+ ~ it under the terms of the GNU Affero General Public License as published
+ ~ by the Free Software Foundation, either version 3 of the License, or
+ ~ (at your option) any later version.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ~ GNU Affero General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Affero General Public License
+ ~ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ -->
+
+<bgcolor backgroundColor="#FF111111">
+ <col crossAlign="START">
+ <padding left="10" top="10" right="10">
+ <Text text="Choose Nickname Prefix" color="#FFFFFFFF" size="12"/>
+ </padding>
+ <flexible>
+ <row>
+ <ConstrainedBox maxWidth="260">
+ <padding top="5" left="5" bottom="5" right="5">
+ <col>
+ <bgcolor backgroundColor="#FF000000">
+ <col crossAlign="CENTER">
+ <Text text="Preview" size="8" color="#FFFFFFFF"/>
+ <padding top="1" left="1" right="1" bottom="1">
+ <bgcolor backgroundColor="#FF222222">
+ <IntrinsicHeight>
+ <ScrollablePanel direction="HORIZONTAL">
+ <padding top="5" right="5" bottom="5" left="5">
+ <Text bind:text="preview" size="8" />
+ </padding>
+ </ScrollablePanel>
+ </IntrinsicHeight>
+ </bgcolor>
+ </padding>
+ </col>
+ </bgcolor>
+ <col mainAlign="CENTER">
+ <size height="3"/>
+ <row mainAlign="CENTER">
+ <Text text="Visit " color="#FFFFFFFF"/>
+ <Text text="Dungeons Guide Store" color="#FF74A0C6"/>
+ <Text text=" at " color="#FFFFFFFF"/>
+ <size height="16" width="16">
+ <IconButton location="dungeonsguide:textures/dglogox128round.png" width="128" height="128" on:click="shop"/>
+ </size>
+ </row>
+ <row mainAlign="CENTER">
+ <Text text="to purchase" color="#FFFFFFFF" align="CENTER"/>
+ <Text text=" cosmetics" color="#FFFFFF00" align="CENTER"/>
+ </row>
+ <size height="3"/>
+ <row mainAlign="CENTER">
+ <Text text="and " color="#FFFFFFFF" align="CENTER"/>
+ <Text text="support " color="#FFFFFF00" align="CENTER"/>
+ <Text text="Dungeons Guide!" color="#FFFFFFFF" align="CENTER"/>
+ </row>
+ </col>
+ </col>
+ </padding>
+ </ConstrainedBox>
+ <flexible>
+ <col>
+ <size height="5"/>
+ <Text text="Prefix" size="8" color="#FFFFFFFF"/>
+ <size height="5"/>
+ <line color="#FFFFFFFF"/>
+ <flexible fit="LOOSE">
+ <IntrinsicHeight>
+ <ScrollablePanel direction="VERTICAL">
+ <bgcolor backgroundColor="#FF000000">
+ <padding top="5" left="5" bottom="5" right="5">
+ <col bind:_="prefixes"/>
+ </padding>
+ </bgcolor>
+ </ScrollablePanel>
+ </IntrinsicHeight>
+ </flexible>
+ <line color="#FFFFFFFF"/>
+ <size height="5"/>
+ <Text text="Bracket Color (some prefixes override this)" size="8" color="#FFFFFFFF"/>
+ <size height="5"/>
+ <line color="#FFFFFFFF"/>
+ <flexible fit="LOOSE">
+ <IntrinsicHeight>
+ <ScrollablePanel direction="VERTICAL">
+ <bgcolor backgroundColor="#FF000000">
+ <padding top="5" left="5" bottom="5" right="5">
+ <WrapGrid minimumWidth="50" gap="5" bind:_="colors"/>
+ </padding>
+ </bgcolor>
+ </ScrollablePanel>
+ </IntrinsicHeight>
+ </flexible>
+ <line color="#FFFFFFFF"/>
+ <padding top="5" left="5" bottom="5" right="5">
+ <row mainAlign="END">
+ <size width="60" height="20">
+ <RoundButton text="Clear" on:click="clear"/>
+ </size>
+ <size width="5" height="0"/>
+ <size width="60" height="20">
+ <RoundButton text="Apply" on:click="apply" bind:disabled="disabled"/>
+ </size>
+ </row>
+ </padding>
+ </col>
+ </flexible>
+ </row>
+ </flexible>
+ </col>
+</bgcolor> \ No newline at end of file