aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr/syeyoung/dungeonsguide/mod/config
diff options
context:
space:
mode:
authorEryk Ruta <70776766+kingstefan26@users.noreply.github.com>2022-11-01 15:51:30 +0100
committerGitHub <noreply@github.com>2022-11-01 23:51:30 +0900
commit292fbd05e13271ca3ad99ebe00ae4302e04848f3 (patch)
tree2a7aeb12ab95ff688479a4727f76e3e4152c30b5 /src/main/java/kr/syeyoung/dungeonsguide/mod/config
parentdd7a4209752715db544b2fef804da9762c532cdc (diff)
downloadSkyblock-Dungeons-Guide-292fbd05e13271ca3ad99ebe00ae4302e04848f3.tar.gz
Skyblock-Dungeons-Guide-292fbd05e13271ca3ad99ebe00ae4302e04848f3.tar.bz2
Skyblock-Dungeons-Guide-292fbd05e13271ca3ad99ebe00ae4302e04848f3.zip
3rd time is the charm (#70)
* Updated some dependencies, used my crusty skytils forgegradle fork + removed the IRRELEVANT hytils fixes. generally made the thing build * made the logs less annoying * temp fix so it doesn't throw an exception * FAT REFACTOR General refactor on Authenticator.java DungeonsGuide.java Main.java removed unnecessary imports where not needed to be removed DGInterface.java (no real reason to exist) in DungeonsGuide.java made the retry stomp a singe-thread executor, so it doesn't leak when offline added an "offline mode" so it doesn't just error when server down TODO: move auth to DungeonsGuide.java and make it retry when network down on launch * New auth implementation that should replace the old one: does all the things the old one did removed progressBar cuz it would make the impl 3x more complicated in the name of a splash screen added a token changed event (so now it supports re-logging with a different account) code is (should) be more readable / extensible TODO: surgically replace Authenticator.java with new impl AND support re-logging * Made the chat processor logger name less obnoxious * implemented my implementation of an implementation of auth can and is very buggy, essentially the loading of the remote classes but the mod works so idk TODO: MAKE STOMP NOT DO STUFF TILL STOMPCONNECTED IS EMITTED * fix for stomp client null bc forge events not going tru on pre-init TODO: make work and test the web loadable classes, then make all the stuff that relies on stomp not throw exceptions when stomp is not connected * move the create auth method into AuthProvider interface, so we don't clutter AuthManager with implementation details * Decouple AuthProviderUtil and DgAuth, move some stuff around and make it more readable * moved AuthUtil to make more sense * de-clutter the tree a little bit * Inline StompClientStatus.java / refactor * inline the useless interface * refactoringgg * fix ahUtils exeption spam * small StompClient refactor * fix GLCursors exeption spam + logger * make sure we are authenticated when downloading resources * new .destination("value") instead of .header("destination", "value") * StompMessageHandler -> StompMessageSubscription * Introduced StompManager * fix dungeon map not showing ppl heads * ehhh * wip (commit cuz im chekig out) * fix player profile not never loading in chat * remove this specific line * fix player profile not never loading in chat * cut out hychat like a cancer * ApiFetchur now caches whole players not single profiles, added a switch profile button in gui * ugh git * Revert "cut out hychat like a cancer" This reverts commit 2ee11afa * ugh git x2 * I tried, good luck maintaining this * forgot to uncomment hychat fix * make my new party ready work and look ok * change the look and add some "somewhere" locations * make stomp connection "null safe" * i hate git * introduce callbacks on parameter change for cleaner code add one example * impl new system, half way done * now shows which profile is now selected put button on top a lil refactor * fix player profile sometimes not loading * add players knowing who is using dg (try to) * announcing that we are a dg user will get reworked in the future * update deps * make it not spam logs * sanity check for premium features so it doesn't 403 * add YoMamaOutdated that checks if you are using outdated dg * hychat?? anyone * try catch in FeatureRegistry * added Ether transmission ability * chat shredder borken, disabled for now * party deserves its own folder * dungeon stuff in dungeon folder * events folders moved * fix score data collection hanging forever if stomp is not connected * fix stomp never connecting * re-add the removed * fix wonky rendering * server side implementation is not ready, canning this for a future release * attempt to fix heads loading on main thread * discord * me when sonar lint * new consumer based stomp subscriptions * replace old with new subscriptions * remove the remains of StompSubscription and replace CloseListener with a forge event * StompSubscription is now a functional interface * remove unnecessary event message chains, feature logic should be in the feature * fix events being set up wrongly * Revert "fix events being set up wrongly" This reverts commit e6ea7efa557a5f5c8a3ea33be998717bc024b8cb. * Revert "remove unnecessary event message chains," This reverts commit 96f508bae85b33cdcef6be19226c00fc52a1439b. * fix stomp client sending payload object instead of the actual payload * fix null pointer on empty party * fix players with cosmetics name being white in tab * added message when not connected to dg changed YoMamaOutdated to use CloudFlare workers added client sided message queue * the mod doesn't init when outdated * mcmod.info * dont busy wait in authmenager * test pepole crusty tests * chill out the authmanager * name the thread pool in auth manager * clear most compiler warnings * make outdated check allow to play without the mod initialized * make first startup VERY noticeable, move config creation to main * major dungeon package refactor * refactor checkpoint * refactor checkpoint #1 * final refactor checkpoint #2 * remove the player if from version check, made the version check not nesssery for playing Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove trap room fix that didnt fix anything Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make secret beacons optional Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make the checkmarks on map align with the rest of everyone Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * removed debug function Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move the menus to make more sense + make destination text on secrets optional Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * improve dungeonMap performance by ~90% temporarly disabled 9 slot map player location due to bugs fix DungeonContext not getting player from ScoreBoard Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * add epic countdown on dungeon start (still wip) Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added a option to cache blockstaes Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added TabListUtil Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fixed epic countdown Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * (i want to sleep) made all the dungeon room detection async TODO: fix ol the bugs i created by doing that Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * stuff still broken but almost playable, unlike last commit Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * upload build jar to discord Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * cache the deps for the love of god Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * who needs linux and 32bit windows anyway Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * only upload to discord on beta branch Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added "kick" when a member joins party Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move stuff that sends chat to player into a separate class Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * use our chat queue instead of calling `thePlayer.addChatMessage` to proxy ourselves from 1.8 code Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Added and implemented MortDetector2000.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * extract duplicate + make more readable Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added dummy support in FeatureDebugTrap Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * gradle now puts version in mcmod.info Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove side effects from DgAuth.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move debug commands into debug CommandDgDebug.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fix key being wrong Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move epic countdown to dungeon huds, clean up Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Revert "who needs linux and 32bit windows anyway" This reverts commit 0f3c2d544a70fc799cd3215dad5e997c0c8b6c06. * make FeatureRegistry not static initialise to get rid of "ClassNotDefined" errors Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * null check on Exception since it threw NullPointers Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * finish up progress bar in DungeonsGuide.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * warn about null features Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move stuff around in SkyblockStatus, move the stuff that updates status into SkyblockStatus from DungeonListener Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * rename DungeonGodObject.java to DungeonFacade.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * add cleanChat clause in FeatureEpicCountdown Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * implement getPreRequisites and isComplete in ActionBreakWithSuperBoom Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * clean up FeatureParameter Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * eliminate possible state inconsistency in DungeonListener Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move percentage from DungeonFacade to DungeonContext Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move `purge` and `partymax` back into CommandDungeonsGuide Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * stop repeating ReceiveChatQueue in ChatTransmitter Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Clean up DungeonsGuide Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move `sendDebugChat` to `ChatTransmitter.java` Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * change CommandDgDebug into a `else if` from an `switch` because some bigot decided its better Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * duplicate code since it currently doesn't make sense, to be reworked Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fix typo Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove the trycatch so we fail fast Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fix null pointer when trying to get fontRenderer before minecraft is initialised Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * broken checkpoint 0 Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * broken checkpoint 1 Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Revert "broken checkpoint 1" This reverts commit 64985e6287c7b5650b509668e42b9803e25c419c. * Revert "broken checkpoint 0" This reverts commit 5f62e1345d9c8e7f66f1e5792004a05027913d92. * Revert "fix null pointer when trying to get fontRenderer before minecraft is initialised" This reverts commit 57d92a78d31c410f699b58c8995c94055d57e2a4. * Revert "remove the trycatch so we fail fast" This reverts commit 12772255ed575e411fb99edf37ec16d0e5f42924. * Revert "fix typo" This reverts commit aa96cc2436d3ead42d53ead78f3334fac5100713. * Revert "duplicate code since it currently doesn't make sense, to be reworked" This reverts commit 6d71b88e3102d23bcfd90d85e8996327776fd52f. * Revert "change CommandDgDebug into a `else if` from an `switch` because some bigot decided its better" This reverts commit ffea84d9b5fd4adbe034a88249bc920eafa7c53a. * Revert "move `sendDebugChat` to `ChatTransmitter.java`" This reverts commit 5b8b2e22fff33768134a01c15c7650100ebb9257. * Revert "Clean up DungeonsGuide" This reverts commit 2069ad3ebc4344eb1e778954dc1d8f6c9303de69. * fix typo Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> (cherry picked from commit aa96cc2436d3ead42d53ead78f3334fac5100713) * duplicate code since it currently doesn't make sense, to be reworked Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> (cherry picked from commit 6d71b88e3102d23bcfd90d85e8996327776fd52f) * change CommandDgDebug into a `else if` from an `switch` because some bigot decided its better Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> (cherry picked from commit ffea84d9b5fd4adbe034a88249bc920eafa7c53a) * move debug chat into ChatTransmitter Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * null pointer in SkyblockStatus bc context was not initialised yet Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move dungeon starting door detection up the tree since it was a duplicate in both children, inline MortDetector2000 Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move dungeon name to DungeonContext Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * clean up Main Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * separate the "loader" and "mod" Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * separate DungeonsGuide and Main even more Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * change singleton implementation of DungeonsGuide Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move classes since their paths are hardcoded into roomdatas Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * create CatacombsDataProvider.java and implement it Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove unnecessary `DungeonsGuide.getDungeonsGuide();` (IntelliJ refactor bug) Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move `help` text in commands Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * a certain someone hates switch statements Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove my version check, since we have to wait for out lord and savior to make his own Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make `Main` and `DungeonsGuide` compatible with supported jar classloading Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make the beta upload action run on push since it didnt get the secret on pull request and failed anyway, TODO: make the jar name not hardcoded Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * upload all jar Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> Co-authored-by: syeyoung <42869671+cyoung06@users.noreply.github.com>
Diffstat (limited to 'src/main/java/kr/syeyoung/dungeonsguide/mod/config')
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/Config.java65
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/ConfigPanelCreator.java40
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/GuiConfigV2.java59
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategory.java103
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategoryElement.java82
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeature.java154
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeatureEdit.java113
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MNotFound.java38
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MPanelCategory.java83
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MParameterEdit.java219
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/NestedCategory.java54
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java311
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/GuiGuiLocationConfig.java166
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/Marker.java45
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/PanelDelegate.java403
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/AColor.java63
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/GUIRectangle.java81
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCAColor.java51
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCBoolean.java39
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCColor.java41
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCFloat.java39
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCGUIRectangle.java50
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCInteger.java39
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCKeybind.java39
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCRectangle.java51
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCString.java39
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCStringList.java51
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyle.java52
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyleList.java54
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverter.java29
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverterRegistry.java52
31 files changed, 2705 insertions, 0 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/Config.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/Config.java
new file mode 100644
index 00000000..0e1bf7fd
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/Config.java
@@ -0,0 +1,65 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+
+import java.io.*;
+
+public class Config {
+ public static JsonObject configuration;
+
+ public static File f;
+
+ public static void loadConfig(File f) throws IOException {
+ try {
+ configuration = (JsonObject) new JsonParser().parse(new InputStreamReader(new FileInputStream(Config.f = f == null ? Config.f : f)));
+ } catch (Exception e) {
+ configuration = new JsonObject();
+ }
+ for (AbstractFeature feature : FeatureRegistry.getFeatureList()) {
+ JsonObject object = configuration.getAsJsonObject(feature.getKey());
+ if (object != null) feature.loadConfig(object);
+ }
+
+ saveConfig();
+ }
+
+ public static void saveConfig() throws IOException {
+ for (AbstractFeature feature : FeatureRegistry.getFeatureList()) {
+ JsonObject object = feature.saveConfig();
+ configuration.add(feature.getKey(), object);
+ }
+
+ String str = new Gson().toJson(configuration);
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(f);
+ BufferedWriter bos = new BufferedWriter(new OutputStreamWriter(fos));
+ bos.write(str);
+ bos.flush();
+ } finally {
+ fos.close();
+ }
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/ConfigPanelCreator.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/ConfigPanelCreator.java
new file mode 100644
index 00000000..da3974a3
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/ConfigPanelCreator.java
@@ -0,0 +1,40 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ConfigPanelCreator implements Function<String, MPanel> {
+ public static final ConfigPanelCreator INSTANCE = new ConfigPanelCreator();
+
+ public static final Map<String, Supplier<MPanel>> map = new HashMap<String, Supplier<MPanel>>();
+
+ @Nullable
+ @Override
+ public MPanel apply(@Nullable String input) {
+ if (!map.containsKey(input)) return null;
+ return map.get(input).get();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/GuiConfigV2.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/GuiConfigV2.java
new file mode 100644
index 00000000..0f6be522
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/GuiConfigV2.java
@@ -0,0 +1,59 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.gui.MGui;
+import lombok.Getter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.MathHelper;
+
+import java.awt.*;
+
+public class GuiConfigV2 extends MGui {
+
+ @Getter
+ private RootConfigPanel rootConfigPanel;
+
+ public GuiConfigV2() {
+ rootConfigPanel = new RootConfigPanel(this);
+ getMainPanel().add(rootConfigPanel);
+ }
+
+
+ @Override
+ public void initGui() {
+ super.initGui();
+ int dw = Minecraft.getMinecraft().displayWidth;
+ int dh = Minecraft.getMinecraft().displayHeight;
+ int width = MathHelper.clamp_int(dw - 200, 1250, 1500), height = MathHelper.clamp_int(dh - 200, 600, 800);
+ double scale = 2.0;
+ if (dw <= width || dh <= height) {
+ width = width/2; height = height/2;
+ scale = 1.0;
+ }
+ rootConfigPanel.setBounds(new Rectangle((dw-width)/2, (dh-height)/2, width,height));
+ rootConfigPanel.setScale(scale);
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ super.drawDefaultBackground();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategory.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategory.java
new file mode 100644
index 00000000..c4561c09
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategory.java
@@ -0,0 +1,103 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import kr.syeyoung.dungeonsguide.mod.utils.cursor.EnumCursor;
+import lombok.Getter;
+import lombok.Setter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL14;
+
+import java.awt.*;
+
+public class MCategory extends MPanel {
+
+ private NestedCategory nestedCategory;
+ private RootConfigPanel rootConfigPanel;
+ @Getter
+ @Setter
+ private Color hover = new Color(94, 94, 94, 255);
+ public MCategory(NestedCategory nestedCategory, RootConfigPanel rootConfigPanel) {
+ this.nestedCategory = nestedCategory;
+ this.rootConfigPanel = rootConfigPanel;
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ int border = RenderUtils.blendAlpha(0x141414, 0.12f);
+ if (!rootConfigPanel.getSearchWord().isEmpty() && (nestedCategory.categoryName().toLowerCase().contains(rootConfigPanel.getSearchWord()))) {
+ border = 0xFF02EE67;
+ }
+
+ Gui.drawRect(0,0,getBounds().width, getBounds().height,border);
+ if (getBounds().height >= 28)
+ Gui.drawRect(1,18,getBounds().width -1, getBounds().height-1, RenderUtils.blendAlpha(0x141414, 0.15f));
+ Gui.drawRect(1,1,getBounds().width-1, 18, RenderUtils.blendAlpha(0x141414, 0.12f));
+
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(5,5,0);
+ GlStateManager.scale(1.0,1.0,0);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+ fr.drawString((lastAbsClip.contains(absMousex, absMousey) ? "§n" : "") + nestedCategory.categoryName(), 0,0, 0xFFFFFFFF);
+ GlStateManager.popMatrix();
+
+ fr.drawSplitString(FeatureRegistry.getCategoryDescription().getOrDefault(nestedCategory.categoryFull(), ""), 5, 23, getBounds().width -10, 0xFFBFBFBF);
+ }
+
+
+ @Override
+ public Dimension getPreferredSize() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+
+ int descriptionHeight =
+ FeatureRegistry.getCategoryDescription().containsKey(nestedCategory.categoryFull()) ?
+ fr.listFormattedStringToWidth(FeatureRegistry.getCategoryDescription().get(nestedCategory.categoryFull()), Math.max(100, getBounds().width - 10)).size() * fr.FONT_HEIGHT
+ : -9;
+
+ return new Dimension(100, descriptionHeight + 28);
+ }
+
+ @Override
+ public void mouseClicked(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int mouseButton) {
+ if (lastAbsClip.contains(absMouseX, absMouseY)) {
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+ rootConfigPanel.setCurrentPageAndPushHistory(nestedCategory.categoryFull());
+ }
+ }
+
+ @Override
+ public void mouseMoved(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0) {
+ if (lastAbsClip.contains(absMouseX, absMouseY))
+ setCursor(EnumCursor.POINTING_HAND);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategoryElement.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategoryElement.java
new file mode 100644
index 00000000..74f5f352
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MCategoryElement.java
@@ -0,0 +1,82 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import kr.syeyoung.dungeonsguide.mod.utils.cursor.EnumCursor;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.audio.PositionedSoundRecord;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.util.ResourceLocation;
+
+import java.awt.*;
+
+public class MCategoryElement extends MPanel {
+ private String category;
+ private Runnable onClick;
+ private int leftPad = 0;
+ private int offsetX;
+ private RootConfigPanel rootConfigPanel;
+ public MCategoryElement(String category, Runnable onClick, int leftPad, int offsetX, RootConfigPanel rooot) {
+ this.category = category;
+ this.onClick = onClick;
+ this.leftPad = leftPad;
+ this.offsetX = offsetX;
+ this.rootConfigPanel = rooot;
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ if (rootConfigPanel.getCurrentPage().equals(category)) {
+ clip(0,scissor.y, Minecraft.getMinecraft().displayWidth, scissor.height);
+ Gui.drawRect(leftPad - offsetX, 0, getBounds().width, getBounds().height, RenderUtils.blendAlpha(0x141414, 0.13f));
+ } else if (lastAbsClip.contains(absMousex, absMousey) && getTooltipsOpen() == 0) {
+ clip(0,scissor.y, Minecraft.getMinecraft().displayWidth, scissor.height);
+ Gui.drawRect(leftPad - offsetX, 0, getBounds().width, getBounds().height, RenderUtils.blendAlpha(0x141414, 0.09f));
+ }
+ clip(scissor.x, scissor.y, scissor.width, scissor.height);
+
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ String name = category.substring(category.lastIndexOf(".")+1);
+ fr.drawString(name, leftPad,2,-1);
+
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ return new Dimension(fr.getStringWidth(category.substring(category.lastIndexOf(".")+1)) + leftPad+10, fr.FONT_HEIGHT+4);
+ }
+
+ @Override
+ public void mouseClicked(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int mouseButton) {
+ if (!lastAbsClip.contains(absMouseX, absMouseY) || getTooltipsOpen() > 0) { return; }
+ if (onClick != null) onClick.run();
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
+
+ }
+ @Override
+ public void mouseMoved(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0) {
+ if (lastAbsClip.contains(absMouseX, absMouseY))
+ setCursor(EnumCursor.POINTING_HAND);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeature.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeature.java
new file mode 100644
index 00000000..070f4fce
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeature.java
@@ -0,0 +1,154 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.config.guiconfig.location.GuiGuiLocationConfig;
+import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature;
+import kr.syeyoung.dungeonsguide.mod.features.GuiFeature;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MButton;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MToggleButton;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Getter;
+import lombok.Setter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.renderer.GlStateManager;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL14;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MFeature extends MPanel {
+
+ @Getter
+ private final AbstractFeature feature;
+
+ private final List<MPanel> addons = new ArrayList<MPanel>();
+
+ @Getter @Setter
+ private Color hover;
+
+ private final RootConfigPanel panel;
+
+ public MFeature(final AbstractFeature abstractFeature, final RootConfigPanel panel) {
+ this.panel = panel;
+ this.feature = abstractFeature;
+
+ if (abstractFeature.isDisyllable()) {
+ final MToggleButton mStringSelectionButton = new MToggleButton();
+ mStringSelectionButton.setOnToggle(new Runnable() {
+ @Override
+ public void run() {
+ boolean selected = mStringSelectionButton.isEnabled();
+ feature.setEnabled(selected);
+ }
+ });
+ mStringSelectionButton.setBackground(RenderUtils.blendAlpha(0x141414, 0.07f));
+ addons.add(mStringSelectionButton);
+ mStringSelectionButton.setEnabled(feature.isEnabled());
+ mStringSelectionButton.setSize(new Dimension(40, 15));
+ add(mStringSelectionButton);
+ }
+ if (abstractFeature.getParameters().size() != 0) {
+ MButton button = new MButton();
+ button.setText("Settings");
+ button.setOnActionPerformed(new Runnable() {
+ @Override
+ public void run() {
+ panel.setCurrentPageAndPushHistory(abstractFeature.getEditRoute(panel));
+ }
+ });
+ button.setBackground(RenderUtils.blendAlpha(0x141414, 0.07f));
+ button.setClicked(RenderUtils.blendAlpha(0x141414, 0.17f));
+ button.setHover(RenderUtils.blendAlpha(0x141414, 0.17f));
+ addons.add(button);
+ button.setSize(new Dimension(50, 15));
+ add(button);
+ }
+ if (abstractFeature instanceof GuiFeature) {
+ MButton button = new MButton();
+ button.setText("Relocate");
+ button.setOnActionPerformed(new Runnable() {
+ @Override
+ public void run() {
+ Minecraft.getMinecraft().displayGuiScreen(new GuiGuiLocationConfig(Minecraft.getMinecraft().currentScreen, abstractFeature));
+ button.setIsclicked(false);
+ }
+ });
+ button.setBackground(RenderUtils.blendAlpha(0x141414, 0.07f));
+ button.setClicked(RenderUtils.blendAlpha(0x141414, 0.17f));
+ button.setHover(RenderUtils.blendAlpha(0x141414, 0.17f));
+ addons.add(button);
+ button.setSize(new Dimension(75, 15));
+ add(button);
+ }
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+
+ int border = RenderUtils.blendAlpha(0x141414, 0.12f);
+ if (!panel.getSearchWord().isEmpty() && (feature.getName().toLowerCase().contains(panel.getSearchWord()) || feature.getDescription().toLowerCase().contains(panel.getSearchWord()))) {
+ border = 0xFF02EE67;
+ }
+
+ Gui.drawRect(0,0,getBounds().width, getBounds().height,border);
+ Gui.drawRect(1,18,getBounds().width -1, getBounds().height-1, RenderUtils.blendAlpha(0x141414, 0.15f));
+ Gui.drawRect(1,1,getBounds().width-1, 18, RenderUtils.blendAlpha(0x141414, 0.12f));
+
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(5,5,0);
+ GlStateManager.scale(1.0,1.0,0);
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ fr.drawString(feature.getName(), 0,0, 0xFFFFFFFF);
+ GlStateManager.popMatrix();
+
+ fr.drawSplitString(feature.getDescription(), 5, 23, getBounds().width -10, 0xFFBFBFBF);
+ }
+
+ @Override
+ public void resize(int parentWidth, int parentHeight) {
+ this.setSize(new Dimension(parentWidth, getBounds().height));
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ int descriptionHeight = fr.listFormattedStringToWidth(feature.getDescription(), Math.max(100, getBounds().width - 10)).size() * fr.FONT_HEIGHT;
+
+ return new Dimension(100, descriptionHeight + 28);
+ }
+
+ @Override
+ public void onBoundsUpdate() {
+ int x = getBounds().width - 5;
+ for (MPanel panel : addons) {
+ panel.setBounds(new Rectangle(x - panel.getPreferredSize().width, 3, panel.getPreferredSize().width, 12));
+ x -= panel.getPreferredSize().width + 5;
+ }
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeatureEdit.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeatureEdit.java
new file mode 100644
index 00000000..87e1b6f1
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MFeatureEdit.java
@@ -0,0 +1,113 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureParameter;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MButton;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MList;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MModalConfirmation;
+
+import java.awt.*;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MFeatureEdit extends MPanel {
+ private MList list;
+ private MButton goBack, resetToDefault;
+ private RootConfigPanel rootConfigPanel;
+ private AbstractFeature abstractFeature;
+
+ private Map<String, MPanel> parameterEdits = new HashMap<>();
+
+ public MFeatureEdit(AbstractFeature abstractFeature, RootConfigPanel rootConfigPanel) {
+ this.abstractFeature = abstractFeature;
+ this.rootConfigPanel = rootConfigPanel;
+ list = new MList();
+ list.setGap(5);
+ list.setDrawLine(false);
+ add(list);
+
+ goBack = new MButton();
+ goBack.setText("< Go Back");
+ goBack.setOnActionPerformed(rootConfigPanel::goBack);
+ add(goBack);
+ resetToDefault = new MButton();
+ resetToDefault.setText("Reset To Default");
+ resetToDefault.setForeground(Color.red);
+ resetToDefault.setOnActionPerformed(() -> {
+ openResetConfirmation();
+ });
+ add(resetToDefault);
+ }
+
+ public void openResetConfirmation() {
+ MModalConfirmation mModal = new MModalConfirmation("Are you sure?",
+ "Resetting to default will reset your configuration for the selected feature to default",
+ () -> {
+ for (FeatureParameter parameter : abstractFeature.getParameters()) {
+ parameter.setToDefault();
+ }
+ abstractFeature.onParameterReset();
+ rootConfigPanel.invalidatePage(abstractFeature.getEditRoute(rootConfigPanel));
+ }, () -> {});
+ mModal.setScale(getScale());
+ mModal.getYes().setBorder(0xFFFF0000);
+ mModal.getYes().setText("Yes, Reset it");
+ mModal.getNo().setText("Cancel");
+ mModal.open(MFeatureEdit.this);
+ }
+
+ public void addParameterEdit(String name, MPanel paramEdit) {
+ parameterEdits.put(name, paramEdit);
+ list.add(paramEdit);
+ }
+ public MPanel removeParameterEdit(String name) {
+ MPanel panel = parameterEdits.remove(name);
+ list.remove(panel);
+ return panel;
+ }
+
+ @Override
+ public void resize(int parentWidth, int parentHeight) {
+ super.resize(parentWidth, parentHeight);
+ setBounds(new Rectangle(0,0,parentWidth,parentHeight));
+ Dimension prefSize = getPreferredSize();
+ int hei = prefSize.height;
+ setBounds(new Rectangle(0,0,parentWidth,hei));
+ }
+
+ @Override
+ public void setBounds(Rectangle bounds) {
+ super.setBounds(bounds);
+ goBack.setBounds(new Rectangle(5,5,75,15));
+ resetToDefault.setBounds(new Rectangle(bounds.width - 105, 5, 100, 15));
+
+ list.setBounds(new Rectangle(5,25,bounds.width - 10, bounds.height - 10));
+ list.realignChildren();
+
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension listPref = list.getPreferredSize();
+ return new Dimension(listPref.width + 10, listPref.height + 30);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MNotFound.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MNotFound.java
new file mode 100644
index 00000000..b63c4e90
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MNotFound.java
@@ -0,0 +1,38 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+
+import java.awt.*;
+
+public class MNotFound extends MPanel {
+ @Override
+ public void resize(int parentWidth, int parentHeight) {
+ setBounds(new Rectangle(0,0,parentWidth,parentHeight));
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("404 Not Found", (getBounds().width - fr.getStringWidth("404 Not Found")) / 2, (getBounds().height - fr.FONT_HEIGHT) / 2, -1);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MPanelCategory.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MPanelCategory.java
new file mode 100644
index 00000000..435940d3
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MPanelCategory.java
@@ -0,0 +1,83 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MList;
+
+import java.awt.*;
+
+public class MPanelCategory extends MPanel {
+
+ private NestedCategory key;
+ private RootConfigPanel rootConfigPanel;
+
+ private MList list;
+
+ public MPanelCategory(NestedCategory nestedCategory, RootConfigPanel rootConfigPanel) {
+ this.key = nestedCategory;
+ this.rootConfigPanel = rootConfigPanel;
+
+ list = new MList();
+ list.setDrawLine(false);
+ list.setGap(5);
+ add(list);
+
+ for (NestedCategory value : nestedCategory.children().values()) {
+ list.add(new MCategory(value, rootConfigPanel));
+ }
+ if (nestedCategory.parent() != null) {
+ String actualCategory = nestedCategory.categoryFull().substring(5);
+ if (FeatureRegistry.getFeaturesByCategory().containsKey(actualCategory))
+ for (AbstractFeature abstractFeature : FeatureRegistry.getFeaturesByCategory().get(actualCategory)) {
+ MFeature mFeature = new MFeature(abstractFeature, rootConfigPanel);
+ list.add(mFeature);
+ mFeature.setHover(new Color(94, 94, 94, 255));
+ }
+ }
+ list.realignChildren();
+
+ }
+
+ @Override
+ public void resize(int parentWidth, int parentHeight) {
+ super.resize(parentWidth, parentHeight);
+ setBounds(new Rectangle(0,0,parentWidth,parentHeight));
+ Dimension prefSize = getPreferredSize();
+ int hei = prefSize.height;
+ setBounds(new Rectangle(0,0,parentWidth,hei));
+ }
+
+ @Override
+ public void setBounds(Rectangle bounds) {
+ super.setBounds(bounds);
+ list.setBounds(new Rectangle(5,5,bounds.width- 10, bounds.height - 10));
+ list.realignChildren();
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension prefSize = list.getPreferredSize();
+ int wid = prefSize.width + 10;
+ int hei = prefSize.height + 10;
+ return new Dimension(wid, hei);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MParameterEdit.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MParameterEdit.java
new file mode 100644
index 00000000..e73e851b
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/MParameterEdit.java
@@ -0,0 +1,219 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import kr.syeyoung.dungeonsguide.mod.config.types.AColor;
+import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureParameter;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.*;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+
+import java.awt.*;
+import java.util.function.Predicate;
+
+public class MParameterEdit extends MPanel {
+ private AbstractFeature abstractFeature;
+ private FeatureParameter featureParameter;
+ private RootConfigPanel rootConfigPanel;
+ private MPanel valueEditHolder;
+ private MPanel valueEdit;
+
+ private Predicate<FeatureParameter> isDisabled ;
+
+ public MParameterEdit(AbstractFeature abstractFeature, FeatureParameter parameter, RootConfigPanel rootConfigPanel) {
+ this(abstractFeature, parameter, rootConfigPanel, (a) -> false);
+ }
+
+ public MParameterEdit(AbstractFeature abstractFeature, FeatureParameter parameter, RootConfigPanel rootConfigPanel, Predicate<FeatureParameter> isDisabled ) {
+ this.abstractFeature = abstractFeature;
+ this.featureParameter = parameter;
+ this.rootConfigPanel = rootConfigPanel;
+ this.isDisabled = isDisabled;
+
+ if (parameter.getValue_type().equals("string")) {
+ valueEdit = new MTextField() {
+ @Override
+ public void edit(String str) {
+ parameter.setValue(str);
+ }
+ };
+ ((MTextField)valueEdit).setText((String) parameter.getValue());
+ } else if (parameter.getValue_type().equals("integer")) {
+ valueEdit = new MIntegerSelectionButton((Integer) parameter.getValue());
+ ((MIntegerSelectionButton)valueEdit).setOnUpdate(() -> {
+ parameter.setValue(((MIntegerSelectionButton) valueEdit).getData());
+ });
+ } else if (parameter.getValue_type().equals("float")) {
+ valueEdit = new MFloatSelectionButton((Float) parameter.getValue());
+ ((MFloatSelectionButton)valueEdit).setOnUpdate(() -> {
+ parameter.setValue(((MFloatSelectionButton) valueEdit).getData());
+ });
+ } else if (parameter.getValue_type().equals("acolor")) {
+ valueEdit = new MEditableAColor();
+ ((MEditableAColor)valueEdit).setColor((AColor) parameter.getValue());
+ ((MEditableAColor)valueEdit).setEnableEdit(true);
+ ((MEditableAColor)valueEdit).setOnUpdate(() -> {
+ parameter.setValue(((MEditableAColor) valueEdit).getColor());
+ });
+ } else if (parameter.getValue_type().equals("color")) {
+ valueEdit = new MEditableAColor();
+ ((MEditableAColor)valueEdit).setColor(new AColor(((Color) parameter.getValue()).getRGB(), true));
+ ((MEditableAColor)valueEdit).setEnableEdit(true);
+ ((MEditableAColor)valueEdit).setOnUpdate(() -> {
+ parameter.setValue(((MEditableAColor) valueEdit).getColor());
+ });
+ } else if (parameter.getValue_type().equals("boolean")) {
+ valueEdit = new MToggleButton();
+ ((MToggleButton)valueEdit).setEnabled((Boolean) parameter.getValue());
+ ((MToggleButton)valueEdit).setOnToggle(() -> {
+ parameter.setValue(((MToggleButton) valueEdit).isEnabled());
+ });
+ } else if (parameter.getValue_type().equals("keybind")) {
+ valueEdit = new MKeyEditButton();
+ ((MKeyEditButton)valueEdit).setKey((Integer) parameter.getValue());
+ ((MKeyEditButton)valueEdit).setOnKeyEdit(() -> {
+ parameter.setValue(((MKeyEditButton) valueEdit).getKey());
+ });
+ ((MKeyEditButton)valueEdit).setBorder(RenderUtils.blendTwoColors(0xFF141414,0x7702EE67));
+ }else {
+ valueEdit = new MLabel();
+ ((MLabel)valueEdit).setText("????");
+ }
+
+
+ valueEditHolder = new MPanel() {
+ @Override
+ public void setBounds(Rectangle bounds) {
+ super.setBounds(bounds);
+ Dimension dimension = valueEdit.getPreferredSize();
+ if (dimension.width <= 0) dimension.width = bounds.width/2;
+ if (dimension.height <= 0) dimension.height = bounds.height/2;
+ valueEdit.setBounds(new Rectangle((bounds.width - dimension.width)/2,(bounds.height - dimension.height)/2,dimension.width, dimension.height));
+ }
+ };
+ add(valueEditHolder);
+ valueEditHolder.add(valueEdit);
+ }
+ public MParameterEdit(AbstractFeature abstractFeature, FeatureParameter parameter, RootConfigPanel rootConfigPanel, MPanel valueEdit, Predicate<FeatureParameter> isDisabled) {
+ this.abstractFeature = abstractFeature;
+ this.featureParameter = parameter;
+ this.rootConfigPanel = rootConfigPanel;
+ this.isDisabled = isDisabled;
+
+
+ valueEditHolder = new MPanel() {
+ @Override
+ public void setBounds(Rectangle bounds) {
+ super.setBounds(bounds);
+ Dimension dimension = valueEdit.getPreferredSize();
+ if (dimension.width <= 0) dimension.width = bounds.width/2;
+ if (dimension.height <= 0) dimension.height = bounds.height/2;
+ valueEdit.setBounds(new Rectangle((bounds.width - dimension.width)/2,(bounds.height - dimension.height)/2,dimension.width, dimension.height));
+ }
+ };
+ add(valueEditHolder);
+ valueEditHolder.add(valueEdit);
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ Gui.drawRect(0,0,getBounds().width, getBounds().height, RenderUtils.blendAlpha(0x141414, 0.12f));
+ Gui.drawRect(2*bounds.width / 3,1,getBounds().width -1, getBounds().height-1, RenderUtils.blendAlpha(0x141414, 0.15f));
+ Gui.drawRect(4, 15,2*bounds.width / 3-5, 16, RenderUtils.blendAlpha(0x141414, 0.3f));
+
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString(featureParameter.getName(), 5,5, 0xFFFFFFFF);
+ fr.drawSplitString(featureParameter.getDescription(), 5,18, 2*bounds.width /3-10, 0xFFAAAAAA);
+
+ }
+
+ @Override
+ public void render0(double scale, Point parentPoint, Rectangle parentClip, int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks) {
+ super.render0(scale, parentPoint, parentClip, absMousex, absMousey, relMousex0, relMousey0, partialTicks);
+ if (isDisabled.test(featureParameter)) {
+ Gui.drawRect(0,0, getBounds().width, getBounds().height, 0x55000000);
+ }
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ int descriptionHeight = fr.listFormattedStringToWidth(featureParameter.getDescription(), Math.max(50, 2*bounds.width/3-10)).size() * fr.FONT_HEIGHT;
+ return new Dimension(100, Math.max(30, descriptionHeight + 23));
+ }
+
+ @Override
+ public void setBounds(Rectangle bounds) {
+ super.setBounds(bounds);
+ valueEditHolder.setBounds(new Rectangle(2*bounds.width / 3, 0, bounds.width / 3, bounds.height));
+ }
+
+ @Override
+ public void keyPressed0(char typedChar, int keyCode) {
+ if (isDisabled.test(featureParameter)) return;
+ super.keyPressed0(typedChar, keyCode);
+ }
+
+ @Override
+ public void keyHeld0(char typedChar, int keyCode) {
+ if (isDisabled.test(featureParameter)) return;
+ super.keyHeld0(typedChar, keyCode);
+ }
+
+ @Override
+ public void keyReleased0(char typedChar, int keyCode) {
+ if (isDisabled.test(featureParameter)) return;
+ super.keyReleased0(typedChar, keyCode);
+ }
+
+ @Override
+ public boolean mouseClicked0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int mouseButton) {
+ if (isDisabled.test(featureParameter)) return false;
+ return super.mouseClicked0(absMouseX, absMouseY, relMouseX0, relMouseY0, mouseButton);
+ }
+
+ @Override
+ public void mouseReleased0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int state) {
+ if (isDisabled.test(featureParameter)) return ;
+ super.mouseReleased0(absMouseX, absMouseY, relMouseX0, relMouseY0, state);
+ }
+
+ @Override
+ public void mouseClickMove0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int clickedMouseButton, long timeSinceLastClick) {
+ if (isDisabled.test(featureParameter)) return ;
+ super.mouseClickMove0(absMouseX, absMouseY, relMouseX0, relMouseY0, clickedMouseButton, timeSinceLastClick);
+ }
+
+ @Override
+ public void mouseScrolled0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int scrollAmount) {
+ if (isDisabled.test(featureParameter)) return ;
+ super.mouseScrolled0(absMouseX, absMouseY, relMouseX0, relMouseY0, scrollAmount);
+ }
+
+ @Override
+ public void mouseMoved0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0) {
+ if (isDisabled.test(featureParameter)) return ;
+ super.mouseMoved0(absMouseX, absMouseY, relMouseX0, relMouseY0);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/NestedCategory.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/NestedCategory.java
new file mode 100644
index 00000000..28a3d4d1
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/NestedCategory.java
@@ -0,0 +1,54 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Data
+@Accessors(chain = true, fluent = true)
+public
+class NestedCategory {
+ private final String categoryFull;
+ @EqualsAndHashCode.Exclude
+ private String categoryName;
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private NestedCategory parent;
+
+ public NestedCategory(String categoryFull) {
+ this.categoryFull = categoryFull;
+ this.categoryName = categoryFull.substring(categoryFull.lastIndexOf(".") + 1);
+ }
+
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Map<String, NestedCategory> children = new LinkedHashMap<>();
+
+ public NestedCategory child(NestedCategory child) {
+ this.children.put(child.categoryName, child);
+ child.parent = this;
+ return this;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java
new file mode 100644
index 00000000..d4d7dcf9
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java
@@ -0,0 +1,311 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig;
+
+import com.google.common.base.Function;
+import kr.syeyoung.dungeonsguide.auth.AuthManager;
+import kr.syeyoung.dungeonsguide.mod.config.guiconfig.location.GuiGuiLocationConfig;
+import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.*;
+import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import lombok.Getter;
+import lombok.Setter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+
+import java.awt.*;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+public class RootConfigPanel extends MPanelScaledGUI {
+ private MScrollablePanel navigationScroll;
+
+ private MList navigation = new MList();
+
+ private MScrollablePanel contentScroll;
+
+
+ private final Map<String, MPanel> pages = new HashMap<String, MPanel>();
+ @Getter
+ @Setter
+ private Function<String, MPanel> pageGenerator = ConfigPanelCreator.INSTANCE;
+ @Getter
+ private String currentPage = "";
+
+ private GuiConfigV2 gui;
+
+ private long lastPageSet = System.currentTimeMillis();
+
+ private MTextField search;
+ private MButton guiRelocate;
+
+ private MButton github, discord;
+
+ private final Stack<String> history = new Stack<String>();
+
+ public String getSearchWord() {
+ return search.getText().trim().toLowerCase();
+ }
+
+ public RootConfigPanel(GuiConfigV2 guiConfigV2) {
+ this.gui = guiConfigV2;
+
+ search = new MTextField() {
+ @Override
+ public void edit(String str) {
+ setupNavigation();
+
+ setCurrentPageAndPushHistory("");
+ if (!categoryMap.containsKey(lastOpenCategory)) {
+ for (Map.Entry<NestedCategory, MPanel> nestedCategoryMPanelEntry : categoryMap.entrySet()) {
+ if (nestedCategoryMPanelEntry.getValue() instanceof MCategoryElement) {
+ setCurrentPageAndPushHistory(nestedCategoryMPanelEntry.getKey().categoryFull());
+ lastOpenCategory = nestedCategoryMPanelEntry.getKey();
+ break;
+ }
+ }
+ }
+ for (Map.Entry<NestedCategory, MPanel> nestedCategoryMPanelEntry : categoryMap.entrySet()) {
+ if (nestedCategoryMPanelEntry.getValue() instanceof MCollapsable) {
+ ((MCollapsable) nestedCategoryMPanelEntry.getValue()).setCollapsed(false);
+ }
+ }
+ rePlaceElements();
+ }
+ };
+ search.setPlaceHolder("Search...");
+ add(search);
+ guiRelocate = new MButton();
+ guiRelocate.setText("Edit Gui Locations");
+ guiRelocate.setOnActionPerformed(() -> {
+ Minecraft.getMinecraft().displayGuiScreen(new GuiGuiLocationConfig(gui, null));
+ guiRelocate.setIsclicked(false);
+ });
+ guiRelocate.setBorder(RenderUtils.blendTwoColors(0xFF141414,0x7702EE67));
+ add(guiRelocate);
+
+ discord = new MButton(); github = new MButton();
+ discord.setText("Discord"); github.setText("Github");
+ discord.setBorder(RenderUtils.blendTwoColors(0xFF141414,0x7702EE67));
+ github.setBorder(RenderUtils.blendTwoColors(0xFF141414,0x7702EE67));
+ github.setOnActionPerformed(() -> {
+ try {
+ Desktop.getDesktop().browse(new URI("https://github.com/Dungeons-Guide/Skyblock-Dungeons-Guide/"));
+ } catch (IOException | URISyntaxException e) {
+ e.printStackTrace();
+ }
+ });
+ discord.setOnActionPerformed(() -> {
+ try {
+ Desktop.getDesktop().browse(new URI("https://discord.gg/VuxayCWGE8"));
+ } catch (IOException | URISyntaxException e) {
+ e.printStackTrace();
+ }
+ });
+ add(discord); add(github);
+
+ navigationScroll = new MScrollablePanel(1);
+ navigationScroll.setHideScrollBarWhenNotNecessary(false);
+
+
+ add(navigationScroll);
+ navigationScroll.add(navigation);
+
+ contentScroll = new MScrollablePanel(3);
+ contentScroll.setHideScrollBarWhenNotNecessary(true);
+ add(contentScroll);
+
+ setupNavigation();
+ navigation.setGap(0);
+ navigation.setDrawLine(false);
+
+ setCurrentPageAndPushHistory("ROOT");
+ rePlaceElements();
+
+ search.setFocused(true);
+ }
+
+
+ private Map<NestedCategory, MPanel> categoryMap = new HashMap<>();
+ private NestedCategory lastOpenCategory;
+ private void setupNavigation() {
+ categoryMap.clear();
+ for (MPanel childComponent : navigation.getChildComponents()) {
+ navigation.remove(childComponent);
+ }
+ NestedCategory root = new NestedCategory("ROOT");
+ Set<String> categoryAllowed = new HashSet<>();
+ String search = this.search.getText().trim().toLowerCase();
+ for (AbstractFeature abstractFeature : FeatureRegistry.getFeatureList()) {
+ if (search.isEmpty()) {
+ categoryAllowed.add("ROOT."+abstractFeature.getCategory()+".");
+ } else if (abstractFeature.getName().toLowerCase().contains(search)) {
+ categoryAllowed.add("ROOT."+abstractFeature.getCategory()+".");
+ } else if (abstractFeature.getDescription().toLowerCase().contains(search)) {
+ categoryAllowed.add("ROOT."+abstractFeature.getCategory()+".");
+ }
+ }
+ for (AbstractFeature abstractFeature : FeatureRegistry.getFeatureList()) {
+ String category = abstractFeature.getCategory();
+ boolean test =false;
+ for (String s : categoryAllowed) {
+ if (s.startsWith("ROOT."+category+".")) {
+ test = true;
+ break;
+ }
+ }
+ if (!test) continue;
+
+ NestedCategory currentRoot = root;
+ for (String s : category.split("\\.")) {
+ NestedCategory finalCurrentRoot = currentRoot;
+ if (currentRoot.children().containsKey(s))
+ currentRoot = currentRoot.children().get(s);
+ else {
+ currentRoot.child(currentRoot = new NestedCategory(finalCurrentRoot.categoryFull()+"."+s));
+ }
+ }
+
+ }
+
+ for (NestedCategory value : root.children().values()) {
+ setupNavigationRecursive(value, navigation, 0, 17);
+ }
+ ConfigPanelCreator.map.put("ROOT", () -> new MPanelCategory(root, this));
+ }
+ private void setupNavigationRecursive(NestedCategory nestedCategory, MPanel parent, int depth, int offset) {
+ ConfigPanelCreator.map.put(nestedCategory.categoryFull(), () -> new MPanelCategory(nestedCategory, this));
+
+ if (nestedCategory.children().size() == 0) {
+ MCategoryElement current = new MCategoryElement(nestedCategory.categoryFull(),() -> {
+ setCurrentPageAndPushHistory(nestedCategory.categoryFull());
+ lastOpenCategory = nestedCategory;
+ }, 13 * depth + 17, offset, this);
+ parent.add(current);
+ categoryMap.put(nestedCategory, current);
+ } else {
+ MCategoryElement current = new MCategoryElement(nestedCategory.categoryFull(),() -> {
+ setCurrentPageAndPushHistory(nestedCategory.categoryFull());
+ lastOpenCategory = nestedCategory;
+ }, 3,offset, this);
+ MCollapsable mCollapsable = new MCollapsable(current, this::rePlaceElements);
+ mCollapsable.setLeftPad(offset-13);
+ mCollapsable.getLowerElements().setDrawLine(false);
+ mCollapsable.getLowerElements().setGap(0);
+ mCollapsable.setLeftPadElements(0);
+ parent.add(mCollapsable);
+ categoryMap.put(nestedCategory, mCollapsable);
+
+ for (NestedCategory value : nestedCategory.children().values()) {
+ setupNavigationRecursive(value, mCollapsable, depth+1, offset+13);
+ }
+ }
+ }
+
+
+ public void setCurrentPageAndPushHistory(String currentPage) {
+ if (!this.currentPage.equals(currentPage))
+ history.push(this.currentPage);
+ lastOpenCategory = null;
+ this.currentPage = currentPage;
+ setupPage();
+ }
+ public void goBack() {
+ if (history.size() == 0) return;
+ this.currentPage = history.pop();
+ setupPage();
+ }
+
+ private void setupPage() {
+ contentScroll.getContentArea().getChildComponents().forEach(contentScroll.getContentArea()::remove);
+ if (!pages.containsKey(currentPage)) {
+ MPanel page = pageGenerator.apply(currentPage);
+ if (page == null) page = new MNotFound();
+ pages.put(currentPage, page);
+ }
+ contentScroll.getContentArea().add(pages.get(currentPage));
+ rePlaceElements();
+ }
+
+ public void invalidatePage(String page) {
+ pages.remove(page);
+ if (page.equals(currentPage))
+ setupPage();
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ Dimension effectiveDim = getEffectiveDimension();
+ Gui.drawRect(0,0, (int) (effectiveDim.width), (int) (effectiveDim.height), RenderUtils.blendAlpha(0x141414, 0.00f));
+ Gui.drawRect(0,0, (int) (effectiveDim.width), 25, RenderUtils.blendAlpha(0x0, 0.20f));
+// Gui.drawRect(navigationScroll.getBounds().x + navigationScroll.getBounds().width - 10, 25, navigationScroll.getBounds().x + navigationScroll.getBounds().width , 50, RenderUtils.blendAlpha(0xFF141414, 0.04f));
+ Gui.drawRect(0, 25,navigationScroll.getBounds().x + navigationScroll.getBounds().width , 50, RenderUtils.blendAlpha(0xFF141414, 0.08f));
+
+
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+
+ if(AuthManager.getInstance().getToken() == null) {
+ fr.drawString("ERROR CONNECTING TO DG, YOUR COSMETICS ARE NOT VISIBLE",(effectiveDim.width - fr.getStringWidth("ERROR CONNECTING TO DG, YOUR COSMETICS ARE NOT VISIBLE"))/2, (10 - fr.FONT_HEIGHT)/2, 0xFFFF0000);
+ }
+
+ fr.drawString("DungeonsGuide By syeyoung", (effectiveDim.width - fr.getStringWidth("DungeonsGuide By syeyoung"))/2, (25 - fr.FONT_HEIGHT)/2, 0xFF02EE67);
+ }
+
+ @Override
+ public void render0(double parentScale, Point parentPoint, Rectangle parentClip, int absMousex0, int absMousey0, int relMousex0, int relMousey0, float partialTicks) {
+ super.render0(parentScale, parentPoint, parentClip, absMousex0, absMousey0, relMousex0, relMousey0, partialTicks);
+ Dimension effectiveDim = getEffectiveDimension();
+ Gui.drawRect(0,24, (int) (Double.min(1, (System.currentTimeMillis() - lastPageSet)/1000.0) * effectiveDim.width), 25, 0xFF02EE67);
+ }
+
+ @Override
+ public void setBounds(Rectangle bounds) {
+ super.setBounds(bounds);
+ rePlaceElements();
+ }
+
+ @Override
+ public void setScale(double scale) {
+ super.setScale(scale);
+ rePlaceElements();
+ }
+
+ private void rePlaceElements() {
+ Dimension effectiveDim = getEffectiveDimension();
+
+ navigation.setBounds(new Rectangle(new Point(0,1), new Dimension(Math.max(100, Math.max(navigation.getPreferredSize().width, navigationScroll.getBounds().width-10)), navigation.getPreferredSize().height)));
+ navigation.realignChildren();
+
+ navigationScroll.evalulateContentArea();
+ Rectangle navBound;
+ navigationScroll.setBounds(navBound = new Rectangle(0,50, navigation.getBounds().width+10, effectiveDim.height-50));
+ contentScroll.setBounds(new Rectangle(navBound.x + navBound.width, 25, effectiveDim.width - navBound.x - navBound.width, effectiveDim.height-25));
+
+ search.setBounds(new Rectangle(5,30,navBound.x + navBound.width - 10,15));
+
+ guiRelocate.setBounds(new Rectangle(5,5,100,15));
+ github.setBounds(new Rectangle(effectiveDim.width - 80,5,75,15));
+ discord.setBounds(new Rectangle(effectiveDim.width - 160,5,75,15));
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/GuiGuiLocationConfig.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/GuiGuiLocationConfig.java
new file mode 100755
index 00000000..0b4193da
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/GuiGuiLocationConfig.java
@@ -0,0 +1,166 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig.location;
+
+import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature;
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.mod.features.GuiFeature;
+import kr.syeyoung.dungeonsguide.mod.gui.MGui;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import lombok.Getter;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.Vec3;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.List;
+
+public class GuiGuiLocationConfig extends MGui {
+
+ @Getter
+ private final GuiScreen before;
+
+ @Getter
+ private TreeMap<Integer, List<Marker>> markerTreeMapByX = new TreeMap<>();
+ @Getter
+ private TreeMap<Integer, List<Marker>> markerTreeMapByY = new TreeMap<>();
+ @Getter
+ private Set<Marker> markerSet = new HashSet<>();
+
+
+ Marker[] markers = new Marker[4];
+
+
+ public GuiGuiLocationConfig(final GuiScreen before, AbstractFeature featureWhitelist) {
+ this.before = before;
+ for (AbstractFeature feature : FeatureRegistry.getFeatureList()) {
+ if (feature instanceof GuiFeature && feature.isEnabled()) {
+ getMainPanel().add(new PanelDelegate((GuiFeature) feature, featureWhitelist == null || feature == featureWhitelist, this));
+ }
+ }
+
+ getMainPanel().setBackgroundColor(new Color(0,0,0, 100));
+ }
+
+ public static final Vec3[] facing = new Vec3[] {
+ new Vec3(0, 0.5, 2),
+ new Vec3(0.5, 0, 1),
+ new Vec3(0.5, 1, 3),
+ new Vec3(1, 0.5, 4),
+ };
+
+ public void removeAndAddMarker(Marker prev, Marker newM) {
+ if (prev != null) {
+ markerTreeMapByX.computeIfPresent(prev.getX(),(k,v) -> {
+ v.remove(prev);
+ if (v.isEmpty()) return null;
+ else return v;
+ });
+ markerTreeMapByY.computeIfPresent(prev.getY(),(k,v) -> {
+ v.remove(prev);
+ if (v.isEmpty()) return null;
+ else return v;
+ });
+ markerSet.remove(prev);
+ }
+ if (newM != null) {
+ markerTreeMapByX.compute(newM.getX(), (k,v) -> {
+ if (v == null) {
+ return new ArrayList<>(Arrays.asList(newM));
+ } else {
+ v.add(newM);
+ return v;
+ }
+ });
+ markerTreeMapByY.compute(newM.getY(), (k,v) -> {
+ if (v == null) {
+ return new ArrayList<>(Arrays.asList(newM));
+ } else {
+ v.add(newM);
+ return v;
+ }
+ });
+ markerSet.add(newM);
+ }
+ }
+
+ public void setupMarkers() {
+ for (int i1 = 0; i1 < markers.length; i1++) {
+ Marker orig = markers[i1];
+ Vec3 pt = facing[i1];
+ markers[i1] = new Marker((int) (pt.xCoord * getMainPanel().getBounds().width), (int) (pt.yCoord * getMainPanel().getBounds().height), (int) pt.zCoord, this);
+
+ removeAndAddMarker(orig, markers[i1]);
+ }
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ GlStateManager.pushMatrix();
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ GlStateManager.translate(scaledResolution.getScaledWidth()/2, scaledResolution.getScaledHeight()/2, 0);
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ GlStateManager.enableBlend();
+ GlStateManager.enableAlpha();
+ GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
+ GlStateManager.color(1, 1, 1, 1);
+ fr.drawString("Right Click On Elements to Open Popup Menu",
+ -fr.getStringWidth("Right Click On Elements to Open Popup Menu")/2
+ ,-fr.FONT_HEIGHT/2, -1);
+ GlStateManager.popMatrix();
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ }
+
+ @Override
+ public void keyTyped(char typedChar, int keyCode) throws IOException {
+ try {
+ getMainPanel().keyPressed0(typedChar, keyCode);
+
+ if (keyCode == 1) {
+ Minecraft.getMinecraft().displayGuiScreen(before);
+ }
+ } catch (Throwable e) {
+ if (!e.getMessage().contains("hack to stop"))
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void initGui() {
+ super.initGui();
+ getMainPanel().setBounds(new Rectangle(0,0,Minecraft.getMinecraft().displayWidth,Minecraft.getMinecraft().displayHeight));
+ markerTreeMapByX.clear();
+ markerTreeMapByY.clear();
+ markerSet.clear();
+ setupMarkers();
+ for (MPanel childComponent : getMainPanel().getChildComponents()) {
+ if (childComponent instanceof PanelDelegate) {
+ ((PanelDelegate) childComponent).rebuildMarker();
+ }
+ }
+
+ }
+
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/Marker.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/Marker.java
new file mode 100644
index 00000000..10683425
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/Marker.java
@@ -0,0 +1,45 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig.location;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.ToString;
+
+@Getter
+@ToString
+@AllArgsConstructor
+public class Marker {
+ private final int x;
+ private final int y;
+ /**
+ * 0xABCDEFGH
+ * A: ?
+ * B: ?
+ * C: ?
+ * D: ?
+ * EF: 0~3 (TC 0x00 CL 0x01 BC 0x10 CR 0x11)
+ */
+ private final int type;
+ private final Object parent;
+
+ public int distanceSQ(Marker m2) {
+ return (m2.x - x)*(m2.x - x) + (m2.y - y)*(m2.y - y);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/PanelDelegate.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/PanelDelegate.java
new file mode 100644
index 00000000..3c03fb73
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location/PanelDelegate.java
@@ -0,0 +1,403 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.guiconfig.location;
+
+import kr.syeyoung.dungeonsguide.mod.config.types.GUIRectangle;
+import kr.syeyoung.dungeonsguide.mod.features.GuiFeature;
+import kr.syeyoung.dungeonsguide.mod.gui.MPanel;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MPopupMenu;
+import kr.syeyoung.dungeonsguide.mod.gui.elements.MTooltip;
+import kr.syeyoung.dungeonsguide.mod.utils.cursor.EnumCursor;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.WorldRenderer;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.Tuple;
+import net.minecraft.util.Vec3;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+public class PanelDelegate extends MPanel {
+ private final GuiFeature guiFeature;
+ private boolean draggable = false;
+ private GuiGuiLocationConfig guiGuiLocationConfig;
+
+ private Set<Marker> markerSet = new HashSet<>();
+ public PanelDelegate(GuiFeature guiFeature, boolean draggable, GuiGuiLocationConfig guiGuiLocationConfig) {
+ this.guiFeature = guiFeature;
+ this.draggable = draggable;
+ this.guiGuiLocationConfig = guiGuiLocationConfig;
+ }
+
+ public void rebuildMarker() {
+ internallyThinking = guiFeature.getFeatureRect().getRectangleNoScale();
+ applyConstraint();
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ Rectangle rectangle = guiFeature.getFeatureRect().getRectangle();
+ return new Rectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMouseX, int relMouseY, float partialTicks, Rectangle scissor) {
+ if (!guiFeature.isEnabled()) return;
+
+ GlStateManager.pushMatrix();
+ guiFeature.drawDemo(partialTicks);
+ GlStateManager.popMatrix();
+ if (!draggable) return;
+ Gui.drawRect(0,0, 4, 4, 0xFFBBBBBB);
+ Gui.drawRect(0, getBounds().height - 4, 4, getBounds().height, 0xFFBBBBBB);
+ Gui.drawRect(getBounds().width - 4,0, getBounds().width, 4, 0xFFBBBBBB);
+ Gui.drawRect(getBounds().width - 4,getBounds().height - 4, getBounds().width, getBounds().height, 0xFFBBBBBB);
+ if (lastAbsClip.contains(absMousex, absMousey)) {
+ if (relMouseX < 4 && relMouseY < 4) {
+ Gui.drawRect(0,0, 4, 4, 0x55FFFFFF);
+ } else if (relMouseX < 4 && relMouseY > getBounds().height - 4) {
+ Gui.drawRect(0, getBounds().height - 4, 4, getBounds().height, 0x55FFFFFF);
+ } else if (relMouseX > getBounds().width - 4 && relMouseY > getBounds().height - 4) {
+ Gui.drawRect(getBounds().width - 4,getBounds().height - 4, getBounds().width, getBounds().height, 0x55FFFFFF);
+ } else if (relMouseX > getBounds().width - 4 && relMouseY < 4) {
+ Gui.drawRect(getBounds().width - 4,0, getBounds().width, 4, 0x55FFFFFF);
+ } else if (selectedPart == -2){
+ Gui.drawRect(0,0, getBounds().width, getBounds().height, 0x55FFFFFF);
+ }
+ }
+ GlStateManager.enableBlend();
+ }
+
+ @Override
+ public void render0(double scale, Point parentPoint, Rectangle parentClip, int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks) {
+ GlStateManager.pushMatrix();
+ super.render0(scale, parentPoint, parentClip, absMousex, absMousey, relMousex0, relMousey0, partialTicks);
+ GlStateManager.popMatrix();
+
+ if (snapped != null && selectedPart != -2) {
+ Tessellator tessellator = Tessellator.getInstance();
+ GlStateManager.disableTexture2D();
+ WorldRenderer worldRenderer = tessellator.getWorldRenderer();
+ worldRenderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
+ GL11.glLineWidth(1);
+ for (Tuple<Marker[], EnumFacing.Axis> markerAxisTuple : snapped) {
+ if (markerAxisTuple.getSecond() == EnumFacing.Axis.X) {
+ worldRenderer.pos(markerAxisTuple.getFirst()[0].getX(), 0, 0).color(0,255,0,255).endVertex();
+ worldRenderer.pos(markerAxisTuple.getFirst()[0].getX(), Minecraft.getMinecraft().displayHeight, 0).color(0,255,0,255).endVertex();
+ } else {
+ worldRenderer.pos(0, markerAxisTuple.getFirst()[0].getY(), 0).color(0,255,0,255).endVertex();
+ worldRenderer.pos(Minecraft.getMinecraft().displayWidth, markerAxisTuple.getFirst()[0].getY(), 0).color(0,255,0,255).endVertex();
+ }
+ }
+ tessellator.draw();
+ for (Marker marker : guiGuiLocationConfig.getMarkerSet()) {
+ Gui.drawRect(marker.getX(),marker.getY(), marker.getX()+1, marker.getY()+1, 0xFFFF0000);
+ }
+ }
+ }
+
+ private int selectedPart = -2;
+
+ private int lastX = 0;
+ private int lastY = 0;
+
+ private Rectangle internallyThinking;
+ private Rectangle constraintApplied;
+
+ private Set<Tuple<Marker[], EnumFacing.Axis>> snapped = new HashSet<>();
+
+ public void applyConstraint() {
+ constraintApplied = internallyThinking.getBounds();
+
+ // SNAP Moving Point.
+ snapped.clear();
+ int scailingThreshold = 5;
+ if (selectedPart == 0){
+ Point snapPt = new Point(constraintApplied.x +constraintApplied.width, constraintApplied.y + constraintApplied.height);
+ Optional<Marker> snapX, snapY;
+ SortedMap<Integer, List<Marker>> markerSortedMap = guiGuiLocationConfig.getMarkerTreeMapByX().subMap(snapPt.x-scailingThreshold, snapPt.x +scailingThreshold);
+ snapX = markerSortedMap.values().stream()
+ .filter(Objects::nonNull)
+ .flatMap(Collection::stream)
+ .filter(a -> a.getParent() != this)
+ .min(Comparator.comparingInt(a -> (int) snapPt.distanceSq(a.getX(), a.getY())));
+ markerSortedMap = guiGuiLocationConfig.getMarkerTreeMapByY().subMap(snapPt.y-scailingThreshold, snapPt.y +scailingThreshold);
+ snapY = markerSortedMap.values().stream()
+ .filter(Objects::nonNull)
+ .flatMap(Collection::stream)
+ .filter(a -> a.getParent() != this)
+ .min(Comparator.comparingInt(a -> (int) snapPt.distanceSq(a.getX(), a.getY())));
+ snapX.ifPresent(a -> {
+ snapPt.x = a.getX();
+ });
+ snapY.ifPresent(a -> {
+ snapPt.y = a.getY();
+ });
+
+ constraintApplied = new Rectangle(constraintApplied.x, constraintApplied.y, snapPt.x - constraintApplied.x, snapPt.y - constraintApplied.y);
+
+
+
+ int minWidth;
+ int minHeight;
+ if (guiFeature.isKeepRatio()) {
+ if (guiFeature.getDefaultRatio() >= 1) {
+ minHeight = constraintApplied.height < 0 ? -8 : 8;
+ minWidth = (int) (guiFeature.getDefaultRatio() * minHeight);
+ } else {
+ minWidth = constraintApplied.width < 0 ? -8 : 8;
+ minHeight = (int) (minWidth / guiFeature.getDefaultRatio());
+ }
+ } else {
+ minWidth = constraintApplied.width < 0 ? -8 : 8;
+ minHeight = constraintApplied.height < 0 ? -8 : 8;
+ }
+
+
+ constraintApplied.width = Math.abs(constraintApplied.width) > Math.abs(minWidth) ? constraintApplied.width :
+ Math.abs(internallyThinking.width) > Math.abs(minWidth) ? internallyThinking.width : minWidth;
+ constraintApplied.height = Math.abs(constraintApplied.height) > Math.abs(minHeight) ? constraintApplied.height :
+ Math.abs(internallyThinking.height) > Math.abs(minHeight) ? internallyThinking.height : minHeight;
+
+ if (guiFeature.isKeepRatio()) {
+ double ratio = guiFeature.getDefaultRatio();
+
+ int heightWhenWidthFix = (int) Math.abs(constraintApplied.width / ratio);
+ int widthWhenHeightFix = (int) Math.abs(ratio * constraintApplied.height);
+ if (Math.abs(heightWhenWidthFix) <= Math.abs(constraintApplied.height)) {
+ constraintApplied.height = constraintApplied.height < 0 ? -heightWhenWidthFix : heightWhenWidthFix;
+ } else if (Math.abs(widthWhenHeightFix) <= Math.abs(constraintApplied.width)) {
+ constraintApplied.width =constraintApplied.width < 0 ? - widthWhenHeightFix : widthWhenHeightFix;
+ }
+ }
+
+
+ snapX.ifPresent(a -> {
+ if (snapPt.x - constraintApplied.x == constraintApplied.width) {
+ Marker m = new Marker((int) (GuiGuiLocationConfig.facing[3].xCoord * constraintApplied.width) + constraintApplied.x, (int) (GuiGuiLocationConfig.facing[3].yCoord * constraintApplied.height) + constraintApplied.y, (int) GuiGuiLocationConfig.facing[3].zCoord, this);
+ snapped.add(new Tuple<>(new Marker[]{a, m}, EnumFacing.Axis.X));
+ }
+ });
+ snapY.ifPresent(a -> {
+ if (snapPt.y - constraintApplied.y == constraintApplied.height) {
+ Marker m = new Marker((int) (GuiGuiLocationConfig.facing[2].xCoord * constraintApplied.width) + constraintApplied.x, (int) (GuiGuiLocationConfig.facing[2].yCoord * constraintApplied.height) + constraintApplied.y, (int) GuiGuiLocationConfig.facing[2].zCoord, this);
+ snapped.add(new Tuple<>(new Marker[]{a, m}, EnumFacing.Axis.Y));
+ }
+ });
+
+ if (constraintApplied.height < 0) {
+ constraintApplied.height = -constraintApplied.height;
+ constraintApplied.y -= constraintApplied.height;
+ }
+
+ if (constraintApplied.width < 0) {
+ constraintApplied.width = -constraintApplied.width;
+ constraintApplied.x -= constraintApplied.width;
+ }
+ } else if (selectedPart == -1) {
+ for (int i : Arrays.asList(0,3,1,2)) {
+ Vec3 pt = GuiGuiLocationConfig.facing[i];
+ Marker m = new Marker((int) (pt.xCoord * constraintApplied.width) + constraintApplied.x, (int) (pt.yCoord * constraintApplied.height) + constraintApplied.y, (int) pt.zCoord, this);
+ Optional<Marker> result = guiGuiLocationConfig.getMarkerTreeMapByX().subMap(m.getX()-scailingThreshold, m.getX() +scailingThreshold).values().stream()
+ .filter(Objects::nonNull)
+ .flatMap(Collection::stream)
+ .filter(a -> a.getParent() != this)
+ .filter(a -> Math.abs(a.getX() - m.getX()) < scailingThreshold)
+ .filter(a -> ((a.getX() - pt.xCoord * constraintApplied.width) >= 0
+ && (a.getX() - pt.xCoord * constraintApplied.width + constraintApplied.width) <= Minecraft.getMinecraft().displayWidth))
+ .min(Comparator.comparingInt(a -> a.distanceSQ(m)));
+ if (result.isPresent()) {
+ int x = result.get().getX();
+ constraintApplied.x = (int) (x - pt.xCoord * constraintApplied.width);
+
+ snapped.add(new Tuple<>(new Marker[] {result.get(), m}, EnumFacing.Axis.X));
+ break;
+ }
+ }
+ for (int i : Arrays.asList(1,2,0,3)) {
+ Vec3 pt = GuiGuiLocationConfig.facing[i];
+ Marker m = new Marker((int) (pt.xCoord * constraintApplied.width) + constraintApplied.x, (int) (pt.yCoord * constraintApplied.height) + constraintApplied.y, (int) pt.zCoord, this);
+ Optional<Marker> result = guiGuiLocationConfig.getMarkerTreeMapByY().subMap(m.getY()-scailingThreshold, m.getY() +scailingThreshold).values().stream()
+ .filter(Objects::nonNull)
+ .flatMap(Collection::stream)
+ .filter(a -> a.getParent() != this)
+ .filter(a -> Math.abs(a.getY() - m.getY()) < scailingThreshold)
+ .filter(a -> ((a.getY() - pt.yCoord * constraintApplied.height) >= 0
+ && (a.getY() - pt.yCoord * constraintApplied.height+ constraintApplied.height) <= Minecraft.getMinecraft().displayHeight))
+ .min(Comparator.comparingInt(a -> a.distanceSQ(m)));
+ if (result.isPresent()) {
+ int y = result.get().getY();
+ constraintApplied.y = (int) (y - pt.yCoord * constraintApplied.height);
+ snapped.add(new Tuple<>(new Marker[] {result.get(), m}, EnumFacing.Axis.Y));
+ break;
+ }
+ }
+ }
+
+ if (constraintApplied.x < 0) constraintApplied.x = 0;
+ if (constraintApplied.y < 0) constraintApplied.y = 0;
+ if (constraintApplied.x + constraintApplied.width + 1 >=Minecraft.getMinecraft().displayWidth) constraintApplied.x = Minecraft.getMinecraft().displayWidth - constraintApplied.width - 1;
+ if (constraintApplied.y + constraintApplied.height + 1>= Minecraft.getMinecraft().displayHeight) constraintApplied.y = Minecraft.getMinecraft().displayHeight - constraintApplied.height - 1;
+
+
+ setupMarkers();
+ }
+
+ Marker[] markers = new Marker[4];
+ public void setupMarkers() {
+ for (int i1 = 0; i1 < markers.length; i1++) {
+ Marker orig = markers[i1];
+
+ Vec3 pt = GuiGuiLocationConfig.facing[i1];
+ markers[i1] = new Marker((int) (pt.xCoord * constraintApplied.width) + constraintApplied.x, (int) (pt.yCoord * constraintApplied.height) + constraintApplied.y, (int) pt.zCoord, this);
+
+ guiGuiLocationConfig.removeAndAddMarker(orig, markers[i1]);
+ }
+ }
+
+ MTooltip mTooltip;
+
+ @Override
+ public void mouseClicked(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int mouseButton) {
+ if (!draggable) return;
+ if (!guiFeature.isEnabled()) return;
+ if (getTooltipsOpen() > 0) return;
+ if (!lastAbsClip.contains(absMouseX, absMouseY)) return;
+ if (mouseButton == 0) {
+ internallyThinking = guiFeature.getFeatureRect().getRectangleNoScale();
+ if (relMouseX < 4 && relMouseY < 4) { // TL
+ selectedPart = 0;
+ internallyThinking.y += internallyThinking.height;
+ internallyThinking.height = -internallyThinking.height;
+ internallyThinking.x += internallyThinking.width;
+ internallyThinking.width = -internallyThinking.width;
+ } else if (relMouseX < 4 && relMouseY > getBounds().height - 4) { // BL
+ selectedPart = 0;
+ internallyThinking.x += internallyThinking.width;
+ internallyThinking.width = -internallyThinking.width;
+ } else if (relMouseX > getBounds().width - 4 && relMouseY > getBounds().height - 4) { // BR
+ selectedPart = 0;
+ } else if (relMouseX > getBounds().width - 4 && relMouseY < 4) { // TR
+ selectedPart = 0;
+ internallyThinking.y += internallyThinking.height;
+ internallyThinking.height = -internallyThinking.height;
+ } else {
+ selectedPart = -1;
+ }
+ lastX = absMouseX;
+ lastY = absMouseY;
+ applyConstraint();
+
+ } else if (getTooltipsOpen() == 0){
+ if (mTooltip != null) mTooltip.close();
+ mTooltip = new MPopupMenu(absMouseX, absMouseY, guiFeature.getTooltipForEditor(guiGuiLocationConfig));
+ mTooltip.setScale(2.0f);
+ mTooltip.open(this);
+ }
+ throw new IllegalArgumentException("bruh, a hack to stop event progress");
+ }
+
+ @Override
+ public void mouseReleased(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int state) {
+ if (!draggable) return;
+ if (!guiFeature.isEnabled()) return;
+ if (selectedPart >= -1) {
+ guiFeature.setFeatureRect(new GUIRectangle(constraintApplied));
+ }
+
+ selectedPart = -2;
+ }
+
+ @Override
+ public void mouseClickMove(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int clickedMouseButton, long timeSinceLastClick) {
+ if (!draggable) return;
+ if (!guiFeature.isEnabled()) return;
+ int dx = (absMouseX - lastX);
+ int dy = (absMouseY - lastY);
+ if (selectedPart >= 0) {
+ Rectangle rectangle = internallyThinking;
+
+ int prevWidth = rectangle.width;
+ int prevHeight= rectangle.height;
+
+ rectangle.width = prevWidth + dx;
+ rectangle.height = prevHeight + dy;
+
+ if (rectangle.height * prevHeight <= 0 && prevHeight != rectangle.height) {
+ rectangle.height += prevHeight < 0 ? 4 : -4;
+ }
+ if (rectangle.width * prevWidth <= 0 && prevWidth != rectangle.width) {
+ rectangle.width += prevWidth < 0 ? 4 : -4;
+ }
+
+
+ applyConstraint();
+ guiFeature.setFeatureRect(new GUIRectangle(constraintApplied));
+ lastX = absMouseX;
+ lastY = absMouseY;
+ throw new IllegalArgumentException("bruh, a hack to stop event progress");
+ } else if (selectedPart == -1){
+ Rectangle rectangle = internallyThinking;
+ rectangle.translate(dx, dy);
+ applyConstraint();
+ guiFeature.setFeatureRect(new GUIRectangle(constraintApplied));
+ lastX = absMouseX;
+ lastY = absMouseY;
+ }
+ }
+
+ @Override
+ public void mouseMoved(int absMouseX, int absMouseY, int relMouseX, int relMouseY) {
+ if (!draggable) return;
+ if (!guiFeature.isEnabled()) return;
+ if (getTooltipsOpen() > 0) return;
+
+ if (selectedPart == -1) {
+ setCursor(EnumCursor.CLOSED_HAND);
+ } else if (selectedPart >= 0) {
+ if (internallyThinking.width < 0 && internallyThinking.height < 0) {
+ setCursor(EnumCursor.RESIZE_TL);
+ } else if (internallyThinking.width < 0 && internallyThinking.height >= 0) {
+ setCursor(EnumCursor.RESIZE_DL);
+ } else if (internallyThinking.width >= 0 && internallyThinking.height >= 0) {
+ setCursor(EnumCursor.RESIZE_DR);
+ } else if (internallyThinking.width >= 0 && internallyThinking.height < 0) {
+ setCursor(EnumCursor.RESIZE_TR);
+ }
+ } else if (lastAbsClip.contains(absMouseX, absMouseY)) {
+ if (relMouseX < 4 && relMouseY < 4) {
+ setCursor(EnumCursor.RESIZE_TL);
+ } else if (relMouseX < 4 && relMouseY > getBounds().height - 4) {
+ setCursor(EnumCursor.RESIZE_DL);
+ } else if (relMouseX > getBounds().width - 4 && relMouseY > getBounds().height - 4) {
+ setCursor(EnumCursor.RESIZE_DR);
+ } else if (relMouseX > getBounds().width - 4 && relMouseY < 4) {
+ setCursor(EnumCursor.RESIZE_TR);
+ } else {
+ setCursor(EnumCursor.OPEN_HAND);
+ }
+ }
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/AColor.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/AColor.java
new file mode 100644
index 00000000..3b5f3d36
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/AColor.java
@@ -0,0 +1,63 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.awt.*;
+
+@Getter
+@Setter
+public class AColor extends Color {
+ private boolean chroma;
+ private float chromaSpeed;
+
+ public AColor(int r, int g, int b, int a) {
+ super(r, g, b, a);
+ }
+
+ public AColor(int rgba, boolean hasalpha) {
+ super(rgba, hasalpha);
+ }
+
+ public AColor(AColor clone) {
+ super(clone.getRGB(), true);
+ chroma = clone.isChroma();
+ chromaSpeed = clone.getChromaSpeed();
+ }
+
+ public AColor multiplyAlpha(double multiplier) {
+ AColor aColor = new AColor(getRed(), getGreen(), getBlue(), (int) (getAlpha() * multiplier));
+ aColor.chroma = this.chroma;
+ aColor.chromaSpeed = this.chromaSpeed;
+ return aColor;
+ }
+
+ @Override
+ public String toString() {
+ return "AColor{" +
+ ", r="+getRed()+
+ ", g="+getGreen()+
+ ", b="+getBlue()+
+ ", a="+getAlpha()+
+ ", chromaSpeed=" + chromaSpeed +
+ '}';
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/GUIRectangle.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/GUIRectangle.java
new file mode 100644
index 00000000..cf43fbfb
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/GUIRectangle.java
@@ -0,0 +1,81 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import net.minecraft.client.Minecraft;
+
+import java.awt.*;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class GUIRectangle {
+ public GUIRectangle(Rectangle rectangle) {
+ if (rectangle.x < Minecraft.getMinecraft().displayWidth / 2) {
+ this.x = rectangle.x;
+ this.width = rectangle.width;
+ } else {
+ this.x = rectangle.x + rectangle.width - Minecraft.getMinecraft().displayWidth;
+ this.width = -rectangle.width;
+ }
+
+ if (rectangle.y < Minecraft.getMinecraft().displayHeight / 2) {
+ this.y = rectangle.y;
+ this.height = rectangle.height;
+ } else {
+ this.y = rectangle.y +rectangle.height - Minecraft.getMinecraft().displayHeight;
+ this.height = -rectangle.height;
+ }
+ }
+
+ private int x;
+ private int y;
+ private int width;
+ private int height;
+
+ public Rectangle getRectangle() {
+ return getRectangleNoScale();
+ }
+// public Rectangle getRectangle(ScaledResolution scaledResolution) {
+// double realX = (int) (x < 0 ? scaledResolution.getScaledWidth() + x : x);
+// double realY = (int) (y < 0 ? scaledResolution.getScaledHeight() + y : y);
+//
+// return new Rectangle((int)Math.min(realX + width, realX), (int)Math.min(realY + height, realY),
+// (int)Math.abs(width), (int)Math.abs(height));
+// }
+ public Rectangle getRectangleNoScale() {
+ int x = this.x, y = this.y;
+ if (Math.abs(x) > Minecraft.getMinecraft().displayWidth / 2) {
+ x = x < 0 ? -Minecraft.getMinecraft().displayWidth/2 : Minecraft.getMinecraft().displayWidth/2;
+ }
+ if (Math.abs(y) > Minecraft.getMinecraft().displayHeight / 2) {
+ y = y < 0 ? -Minecraft.getMinecraft().displayHeight/2 : Minecraft.getMinecraft().displayHeight/2;
+ }
+
+
+ double realX = (int) (x < 0 ? Minecraft.getMinecraft().displayWidth + x : x);
+ double realY = (int) (y < 0 ? Minecraft.getMinecraft().displayHeight + y : y);
+
+ return new Rectangle((int)Math.min(realX + width, realX), (int)Math.min(realY + height, realY),
+ (int)Math.abs(width), (int)Math.abs(height));
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCAColor.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCAColor.java
new file mode 100644
index 00000000..dfc2d461
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCAColor.java
@@ -0,0 +1,51 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+public class TCAColor implements TypeConverter<AColor> {
+ @Override
+ public String getTypeString() {
+ return "acolor";
+ }
+
+ @Override
+ public AColor deserialize(JsonElement element) {
+ if (element instanceof JsonPrimitive)
+ return new AColor(element.getAsInt(), true);
+
+ JsonObject object = element.getAsJsonObject();
+ AColor color = new AColor(object.get("color").getAsInt(), true);
+ color.setChroma(object.get("chroma").getAsBoolean());
+ color.setChromaSpeed(object.get("chromaSpeed").getAsFloat());
+ return color;
+ }
+
+ @Override
+ public JsonElement serialize(AColor element) {
+ JsonObject object = new JsonObject();
+ object.addProperty("color", element.getRGB());
+ object.addProperty("chroma", element.isChroma());
+ object.addProperty("chromaSpeed", element.getChromaSpeed());
+ return object;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCBoolean.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCBoolean.java
new file mode 100644
index 00000000..f973f495
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCBoolean.java
@@ -0,0 +1,39 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class TCBoolean implements TypeConverter<Boolean> {
+ @Override
+ public String getTypeString() {
+ return "boolean";
+ }
+
+ @Override
+ public Boolean deserialize(JsonElement element) {
+ return element.getAsBoolean();
+ }
+
+ @Override
+ public JsonElement serialize(Boolean element) {
+ return new JsonPrimitive(element);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCColor.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCColor.java
new file mode 100644
index 00000000..2544a4f3
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCColor.java
@@ -0,0 +1,41 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+import java.awt.*;
+
+public class TCColor implements TypeConverter<Color> {
+ @Override
+ public String getTypeString() {
+ return "color";
+ }
+
+ @Override
+ public Color deserialize(JsonElement element) {
+ return new Color(element.getAsInt());
+ }
+
+ @Override
+ public JsonElement serialize(Color element) {
+ return new JsonPrimitive(element.getRGB());
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCFloat.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCFloat.java
new file mode 100644
index 00000000..2f2aa72f
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCFloat.java
@@ -0,0 +1,39 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class TCFloat implements TypeConverter<Float> {
+ @Override
+ public String getTypeString() {
+ return "float";
+ }
+
+ @Override
+ public Float deserialize(JsonElement element) {
+ return element.getAsFloat();
+ }
+
+ @Override
+ public JsonElement serialize(Float element) {
+ return new JsonPrimitive(element);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCGUIRectangle.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCGUIRectangle.java
new file mode 100644
index 00000000..8d34b013
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCGUIRectangle.java
@@ -0,0 +1,50 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+public class TCGUIRectangle implements TypeConverter<GUIRectangle> {
+ @Override
+ public String getTypeString() {
+ return "guirect";
+ }
+
+ @Override
+ public GUIRectangle deserialize(JsonElement element) {
+ if (element == null) return null;
+ GUIRectangle rectangle = new GUIRectangle();
+ rectangle.setX(((JsonObject)element).get("x").getAsInt());
+ rectangle.setY(((JsonObject)element).get("y").getAsInt());
+ rectangle.setWidth(((JsonObject)element).get("width").getAsInt());
+ rectangle.setHeight(((JsonObject)element).get("height").getAsInt());
+ return rectangle;
+ }
+
+ @Override
+ public JsonElement serialize(GUIRectangle element) {
+ JsonObject object = new JsonObject();
+ object.addProperty("x", element.getX());
+ object.addProperty("y", element.getY());
+ object.addProperty("width", element.getWidth());
+ object.addProperty("height", element.getHeight());
+ return object;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCInteger.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCInteger.java
new file mode 100644
index 00000000..e895345d
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCInteger.java
@@ -0,0 +1,39 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class TCInteger implements TypeConverter<Integer> {
+ @Override
+ public String getTypeString() {
+ return "integer";
+ }
+
+ @Override
+ public Integer deserialize(JsonElement element) {
+ return element.getAsInt();
+ }
+
+ @Override
+ public JsonElement serialize(Integer element) {
+ return new JsonPrimitive(element);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCKeybind.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCKeybind.java
new file mode 100644
index 00000000..5b3bb09b
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCKeybind.java
@@ -0,0 +1,39 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class TCKeybind implements TypeConverter<Integer> {
+ @Override
+ public String getTypeString() {
+ return "keybind";
+ }
+
+ @Override
+ public Integer deserialize(JsonElement element) {
+ return element.getAsInt();
+ }
+
+ @Override
+ public JsonElement serialize(Integer element) {
+ return new JsonPrimitive(element);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCRectangle.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCRectangle.java
new file mode 100644
index 00000000..37736d44
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCRectangle.java
@@ -0,0 +1,51 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+import java.awt.*;
+
+public class TCRectangle implements TypeConverter<Rectangle> {
+ @Override
+ public String getTypeString() {
+ return "rect";
+ }
+
+ @Override
+ public Rectangle deserialize(JsonElement element) {
+ Rectangle rectangle = new Rectangle();
+ rectangle.x = ((JsonObject)element).get("x").getAsInt();
+ rectangle.y = ((JsonObject)element).get("y").getAsInt();
+ rectangle.width = ((JsonObject)element).get("width").getAsInt();
+ rectangle.height = ((JsonObject)element).get("height").getAsInt();
+ return rectangle;
+ }
+
+ @Override
+ public JsonElement serialize(Rectangle element) {
+ JsonObject object = new JsonObject();
+ object.addProperty("x", element.x);
+ object.addProperty("y", element.y);
+ object.addProperty("width", element.width);
+ object.addProperty("height", element.height);
+ return object;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCString.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCString.java
new file mode 100644
index 00000000..b2f9dab4
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCString.java
@@ -0,0 +1,39 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class TCString implements TypeConverter<String> {
+ @Override
+ public String getTypeString() {
+ return "string";
+ }
+
+ @Override
+ public String deserialize(JsonElement element) {
+ return element.getAsString();
+ }
+
+ @Override
+ public JsonElement serialize(String element) {
+ return new JsonPrimitive(element);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCStringList.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCStringList.java
new file mode 100644
index 00000000..90d78d2a
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCStringList.java
@@ -0,0 +1,51 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TCStringList implements TypeConverter<List<String>> {
+ @Override
+ public String getTypeString() {
+ return "stringlist";
+ }
+
+ @Override
+ public List<String> deserialize(JsonElement element) {
+ List<String> strList = new ArrayList<>();
+ for (JsonElement jsonElement : element.getAsJsonArray()) {
+ strList.add(jsonElement.getAsString());
+ }
+ return strList;
+ }
+
+ @Override
+ public JsonElement serialize(List<String> element) {
+ JsonArray jsonElements = new JsonArray();
+ for (String s : element) {
+ jsonElements.add(new JsonPrimitive(s));
+ }
+ return jsonElements;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyle.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyle.java
new file mode 100644
index 00000000..78f03ae0
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyle.java
@@ -0,0 +1,52 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import kr.syeyoung.dungeonsguide.mod.features.text.TextStyle;
+
+public class TCTextStyle implements TypeConverter<TextStyle> {
+ @Override
+ public String getTypeString() {
+ return "textstyle";
+ }
+
+ @Override
+ public TextStyle deserialize(JsonElement element) {
+ TextStyle textStyle = new TextStyle();
+ textStyle.setColor(TypeConverterRegistry.getTypeConverter("acolor", AColor.class).deserialize(element.getAsJsonObject().get("color")));
+ textStyle.setBackground(element.getAsJsonObject().has("background") ? TypeConverterRegistry.getTypeConverter("acolor", AColor.class).deserialize(element.getAsJsonObject().get("background"))
+ : new AColor(0x00777777, true));
+ textStyle.setGroupName(element.getAsJsonObject().get("group").getAsString());
+ if (element.getAsJsonObject().has("shadow"))
+ textStyle.setShadow(element.getAsJsonObject().get("shadow").getAsBoolean());
+ return textStyle;
+ }
+
+ @Override
+ public JsonElement serialize(TextStyle element) {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.add("color", TypeConverterRegistry.getTypeConverter("acolor", AColor.class).serialize(element.getColor()));
+ jsonObject.add("background", TypeConverterRegistry.getTypeConverter("acolor", AColor.class).serialize(element.getBackground()));
+ jsonObject.addProperty("group", element.getGroupName());
+ jsonObject.addProperty("shadow", element.isShadow());
+ return jsonObject;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyleList.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyleList.java
new file mode 100644
index 00000000..50455dd2
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TCTextStyleList.java
@@ -0,0 +1,54 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import kr.syeyoung.dungeonsguide.mod.features.text.TextStyle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TCTextStyleList implements TypeConverter<List<TextStyle>> {
+ @Override
+ public String getTypeString() {
+ return "list_textStyle";
+ }
+
+ @Override
+ public List<TextStyle> deserialize(JsonElement element) {
+ JsonArray arr = element.getAsJsonArray();
+ TypeConverter<TextStyle> conv = TypeConverterRegistry.getTypeConverter("textstyle", TextStyle.class);
+ List<TextStyle> texts = new ArrayList<TextStyle>();
+ for (JsonElement element2:arr) {
+ texts.add(conv.deserialize(element2));
+ }
+ return texts;
+ }
+
+ @Override
+ public JsonElement serialize(List<TextStyle> element) {
+ JsonArray array = new JsonArray();
+ TypeConverter<TextStyle> conv = TypeConverterRegistry.getTypeConverter("textstyle", TextStyle.class);
+ for (TextStyle st:element) {
+ array.add(conv.serialize(st));
+ }
+ return array;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverter.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverter.java
new file mode 100644
index 00000000..eb4c7a27
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverter.java
@@ -0,0 +1,29 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import com.google.gson.JsonElement;
+
+public interface TypeConverter<T> {
+ String getTypeString();
+
+ T deserialize(JsonElement element);
+
+ JsonElement serialize(T element);
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverterRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverterRegistry.java
new file mode 100644
index 00000000..f635d6ad
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/config/types/TypeConverterRegistry.java
@@ -0,0 +1,52 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * 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.config.types;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TypeConverterRegistry {
+ private static final Map<String, TypeConverter> typeConverterMap = new HashMap<String, TypeConverter>();
+
+ public static void register(TypeConverter typeConverter) {
+ typeConverterMap.put(typeConverter.getTypeString(), typeConverter);
+ }
+
+ public static TypeConverter getTypeConverter(String type_string) {
+ return typeConverterMap.get(type_string);
+ }
+ public static <T> TypeConverter<T> getTypeConverter(String type_string, Class<T> t) {
+ return (TypeConverter<T>)typeConverterMap.get(type_string);
+ }
+
+ static {
+ register(new TCBoolean());
+ register(new TCInteger());
+ register(new TCRectangle());
+ register(new TCGUIRectangle());
+ register(new TCString());
+ register(new TCColor());
+ register(new TCFloat());
+ register(new TCAColor());
+ register(new TCTextStyleList());
+ register(new TCTextStyle());
+ register(new TCStringList());
+ register(new TCKeybind());
+ }
+}