failMessages = warpMessages.getWarpFailMessages();
56 | if (failMessages == null || failMessages.isEmpty()) {
57 | throw new IllegalArgumentException("Warp fail message list cannot be empty");
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/menu/Menu.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2024. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu;
24 |
25 | /**
26 | * In-game menus, not serialized
27 | */
28 | public enum Menu {
29 | /** Value used when player is not in a menu or in an unknown or irrelevant menu */
30 | NONE(""),
31 | SKYBLOCK_MENU("SkyBlock Menu"),
32 | FAST_TRAVEL("Fast Travel"),
33 | PORHTAL("Porhtal");
34 |
35 | /**
36 | * Menu name as displayed at the top of the {@code GuiChest}
37 | */
38 | final String MENU_DISPLAY_NAME;
39 |
40 | Menu(String menuDisplayName) {
41 | this.MENU_DISPLAY_NAME = menuDisplayName;
42 | }
43 |
44 | public String getMenuDisplayName() {
45 | return MENU_DISPLAY_NAME;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/FancyWarpMenuConfigScreen.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
26 | import net.minecraft.client.gui.GuiScreen;
27 | import net.minecraft.client.resources.I18n;
28 | import net.minecraft.event.ClickEvent;
29 | import net.minecraft.util.ChatComponentText;
30 | import net.minecraft.util.ChatStyle;
31 | import net.minecraft.util.EnumChatFormatting;
32 | import net.minecraft.util.IChatComponent;
33 | import net.minecraftforge.fml.client.config.GuiConfig;
34 | import net.minecraftforge.fml.client.config.GuiConfigEntries;
35 | import net.minecraftforge.fml.client.config.IConfigElement;
36 |
37 | import java.io.IOException;
38 | import java.net.URI;
39 | import java.net.URISyntaxException;
40 | import java.net.URL;
41 |
42 | public class FancyWarpMenuConfigScreen extends GuiConfig {
43 | public FancyWarpMenuConfigScreen(GuiScreen parent)
44 | {
45 | super(parent, Settings.getConfigElements(), "fancywarpmenu", "main", false, false, I18n.format("fancywarpmenu.config.title"), I18n.format("fancywarpmenu.config.subtitle"));
46 | }
47 |
48 | void openLink(URI link) {
49 | IChatComponent chatComponent = new ChatComponentText(null).setChatStyle(new ChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, link.toString())));
50 | handleComponentClick(chatComponent);
51 | }
52 |
53 | /**
54 | * A {@link GuiConfigEntries.CategoryEntry} implementation that changes the color of the label to a supplied chat color
55 | * Example
56 | * DummyConfigElement updateAvailableCategory = new DummyConfigElement.DummyCategoryElement(CATEGORY_UPDATE_AVAILABLE, "fancywarpmenu.config.categories.updateAvailable", updateAvailableElements);
57 | * updateAvailableCategory.set(EnumChatFormatting.GREEN);
58 | * updateAvailableCategory.setConfigEntryClass(FancyWarpMenuConfigScreen.ColoredCategoryEntry.class);
59 | */
60 | public static class ColoredCategoryEntry extends GuiConfigEntries.CategoryEntry
61 | {
62 | public ColoredCategoryEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) {
63 | super(owningScreen, owningEntryList, prop);
64 |
65 | Object colorCodeObject = configElement.getDefault();
66 |
67 | if (colorCodeObject != null) {
68 | if (colorCodeObject instanceof EnumChatFormatting) {
69 | String colorCode = colorCodeObject.toString();
70 | btnSelectCategory.displayString = colorCode + btnSelectCategory.displayString + EnumChatFormatting.RESET;
71 | }
72 | }
73 | }
74 | }
75 |
76 | /**
77 | * A {@link GuiConfigEntries.CategoryEntry} implementation that opens a link when clicked.
78 | * Example
79 | * DummyConfigElement downloadUpdateElement = new DummyConfigElement("downloadUpdate", EnvironmentDetails.SUPPORT_LINK, ConfigGuiType.STRING, "fancywarpmenu.config.downloadUpdate");
80 | * downloadUpdateElement.setConfigEntryClass(FancyWarpMenuConfigScreen.OpenLinkEntry.class);
81 | */
82 | public static class OpenLinkEntry extends GuiConfigEntries.CategoryEntry
83 | {
84 | private URI link;
85 |
86 | public OpenLinkEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) {
87 | super(owningScreen, owningEntryList, prop);
88 |
89 | // Subclasses may use the array to add additional options in addition to the link.
90 | if (getConfigElement().getDefaults() != null) {
91 | setLink(getConfigElement().getDefaults()[0]);
92 | } else {
93 | setLink(getConfigElement().getDefault());
94 | }
95 | }
96 |
97 | @Override
98 | protected GuiScreen buildChildScreen() throws RuntimeException {
99 | return null;
100 | }
101 |
102 | @Override
103 | public boolean mousePressed(int slotIndex, int x, int y, int mouseEvent, int relativeX, int relativeY) {
104 | if (btnSelectCategory.mousePressed(this.mc, x, y)) {
105 | btnSelectCategory.playPressSound(mc.getSoundHandler());
106 |
107 | if (owningScreen instanceof FancyWarpMenuConfigScreen) {
108 | ((FancyWarpMenuConfigScreen) owningScreen).openLink(link);
109 | }
110 |
111 | return true;
112 | } else {
113 | return false;
114 | }
115 | }
116 |
117 | protected void setLink(Object linkObject) {
118 | if (linkObject instanceof String) {
119 | try {
120 | link = new URL((String) linkObject).toURI();
121 | } catch (URISyntaxException | IOException e) {
122 | throw new RuntimeException(linkObject + " is not a valid URL", e);
123 | }
124 | } else {
125 | throw new RuntimeException(linkObject + " is not a string");
126 | }
127 | }
128 | }
129 |
130 | /**
131 | * A {@link GuiConfigEntries.CategoryEntry} implementation that has a colored label and opens a link when clicked.
132 | */
133 | public static class ColoredOpenLinkEntry extends OpenLinkEntry
134 | {
135 | /**
136 | * Creates a new instance of {@code ColoredOpenLinkEntry}.
137 | * Set the value of prop to an {@code Object} array with the link at index 0 and an instance of {@code EnumChatFormatting} at index 1 for the color.
138 | *
139 | * @param owningScreen parent screen
140 | * @param owningEntryList parent config entry list
141 | * @param prop property containing the link to open and the color for the label
142 | */
143 | public ColoredOpenLinkEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) {
144 | super(owningScreen, owningEntryList, prop);
145 | setColor(getConfigElement().getDefaults()[1]);
146 | }
147 |
148 | private void setColor(Object colorCodeObject) {
149 | if (colorCodeObject != null) {
150 | if (colorCodeObject instanceof EnumChatFormatting) {
151 | String colorCode = colorCodeObject.toString();
152 | btnSelectCategory.displayString = colorCode + btnSelectCategory.displayString + EnumChatFormatting.RESET;
153 | } else {
154 | throw new RuntimeException(colorCodeObject + " is not an instance of EnumChatFormatting");
155 | }
156 | }
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/FancyWarpMenuGuiFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui;
24 |
25 | import net.minecraft.client.Minecraft;
26 | import net.minecraft.client.gui.GuiScreen;
27 | import net.minecraftforge.fml.client.IModGuiFactory;
28 |
29 | import java.util.Set;
30 |
31 | @SuppressWarnings("unused")
32 | public class FancyWarpMenuGuiFactory implements IModGuiFactory {
33 | @Override
34 | public void initialize(Minecraft minecraft) {
35 |
36 | }
37 |
38 | @Override
39 | public Class extends GuiScreen> mainConfigGuiClass() {
40 | return FancyWarpMenuConfigScreen.class;
41 | }
42 |
43 | @Override
44 | public Set runtimeGuiCategories() {
45 | return null;
46 | }
47 |
48 | @Override
49 | public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement runtimeOptionCategoryElement) {
50 | return null;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/GuiFastTravel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Island;
27 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Layout;
28 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.Menu;
29 | import ca.tirelesstraveler.fancywarpmenu.gui.buttons.GuiButtonIsland;
30 | import ca.tirelesstraveler.fancywarpmenu.gui.buttons.GuiButtonWarp;
31 | import ca.tirelesstraveler.fancywarpmenu.utils.GameChecks;
32 | import net.minecraft.client.Minecraft;
33 | import net.minecraft.client.gui.GuiButton;
34 | import net.minecraft.inventory.IInventory;
35 |
36 | public class GuiFastTravel extends GuiFancyWarp {
37 |
38 | public GuiFastTravel(IInventory playerInventory, IInventory chestInventory, Layout layout) {
39 | super(playerInventory, chestInventory, layout);
40 | menu = Menu.FAST_TRAVEL;
41 | lastSlotIndexToCheck = FancyWarpMenu.getSkyBlockConstants().getLastMatchConditionInventorySlotIndex(menu);
42 | }
43 |
44 | @Override
45 | protected void actionPerformed(GuiButton button) {
46 | super.actionPerformed(button);
47 |
48 | // Block repeat clicks if the last warp failed
49 | if (Minecraft.getSystemTime() > warpFailCoolDownExpiryTime) {
50 | if (button instanceof GuiButtonWarp) {
51 | GuiButtonWarp warpButton = (GuiButtonWarp) button;
52 |
53 | // Don't send command twice for single warp islands
54 | if (warpButton.getIsland().getWarpCount() > 1) {
55 | String warpCommand = warpButton.getWarpCommand();
56 | mc.thePlayer.sendChatMessage(warpCommand);
57 | }
58 | } else if (button instanceof GuiButtonIsland) {
59 | Island island = ((GuiButtonIsland) button).getIsland();
60 |
61 | if (island.getWarpCount() == 1) {
62 | String warpCommand = island.getWarps().get(0).getWarpCommand();
63 | mc.thePlayer.sendChatMessage(warpCommand);
64 | }
65 | }
66 | }
67 | }
68 |
69 | @Override
70 | protected void updateButtonStates() {
71 | // Season is needed to show/hide the Jerry island button.
72 | GameChecks.checkSeason();
73 |
74 | super.updateButtonStates();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/GuiRiftFastTravel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Island;
27 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Layout;
28 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.Menu;
29 | import ca.tirelesstraveler.fancywarpmenu.gui.buttons.GuiButtonIsland;
30 | import ca.tirelesstraveler.fancywarpmenu.gui.buttons.GuiButtonWarp;
31 | import net.minecraft.client.Minecraft;
32 | import net.minecraft.client.gui.GuiButton;
33 | import net.minecraft.inventory.IInventory;
34 |
35 | public class GuiRiftFastTravel extends GuiFancyWarp {
36 |
37 | public GuiRiftFastTravel(IInventory playerInventory, IInventory chestInventory, Layout layout) {
38 | super(playerInventory, chestInventory, layout);
39 | menu = Menu.PORHTAL;
40 | lastSlotIndexToCheck = FancyWarpMenu.getSkyBlockConstants().getLastMatchConditionInventorySlotIndex(menu);
41 | }
42 |
43 | @Override
44 | protected void actionPerformed(GuiButton button) {
45 | super.actionPerformed(button);
46 |
47 | // Block repeat clicks if the last warp failed
48 | if (Minecraft.getSystemTime() > warpFailCoolDownExpiryTime) {
49 | if (button instanceof GuiButtonWarp) {
50 | GuiButtonWarp warpButton = (GuiButtonWarp) button;
51 |
52 | // Don't click twice for islands with only one warp
53 | if (warpButton.getIsland().getWarpCount() > 1) {
54 | clickSlot(warpButton.getWarpSlotIndex());
55 | }
56 | } else if (button instanceof GuiButtonIsland) {
57 | Island island = ((GuiButtonIsland) button).getIsland();
58 |
59 | if (island.getWarpCount() == 1) {
60 | clickSlot(island.getWarps().get(0).getSlotIndex());
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonChestMenu.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.buttons;
24 |
25 | import net.minecraft.client.Minecraft;
26 | import net.minecraft.client.gui.FontRenderer;
27 | import net.minecraft.client.gui.GuiButton;
28 | import net.minecraft.util.ResourceLocation;
29 | import org.jetbrains.annotations.NotNull;
30 |
31 | import java.awt.*;
32 |
33 | /**
34 | * Button class used with {@link ca.tirelesstraveler.fancywarpmenu.gui.GuiChestMenu}
35 | */
36 | public abstract class GuiButtonChestMenu extends GuiButton implements Comparable {
37 | protected ResourceLocation backgroundTextureLocation;
38 | protected ResourceLocation foregroundTextureLocation;
39 |
40 | /**
41 | * Constructor without coordinates for when placement is set at runtime
42 | */
43 | public GuiButtonChestMenu(int buttonId, String buttonText) {
44 | this(buttonId, 0, 0, buttonText);
45 | }
46 | public GuiButtonChestMenu(int buttonId, int x, int y, String buttonText) {
47 | super(buttonId, x, y, buttonText);
48 | }
49 |
50 | public void setHovered(boolean hovered) {
51 | this.hovered = hovered;
52 | }
53 |
54 | /**
55 | * Calculates whether this button is hovered instead of drawing a vanilla button
56 | */
57 | @Override
58 | public void drawButton(Minecraft mc, int mouseX, int mouseY) {
59 | if (visible) {
60 | hovered = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
61 | }
62 | }
63 |
64 | /**
65 | * Draw the button's display string (label).
66 | *
67 | * @param x x-coordinate to center the string on
68 | * @param y y-coordinate to center the string on
69 | * @param rgb a colour in the integer rgb format produced by {@link Color#getRGB()}
70 | */
71 | public void drawDisplayString(float x, float y, int rgb) {
72 | FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
73 | String[] lines = displayString.split("\n", 3);
74 |
75 | for (int i = 0; i < lines.length; i++) {
76 | fontRenderer.drawStringWithShadow(displayString, x - (float) fontRenderer.getStringWidth(displayString) / 2, y + (10 * i), rgb);
77 | }
78 | }
79 |
80 | /**
81 | * Compares the z-level of this {@code GuiButtonChestMenu} with another {@code GuiButtonChestMenu}
82 | * Returns negative if this button's z-level is smaller than the other button's, 0 if their z-levels are equal,
83 | * and positive if this button's z-level is greater than the other button's.
84 | *
85 | * @param o the object to be compared.
86 | */
87 | @Override
88 | public int compareTo(@NotNull GuiButtonChestMenu o) {
89 | return (int) (this.zLevel - o.zLevel);
90 | }
91 |
92 | public int getZLevel() {
93 | return (int) zLevel;
94 | }
95 |
96 | public void setEnabled(boolean enabled) {
97 | this.enabled = enabled;
98 | }
99 |
100 | public void setVisible(boolean visible) {
101 | this.visible = visible;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.buttons;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
27 | import ca.tirelesstraveler.fancywarpmenu.data.layout.ConfigButton;
28 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Island;
29 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Layout;
30 | import ca.tirelesstraveler.fancywarpmenu.gui.grid.GridRectangle;
31 | import ca.tirelesstraveler.fancywarpmenu.gui.grid.ScaledGrid;
32 | import ca.tirelesstraveler.fancywarpmenu.gui.transitions.ScaleTransition;
33 | import net.minecraft.client.Minecraft;
34 | import net.minecraft.client.gui.ScaledResolution;
35 | import net.minecraft.client.resources.I18n;
36 | import net.minecraft.util.EnumChatFormatting;
37 | import net.minecraftforge.common.ForgeVersion;
38 |
39 | @SuppressWarnings("FieldCanBeLocal")
40 | public class GuiButtonConfig extends GuiButtonScaleTransition {
41 | private static final float HOVERED_SCALE = 1.2F;
42 | private static final long SCALE_TRANSITION_DURATION = 500;
43 |
44 | /** This button uses its own grid instead of the grid of the GuiScreen it belongs to since it's also attached to vanilla screens, which don't have grids */
45 | private final ScaledGrid scaledGrid;
46 | // Far right edge
47 | private final int GRID_X;
48 | // Bottom edge
49 | private final int GRID_Y;
50 |
51 | public GuiButtonConfig(Layout layout, int buttonId, ScaledResolution res) {
52 | super(buttonId, EnumChatFormatting.GREEN + I18n.format(FancyWarpMenu.getFullLanguageKey("gui.buttons.config")));
53 | scaledGrid = new ScaledGrid(0, 0, res.getScaledWidth(), res.getScaledHeight(), Island.GRID_UNIT_HEIGHT_FACTOR, Island.GRID_UNIT_WIDTH_FACTOR, false);
54 | ConfigButton configButtonSettings = layout.getConfigButton();
55 | configButtonSettings.init(res);
56 | GRID_X = configButtonSettings.getGridX();
57 | GRID_Y = configButtonSettings.getGridY();
58 | width = configButtonSettings.getWidth();
59 | height = configButtonSettings.getHeight();
60 | // Above islands and warps
61 | zLevel = 20;
62 | buttonRectangle = new GridRectangle(scaledGrid, GRID_X, GRID_Y, width, height, false, true);
63 | scaledGrid.addRectangle("configButton", buttonRectangle);
64 | backgroundTextureLocation = configButtonSettings.getTextureLocation();
65 | transition = new ScaleTransition(0, 1, 1);
66 | }
67 |
68 | @Override
69 | public void drawButton(Minecraft mc, int mouseX, int mouseY) {
70 | if (this.visible) {
71 | calculateHoverState(mouseX, mouseY);
72 | transitionStep(SCALE_TRANSITION_DURATION, HOVERED_SCALE);
73 |
74 | super.drawButton(mc, mouseX, mouseY);
75 |
76 | if (Settings.isUpdateNotificationEnabled() && FancyWarpMenu.getUpdateCheckResult() != null && FancyWarpMenu.getUpdateCheckResult().status == ForgeVersion.Status.OUTDATED) {
77 | drawButtonForegroundLayer(ConfigButton.NOTIFICATION_TEXTURE_LOCATION);
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonIsland.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.buttons;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Island;
26 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
27 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Warp;
28 | import ca.tirelesstraveler.fancywarpmenu.gui.GuiFancyWarp;
29 | import ca.tirelesstraveler.fancywarpmenu.gui.grid.ScaledGrid;
30 | import ca.tirelesstraveler.fancywarpmenu.gui.transitions.ScaleTransition;
31 | import net.minecraft.client.Minecraft;
32 | import net.minecraft.client.gui.ScaledResolution;
33 | import net.minecraft.util.EnumChatFormatting;
34 |
35 | import java.awt.*;
36 |
37 | public class GuiButtonIsland extends GuiButtonScaleTransition {
38 | private static final float HOVERED_SCALE = 1.1F;
39 | private static final long SCALE_TRANSITION_DURATION = 400;
40 | final Island island;
41 | final ScaledGrid scaledGrid;
42 |
43 | public GuiButtonIsland(GuiFancyWarp parent, int buttonId, ScaledResolution res, Island island) {
44 | super(buttonId, "");
45 | this.island = island;
46 | island.init(res);
47 | scaledXPosition = parent.getScaledGrid().getActualX(island.getGridX());
48 | scaledYPosition = parent.getScaledGrid().getActualY(island.getGridY());
49 | zLevel = island.getzLevel();
50 | width = island.getWidth();
51 | height = island.getHeight();
52 | scaledGrid = new ScaledGrid(scaledXPosition, scaledYPosition, width, height, Warp.GRID_UNIT_WIDTH_FACTOR, true);
53 | displayString = EnumChatFormatting.GREEN + island.getName();
54 | backgroundTextureLocation = island.getTextureLocation();
55 | foregroundTextureLocation = island.getHoverEffectTextureLocation();
56 | transition = new ScaleTransition(0, 1, 1);
57 |
58 | // Each line is drawn separately. Copy the colour code to all lines.
59 | if (displayString.contains("\n")) {
60 | displayString = displayString.replaceAll("\n", "\n" + EnumChatFormatting.GREEN);
61 | }
62 | }
63 |
64 | @Override
65 | public void drawButton(Minecraft mc, int mouseX, int mouseY) {
66 | if (visible) {
67 | float originalZ = zLevel;
68 |
69 | transitionStep(SCALE_TRANSITION_DURATION, HOVERED_SCALE);
70 |
71 | scaledGrid.setScaleFactor(transition.getCurrentScale());
72 | scaledXPosition = scaledGrid.getGridStartX();
73 | scaledYPosition = scaledGrid.getGridStartY();
74 | scaledWidth = scaledGrid.getScaledDimension(width);
75 | scaledHeight = scaledGrid.getScaledDimension(height);
76 |
77 | if (hovered) {
78 | zLevel = 9;
79 | }
80 |
81 | drawButtonTexture(backgroundTextureLocation);
82 | if (hovered) {
83 | drawButtonForegroundLayer(foregroundTextureLocation);
84 | }
85 |
86 | if (Settings.shouldShowIslandLabels()) {
87 | drawDisplayString(mc, scaledWidth / 2F, scaledHeight);
88 | }
89 |
90 | if (Settings.isDebugModeEnabled() && Settings.shouldDrawBorders()) {
91 | drawBorder(Color.WHITE);
92 | }
93 |
94 | zLevel = originalZ;
95 | }
96 | }
97 |
98 | public Island getIsland() {
99 | return island;
100 | }
101 |
102 | public ScaledGrid getScaledGrid() {
103 | return scaledGrid;
104 | }
105 |
106 | public float getScaledXPosition() {
107 | return scaledXPosition;
108 | }
109 |
110 | public float getScaledYPosition() {
111 | return scaledYPosition;
112 | }
113 |
114 | public float getScaledWidth() {
115 | return scaledWidth;
116 | }
117 |
118 | public float getScaledHeight() {
119 | return scaledHeight;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonRegularWarpMenu.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.buttons;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Layout;
27 | import ca.tirelesstraveler.fancywarpmenu.data.layout.RegularWarpMenuButton;
28 | import ca.tirelesstraveler.fancywarpmenu.gui.grid.GridRectangle;
29 | import ca.tirelesstraveler.fancywarpmenu.gui.grid.ScaledGrid;
30 | import ca.tirelesstraveler.fancywarpmenu.gui.transitions.ScaleTransition;
31 | import net.minecraft.client.Minecraft;
32 | import net.minecraft.client.gui.ScaledResolution;
33 | import net.minecraft.client.resources.I18n;
34 | import net.minecraft.util.EnumChatFormatting;
35 |
36 | @SuppressWarnings("FieldCanBeLocal")
37 | public class GuiButtonRegularWarpMenu extends GuiButtonScaleTransition {
38 | private static final float HOVERED_SCALE = 1.2F;
39 | private static final long SCALE_TRANSITION_DURATION = 500;
40 | // Far right edge
41 | private final int GRID_X;
42 | // Bottom edge
43 | private final int GRID_Y;
44 |
45 | public GuiButtonRegularWarpMenu(Layout layout, int buttonId, ScaledResolution res, ScaledGrid scaledGrid) {
46 | super(buttonId, EnumChatFormatting.GREEN + I18n.format(FancyWarpMenu.getFullLanguageKey("gui.buttons.regularWarpMenu")));
47 | RegularWarpMenuButton regularWarpMenuButtonSettings = layout.getRegularWarpMenuButton();
48 | regularWarpMenuButtonSettings.init(res);
49 | GRID_X = regularWarpMenuButtonSettings.getGridX();
50 | GRID_Y = regularWarpMenuButtonSettings.getGridY();
51 | width = regularWarpMenuButtonSettings.getWidth();
52 | height = regularWarpMenuButtonSettings.getHeight();
53 | // Above islands and warps
54 | zLevel = 20;
55 | buttonRectangle = new GridRectangle(scaledGrid, GRID_X, GRID_Y, width, height, false, true);
56 | scaledGrid.addRectangle("regularWarpMenuButton", buttonRectangle);
57 | backgroundTextureLocation = regularWarpMenuButtonSettings.getTextureLocation();
58 | transition = new ScaleTransition(0, 1, 1);
59 | displayString = String.join("\n", Minecraft.getMinecraft().fontRendererObj.listFormattedStringToWidth(displayString, width * 3));
60 | }
61 |
62 | @Override
63 | public void drawButton(Minecraft mc, int mouseX, int mouseY) {
64 | if (this.visible) {
65 | calculateHoverState(mouseX, mouseY);
66 | transitionStep(SCALE_TRANSITION_DURATION, HOVERED_SCALE);
67 |
68 | super.drawButton(mc, mouseX, mouseY);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonTimedLabel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.buttons;
24 |
25 | import net.minecraft.client.Minecraft;
26 | import net.minecraft.client.gui.GuiButton;
27 |
28 | /**
29 | * This class allows the setting of a temporary button label that reverts to the original button label
30 | * after a given amount of time.
31 | */
32 | public class GuiButtonTimedLabel extends GuiButton {
33 | private String originalButtonLabel;
34 | private long timedLabelExpiryTime;
35 |
36 | public GuiButtonTimedLabel(int buttonId, int x, int y, String buttonText) {
37 | super(buttonId, x, y, buttonText);
38 | }
39 |
40 | public GuiButtonTimedLabel(int buttonId, int x, int y, int widthIn, int heightIn, String buttonText) {
41 | super(buttonId, x, y, widthIn, heightIn, buttonText);
42 | }
43 |
44 | /**
45 | * Reset the temporary label to the original label after {@link #timedLabelExpiryTime} has passed.
46 | */
47 | @Override
48 | public void drawButton(Minecraft mc, int mouseX, int mouseY) {
49 | super.drawButton(mc, mouseX, mouseY);
50 |
51 | if (timedLabelExpiryTime > 0 && Minecraft.getSystemTime() > timedLabelExpiryTime) {
52 | timedLabelExpiryTime = -1;
53 | displayString = originalButtonLabel;
54 | }
55 | }
56 |
57 | /**
58 | * Set a temporary label text for this button that will revert to the original label text after the given
59 | * time has elapsed.
60 | *
61 | * @param labelText the temporary label text
62 | * @param time the time in milliseconds this label text should be shown for
63 | */
64 | public void setTimedLabel(String labelText, int time) {
65 | timedLabelExpiryTime = Minecraft.getSystemTime() + time;
66 | originalButtonLabel = displayString;
67 | displayString = labelText;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonWarp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.buttons;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Island;
26 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
27 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Warp;
28 | import ca.tirelesstraveler.fancywarpmenu.gui.grid.GridRectangle;
29 | import ca.tirelesstraveler.fancywarpmenu.gui.transitions.ScaleTransition;
30 | import net.minecraft.client.Minecraft;
31 |
32 | public class GuiButtonWarp extends GuiButtonScaleTransition {
33 | /** The button of the island this warp belongs to */
34 | private final GuiButtonIsland PARENT;
35 | private final Warp WARP;
36 | /** Whether the warp label should be drawn under the button */
37 | private boolean drawWarpLabel;
38 |
39 | /**
40 | * x and y are relative to the top left corner of the parent island button.
41 | */
42 | public GuiButtonWarp(int buttonId, GuiButtonIsland parent, Warp warp) {
43 | super(buttonId, "");
44 | PARENT = parent;
45 | WARP = warp;
46 | buttonRectangle = new GridRectangle(parent.scaledGrid, warp.getGridX(), warp.getGridY(), warp.getWidth(), warp.getHeight(), true, false);
47 | parent.scaledGrid.addRectangle(warp.getDisplayName(), buttonRectangle);
48 | zLevel = 10;
49 | displayString = warp.getDisplayName();
50 | drawWarpLabel = true;
51 | backgroundTextureLocation = WARP.getWarpTextureLocation();
52 | foregroundTextureLocation = WARP.getWarpHoverEffectTextureLocation();
53 | transition = new ScaleTransition(0, 0, 0);
54 | }
55 |
56 | /**
57 | * Draws this button to the screen.
58 | */
59 | @Override
60 | public void drawButton(Minecraft mc, int mouseX, int mouseY) {
61 | if (visible) {
62 | float originalZ = zLevel;
63 |
64 | calculateHoverState(mouseX, mouseY);
65 | transition.setCurrentScale(PARENT.scaledGrid.getScaleFactor());
66 |
67 | if (hovered) {
68 | zLevel = 19;
69 | }
70 |
71 | super.drawButton(mc, mouseX, mouseY);
72 |
73 | if (hovered) {
74 | drawButtonForegroundLayer(foregroundTextureLocation);
75 | }
76 |
77 | if (drawWarpLabel && (!Settings.shouldHideWarpLabelsUntilIslandHovered() || PARENT.isMouseOver())) {
78 | drawDisplayString(mc, buttonRectangle.getWidth() / 2F, buttonRectangle.getHeight());
79 | }
80 |
81 | zLevel = originalZ;
82 | }
83 | }
84 |
85 | public String getWarpCommand() {
86 | return WARP.getWarpCommand();
87 | }
88 |
89 | public int getWarpSlotIndex() {
90 | return WARP.getSlotIndex();
91 | }
92 |
93 | public Island getIsland() {
94 | return PARENT.island;
95 | }
96 |
97 | public Warp getWarp() {
98 | return WARP;
99 | }
100 |
101 | public void setDrawWarpLabel(boolean drawWarpLabel) {
102 | this.drawWarpLabel = drawWarpLabel;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/grid/GridRectangle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.grid;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.gui.buttons.GuiButtonIsland;
26 |
27 | /**
28 | * A rectangle placed on a {@code ScaledGrid}. These rectangles serve as bounding boxes for the GUI elements placed on
29 | * the grid, providing coordinates and dimensions to be used during rendering. This class does not cover using a
30 | * {@code ScaledGrid} placed within a {@code ScaledGrid}. For an example of that usage, see {@link GuiButtonIsland}
31 | *
32 | * @see ScaledGrid
33 | */
34 | public class GridRectangle {
35 | protected transient final ScaledGrid scaledGrid;
36 | protected int gridX;
37 | protected int gridY;
38 | /** x position in pixels of the left edge */
39 | protected float xPosition;
40 | /** y position in pixels of the top edge */
41 | protected float yPosition;
42 | /** scaled x position of the left edge */
43 | protected float scaledXPosition;
44 | /** scaled y position of the top edge */
45 | protected float scaledYPosition;
46 | protected float width;
47 | protected float height;
48 | protected float scaledWidth;
49 | protected float scaledHeight;
50 | /** If {@code true}, multiply the position by the scale factor. If {@code false}, leave position as is. */
51 | protected boolean scalePosition;
52 | /** If {@code true}, shift the position so the rectangle looks like it's being expanded from the centre instead of the top left when scaled. If {@code false}, leave position as is. This works only when {@code scalePosition} is {@code false}. */
53 | protected boolean centerPositionWhenScaled;
54 |
55 | public GridRectangle(ScaledGrid scaledGrid, int gridX, int gridY, float width, float height, boolean scalePosition, boolean centerPositionWhenScaled) {
56 | this.scaledGrid = scaledGrid;
57 | this.gridX = gridX;
58 | this.gridY = gridY;
59 | this.xPosition = scaledGrid.getActualX(gridX);
60 | this.yPosition = scaledGrid.getActualY(gridY);
61 | this.width = width;
62 | this.height = height;
63 | this.scalePosition = scalePosition;
64 | this.centerPositionWhenScaled = centerPositionWhenScaled;
65 | }
66 |
67 | public void scale(float scaleFactor) {
68 | scaledWidth = width * scaleFactor;
69 | scaledHeight = height * scaleFactor;
70 |
71 | if (scalePosition) {
72 | scaledXPosition = scaledGrid.getActualX(gridX);
73 | scaledYPosition = scaledGrid.getActualY(gridY);
74 | } else if (centerPositionWhenScaled) {
75 | scaledXPosition = xPosition - (scaledWidth - width) / 2;
76 | scaledYPosition = yPosition - (scaledHeight - height) / 2;
77 | }
78 | }
79 |
80 | public float getXPosition() {
81 | if (scalePosition || centerPositionWhenScaled) {
82 | return scaledXPosition;
83 | } else {
84 | return xPosition;
85 | }
86 | }
87 |
88 | public float getYPosition() {
89 | if (scalePosition || centerPositionWhenScaled) {
90 | return scaledYPosition;
91 | } else {
92 | return yPosition;
93 | }
94 | }
95 |
96 | public float getWidth() {
97 | return scaledWidth;
98 | }
99 |
100 | public float getHeight() {
101 | return scaledHeight;
102 | }
103 |
104 | @Override
105 | public String toString() {
106 | return "GridRectangle{" +
107 | "gridX=" + gridX +
108 | ", gridY=" + gridY +
109 | ", xPosition=" + xPosition +
110 | ", yPosition=" + yPosition +
111 | ", scaledXPosition=" + scaledXPosition +
112 | ", scaledYPosition=" + scaledYPosition +
113 | ", width=" + width +
114 | ", height=" + height +
115 | ", scaledWidth=" + scaledWidth +
116 | ", scaledHeight=" + scaledHeight +
117 | ", scalePosition=" + scalePosition +
118 | ", centerPositionWhenScaled=" + centerPositionWhenScaled +
119 | '}';
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/transitions/ScaleTransition.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.transitions;
24 |
25 | /**
26 | * Transition used to change a GUI element's size as time passes
27 | */
28 | public class ScaleTransition extends Transition {
29 | private final float START_SCALE;
30 | private final float END_SCALE;
31 | private float currentScale;
32 |
33 | public ScaleTransition(long duration, float startScale, float endScale) {
34 | super(duration);
35 | this.START_SCALE = startScale;
36 | this.END_SCALE = endScale;
37 | this.currentScale = startScale;
38 | }
39 |
40 | @Override
41 | public void step() {
42 | super.step();
43 | currentScale = START_SCALE + (END_SCALE - START_SCALE) * progress;
44 | }
45 |
46 | public float getStartScale() {
47 | return START_SCALE;
48 | }
49 |
50 | public float getEndScale() {
51 | return END_SCALE;
52 | }
53 |
54 | public float getCurrentScale() {
55 | return currentScale;
56 | }
57 |
58 | public void setCurrentScale(float scale) {
59 | currentScale = scale;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/transitions/Transition.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.gui.transitions;
24 |
25 | import net.minecraft.client.Minecraft;
26 |
27 | /**
28 | * This base class tracks a start time, end time, and the current system time's difference from the end time.
29 | * Subclasses are meant to extend this with GUI attributes whose values will change as time passes.
30 | */
31 | public class Transition {
32 | protected long startTime;
33 | protected long endTime;
34 | protected long duration;
35 | protected long currentTime;
36 | protected float progress;
37 | protected boolean finished;
38 |
39 | public Transition(long duration) {
40 | startTime = Minecraft.getSystemTime();
41 | this.duration = duration;
42 | endTime = startTime + duration;
43 | finished = false;
44 | }
45 |
46 | public float getProgress() {
47 | return progress;
48 | }
49 |
50 | public boolean isFinished() {
51 | return finished;
52 | }
53 |
54 | /**
55 | * Recalculate the progress of the transition using the current system time
56 | */
57 | public void step() {
58 | if (!finished) {
59 | currentTime = Minecraft.getSystemTime();
60 | progress = (float) (currentTime - startTime) / duration;
61 |
62 | if (currentTime >= endTime) {
63 | progress = 1;
64 | finished = true;
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/ChatListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.listeners;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
27 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.WarpCommandVariant;
28 | import ca.tirelesstraveler.fancywarpmenu.gui.GuiFancyWarp;
29 | import ca.tirelesstraveler.fancywarpmenu.state.FancyWarpMenuState;
30 | import ca.tirelesstraveler.fancywarpmenu.utils.ChatUtils;
31 | import net.minecraft.client.Minecraft;
32 | import net.minecraft.client.gui.GuiChat;
33 | import net.minecraft.client.gui.GuiScreen;
34 | import net.minecraft.util.ChatComponentTranslation;
35 | import net.minecraft.util.ChatStyle;
36 | import net.minecraft.util.EnumChatFormatting;
37 | import net.minecraft.util.IChatComponent;
38 | import net.minecraftforge.client.event.ClientChatReceivedEvent;
39 | import net.minecraftforge.client.event.GuiOpenEvent;
40 | import net.minecraftforge.client.event.GuiScreenEvent;
41 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
42 | import org.lwjgl.input.Keyboard;
43 | import org.lwjgl.input.Mouse;
44 |
45 | import java.util.List;
46 | import java.util.Locale;
47 |
48 | public class ChatListener {
49 | private final Minecraft mc;
50 | private boolean chatMessageSendDetected;
51 |
52 | public ChatListener() {
53 | mc = Minecraft.getMinecraft();
54 | }
55 |
56 | @SubscribeEvent
57 | public void onChatMessageReceived(ClientChatReceivedEvent event) {
58 | // type 0 is a standard chat message
59 | if (event.type == 0 && FancyWarpMenuState.isFancyWarpMenuOpen()) {
60 | String unformattedText = event.message.getUnformattedText();
61 |
62 | if (FancyWarpMenu.getSkyBlockConstants().getWarpMessages().getWarpFailMessages().containsKey(unformattedText)) {
63 | String failMessageKey = FancyWarpMenu.getSkyBlockConstants().getWarpMessages().getWarpFailMessages().get(unformattedText);
64 | ((GuiFancyWarp) mc.currentScreen).onWarpFail(failMessageKey);
65 | }
66 | }
67 | }
68 |
69 | @SubscribeEvent
70 | public void onGuiOpen(GuiOpenEvent event) {
71 | if (chatMessageSendDetected && mc.currentScreen instanceof GuiChat && event.gui == null) {
72 | chatMessageSendDetected = false;
73 |
74 | List sentMessages = mc.ingameGUI.getChatGUI().getSentMessages();
75 |
76 | if (!sentMessages.isEmpty()) {
77 | checkChatMessageForReminder(sentMessages.get(sentMessages.size() - 1));
78 | }
79 | }
80 | }
81 |
82 | /**
83 | * Copies the throwable provided when the component from
84 | * {@link ChatUtils#sendErrorMessageWithCopyableThrowable(String, Throwable)} is clicked.
85 | *
86 | * @param event the mouse event
87 | */
88 | @SubscribeEvent
89 | public void mouseClicked(GuiScreenEvent.MouseInputEvent.Pre event) {
90 | // Left mouse button down
91 | if (event.gui instanceof GuiChat && Mouse.getEventButton() == 0 && Mouse.getEventButtonState()) {
92 | IChatComponent chatComponent = mc.ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY());
93 |
94 | if (chatComponent != null && chatComponent.getChatStyle() != null) {
95 | ChatStyle chatStyle = chatComponent.getChatStyle();
96 | String insertion = chatStyle.getInsertion();
97 |
98 | if (insertion != null && insertion.equals(ChatUtils.COPY_TO_CLIPBOARD_TRANSLATION_KEY)
99 | && chatStyle.getChatClickEvent() != null) {
100 | String clickEventValue = chatStyle.getChatClickEvent().getValue();
101 |
102 | if (clickEventValue != null) {
103 | String copiedMessageTranslationKey = "fancywarpmenu.gui.buttons.copyToClipboard.copied";
104 |
105 | GuiScreen.setClipboardString(clickEventValue);
106 | ChatUtils.sendMessageWithModNamePrefix(new ChatComponentTranslation(copiedMessageTranslationKey)
107 | .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN)));
108 | event.setCanceled(true);
109 | }
110 | }
111 | }
112 | }
113 | }
114 |
115 | @SubscribeEvent
116 | public void keyTyped(GuiScreenEvent.KeyboardInputEvent event) {
117 | if (event.gui instanceof GuiChat &&
118 | (Keyboard.getEventKey() == Keyboard.KEY_RETURN || Keyboard.getEventKey() == Keyboard.KEY_NUMPADENTER) &&
119 | Keyboard.getEventKeyState()) {
120 | chatMessageSendDetected = true;
121 | }
122 | }
123 |
124 | /**
125 | * If the reminder feature is enabled, check a given chat message for a warp command variant.
126 | * If the message is a warp command variant, remind the player to use the Fancy Warp Menu instead of commands.
127 | *
128 | * @param sentChatMessage the chat message that was just sent
129 | * @see Settings#shouldSuggestWarpMenuOnWarpCommand()
130 | */
131 | private void checkChatMessageForReminder(String sentChatMessage) {
132 | if (Settings.shouldSuggestWarpMenuOnWarpCommand() && getWarpCommandVariant(sentChatMessage) != null) {
133 | sendReminderToUseFancyMenu();
134 | }
135 | }
136 |
137 | /**
138 | * Checks if a given command is the warp command or any of its variants and returns the corresponding
139 | * {@code WarpCommandVariant} object if one is found.
140 | *
141 | * @param command the command the player sent
142 | * @return a {@link WarpCommandVariant} if one with the same command is found, or {@code null} otherwise
143 | */
144 | private WarpCommandVariant getWarpCommandVariant(String command) {
145 | // Trim off the slash and all arguments
146 | String baseCommand = command.toLowerCase(Locale.US).substring(1).split(" ")[0];
147 |
148 | for (WarpCommandVariant commandVariant : FancyWarpMenu.getSkyBlockConstants().getWarpCommandVariants()) {
149 | if (commandVariant.getCommand().equals(baseCommand)) {
150 | return commandVariant;
151 | }
152 | }
153 |
154 | return null;
155 | }
156 |
157 | private void sendReminderToUseFancyMenu() {
158 | ChatUtils.sendMessageWithModNamePrefix(new ChatComponentTranslation(FancyWarpMenu
159 | .getFullLanguageKey("messages.useWarpMenuInsteadOfCommand"))
160 | .setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)));
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/InventoryChangeListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.listeners;
24 |
25 | import net.minecraft.inventory.IInvBasic;
26 | import net.minecraft.inventory.InventoryBasic;
27 |
28 | import java.util.function.Consumer;
29 |
30 | /**
31 | * A simple listener that calls a callback when an item changes in the inventory it is assigned to.
32 | */
33 | public class InventoryChangeListener implements IInvBasic {
34 | private final Consumer CALLBACK;
35 |
36 | public InventoryChangeListener(Consumer callback) {
37 | CALLBACK = callback;
38 | }
39 |
40 |
41 | @Override
42 | public void onInventoryChanged(InventoryBasic inventoryBasic) {
43 | CALLBACK.accept(inventoryBasic);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/SkyBlockJoinListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.listeners;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.state.GameState;
26 | import io.netty.channel.ChannelHandler;
27 | import net.minecraft.client.Minecraft;
28 | import net.minecraft.client.entity.EntityPlayerSP;
29 | import net.minecraft.scoreboard.Scoreboard;
30 | import net.minecraftforge.client.event.ClientChatReceivedEvent;
31 | import net.minecraftforge.event.world.WorldEvent;
32 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
33 | import net.minecraftforge.fml.common.network.FMLNetworkEvent;
34 | import org.apache.logging.log4j.LogManager;
35 | import org.apache.logging.log4j.Logger;
36 |
37 | /**
38 | * Forge event and packet listener that detects when the player joins/leaves SkyBlock
39 | */
40 | @ChannelHandler.Sharable
41 | public class SkyBlockJoinListener {
42 | private static final String SERVER_BRAND_START = "Hypixel BungeeCord";
43 | private static final int SCOREBOARD_CHECK_TIME_OUT = 5000;
44 |
45 | private static final Logger logger = LogManager.getLogger();
46 | private boolean serverBrandChecked;
47 | private boolean onHypixel;
48 | private boolean scoreboardChecked;
49 | private long lastWorldSwitchTime;
50 |
51 | @SubscribeEvent
52 | public void onClientDisconnect(FMLNetworkEvent.ClientDisconnectionFromServerEvent e) {
53 | if (onHypixel) {
54 | serverBrandChecked = false;
55 | onHypixel = false;
56 | GameState.setOnSkyBlock(false);
57 | logger.debug("Disconnected from Hypixel.");
58 | }
59 | }
60 |
61 | @SubscribeEvent
62 | public void onWorldLoad(WorldEvent.Load event) {
63 | // Reset on world switch
64 | lastWorldSwitchTime = Minecraft.getSystemTime();
65 | scoreboardChecked = false;
66 | GameState.setOnSkyBlock(false);
67 | }
68 |
69 | @SubscribeEvent
70 | public void onChatMessageReceived(ClientChatReceivedEvent event) {
71 | if (!serverBrandChecked || onHypixel && !scoreboardChecked) {
72 | // type 0 is a standard chat message
73 | if (event.type == 0) {
74 | EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer;
75 | String brand = thePlayer.getClientBrand();
76 |
77 | if (!serverBrandChecked) {
78 | onHypixel = brand != null && brand.startsWith(SERVER_BRAND_START);
79 | serverBrandChecked = true;
80 |
81 | if (onHypixel) {
82 | logger.debug("Player joined Hypixel.");
83 | }
84 | }
85 |
86 | if (onHypixel && !scoreboardChecked) {
87 | Scoreboard scoreboard = thePlayer.getWorldScoreboard();
88 | boolean newSkyBlockState = scoreboard != null && scoreboard.getObjective("SBScoreboard") != null;
89 |
90 | if (newSkyBlockState != GameState.isOnSkyBlock()) {
91 | if (newSkyBlockState) {
92 | logger.debug("Player joined SkyBlock.");
93 | } else {
94 | logger.debug("Player left SkyBlock.");
95 | }
96 |
97 | GameState.setOnSkyBlock(newSkyBlockState);
98 | scoreboardChecked = true;
99 | }
100 |
101 | if (Minecraft.getSystemTime() - lastWorldSwitchTime > SCOREBOARD_CHECK_TIME_OUT) {
102 | scoreboardChecked = true;
103 | }
104 | }
105 | }
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/WarpMenuListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.listeners;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
27 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.SkyBlockConstants;
28 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.Menu;
29 | import ca.tirelesstraveler.fancywarpmenu.gui.FancyWarpMenuConfigScreen;
30 | import ca.tirelesstraveler.fancywarpmenu.gui.GuiFastTravel;
31 | import ca.tirelesstraveler.fancywarpmenu.gui.GuiRiftFastTravel;
32 | import ca.tirelesstraveler.fancywarpmenu.state.FancyWarpMenuState;
33 | import ca.tirelesstraveler.fancywarpmenu.state.GameState;
34 | import ca.tirelesstraveler.fancywarpmenu.utils.GameChecks;
35 | import net.minecraft.client.Minecraft;
36 | import net.minecraft.client.gui.inventory.GuiChest;
37 | import net.minecraft.client.resources.IResourceManager;
38 | import net.minecraft.client.resources.IResourceManagerReloadListener;
39 | import net.minecraft.inventory.ContainerChest;
40 | import net.minecraft.inventory.IInventory;
41 | import net.minecraftforge.client.event.GuiOpenEvent;
42 | import net.minecraftforge.fml.client.event.ConfigChangedEvent;
43 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
44 | import net.minecraftforge.fml.common.gameevent.InputEvent;
45 | import org.apache.logging.log4j.LogManager;
46 | import org.apache.logging.log4j.Logger;
47 |
48 | /**
49 | * General purpose event listener
50 | */
51 | public class WarpMenuListener implements IResourceManagerReloadListener {
52 | private static final Minecraft mc;
53 | private static final FancyWarpMenu modInstance;
54 | private static final Logger logger;
55 | /** The minimum time in milliseconds after a hotkey press before the player can use the hotkey again*/
56 | private static final int HOTKEY_PRESS_DELAY = 2000;
57 |
58 | /**
59 | * Time the user last pressed the fancy warp menu hotkey, used to prevent command spamming from
60 | * spam pressing the hotkey
61 | */
62 | private long lastWarpMenuHotkeyPress;
63 |
64 | static {
65 | mc = Minecraft.getMinecraft();
66 | modInstance = FancyWarpMenu.getInstance();
67 | logger = LogManager.getLogger();
68 | }
69 |
70 | @SubscribeEvent
71 | public void onGuiOpen(GuiOpenEvent event) {
72 | /*
73 | Minecraft closes the current screen after executing a command, meaning any GuiScreen opened by the command is closed.
74 | This section interrupts the closing of the current screen to get around this behavior.
75 | */
76 | if (event.gui == null) {
77 | if (FancyWarpMenuState.isOpenConfigMenuRequested()) {
78 | event.gui = new FancyWarpMenuConfigScreen(null);
79 | FancyWarpMenuState.setOpenConfigMenuRequested(false);
80 | }
81 | } else if (GameState.isOnSkyBlock() && event.gui instanceof GuiChest) {
82 | IInventory playerInventory = mc.thePlayer.inventory;
83 | IInventory chestInventory = ((ContainerChest) ((GuiChest) event.gui).inventorySlots).getLowerChestInventory();
84 |
85 | Menu currentMenu = GameChecks.determineOpenMenu(chestInventory);
86 |
87 | if (currentMenu == Menu.FAST_TRAVEL) {
88 | event.gui = new GuiFastTravel(playerInventory, chestInventory, FancyWarpMenuState.getOverworldLayout());
89 | } else if (currentMenu == Menu.PORHTAL) {
90 | event.gui = new GuiRiftFastTravel(playerInventory, chestInventory, FancyWarpMenuState.getRiftLayout());
91 | }
92 | }
93 | }
94 |
95 | @SubscribeEvent
96 | public void keyTyped(InputEvent.KeyInputEvent event) {
97 | if (Settings.isWarpMenuEnabled() && GameState.isOnSkyBlock() &&
98 | FancyWarpMenu.getKeyBindingOpenWarpMenu().isPressed() &&
99 | Minecraft.getSystemTime() - lastWarpMenuHotkeyPress > HOTKEY_PRESS_DELAY) {
100 | lastWarpMenuHotkeyPress = Minecraft.getSystemTime();
101 | mc.thePlayer.sendChatMessage(SkyBlockConstants.WARP_COMMAND_BASE);
102 | }
103 | }
104 |
105 | @SubscribeEvent
106 | public void onConfigChange(ConfigChangedEvent.OnConfigChangedEvent event) {
107 | if (event.modID.equals(modInstance.getModId())) {
108 | Settings.syncConfig(false);
109 | }
110 | }
111 |
112 | @Override
113 | public void onResourceManagerReload(IResourceManager resourceManager) {
114 | FancyWarpMenu.getInstance().reloadLayouts();
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/resourceloaders/LayoutLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.resourceloaders;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.data.layout.*;
26 | import ca.tirelesstraveler.fancywarpmenu.state.FancyWarpMenuState;
27 | import com.google.gson.stream.JsonReader;
28 | import net.minecraft.client.Minecraft;
29 | import net.minecraft.client.renderer.texture.TextureUtil;
30 | import net.minecraft.client.resources.IResource;
31 | import net.minecraft.client.resources.IResourceManager;
32 | import net.minecraft.crash.CrashReport;
33 | import net.minecraft.util.ReportedException;
34 | import net.minecraft.util.ResourceLocation;
35 | import org.apache.commons.lang3.tuple.Pair;
36 |
37 | import java.awt.image.BufferedImage;
38 | import java.io.IOException;
39 | import java.io.InputStream;
40 | import java.io.InputStreamReader;
41 |
42 | public class LayoutLoader extends ResourceLoader {
43 | public static final ResourceLocation OVERWORLD_LAYOUT_LOCATION = new ResourceLocation("fancywarpmenu",
44 | "data/layout.json");
45 | public static final ResourceLocation RIFT_LAYOUT_LOCATION = new ResourceLocation("fancywarpmenu", "data/riftLayout.json");
46 |
47 | public static Layout loadLayout(ResourceLocation resourceLocation) {
48 | try {
49 | IResource layoutResource = Minecraft.getMinecraft().getResourceManager().getResource(resourceLocation);
50 |
51 | try (InputStream stream = layoutResource.getInputStream();
52 | JsonReader reader = new JsonReader(new InputStreamReader(stream))) {
53 | Layout layout = gson.fromJson(reader, Layout.class);
54 | Layout.validateLayout(layout);
55 |
56 | // Layout background texture
57 | layout.setBackgroundTextureLocation();
58 |
59 | // Warp icon
60 | WarpIcon warpIcon = layout.getWarpIcon();
61 | Warp.setWarpIcon(warpIcon);
62 | warpIcon.init();
63 | Pair warpIconDimensions = getTextureDimensions(warpIcon.getTextureLocation());
64 | warpIcon.setTextureDimensions(warpIconDimensions.getLeft(), warpIconDimensions.getRight());
65 |
66 | // Config and regular warp menu button icon dimensions
67 | ConfigButton configButton = layout.getConfigButton();
68 | RegularWarpMenuButton regularWarpMenuButton = layout.getRegularWarpMenuButton();
69 |
70 | Pair configButtonIconDimensions = getTextureDimensions(configButton.getTextureLocation());
71 | configButton.setTextureDimensions(configButtonIconDimensions.getLeft(), configButtonIconDimensions.getRight());
72 | Pair regularWarpMenuButtonIconDimensions = getTextureDimensions(regularWarpMenuButton.getTextureLocation());
73 | regularWarpMenuButton.setTextureDimensions(regularWarpMenuButtonIconDimensions.getLeft(), regularWarpMenuButtonIconDimensions.getRight());
74 |
75 | // Island texture dimensions and hover effect texture
76 | for (Island island : layout.getIslandList()) {
77 | Pair islandTextureDimensions;
78 |
79 | island.setTextureLocation();
80 | islandTextureDimensions = getTextureDimensions(island.getTextureLocation());
81 | island.setTextureDimensions(islandTextureDimensions.getLeft(), islandTextureDimensions.getRight());
82 |
83 | if (island.getHoverEffectTexturePath() != null) {
84 | island.setHoverEffectTextureLocation();
85 | }
86 | }
87 |
88 | return layout;
89 | } catch (RuntimeException e) {
90 | boolean fatal = FancyWarpMenuState.getOverworldLayout() == null;
91 |
92 | handleResourceLoadException(layoutResource, fatal, e);
93 | return null;
94 | }
95 | } catch (IOException e) {
96 | boolean fatal = FancyWarpMenuState.getOverworldLayout() == null;
97 |
98 | handleGetResourceException(resourceLocation.toString(), fatal, e);
99 | return null;
100 | }
101 | }
102 |
103 | private static Pair getTextureDimensions(ResourceLocation resourceLocation) {
104 | IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
105 |
106 | try (InputStream textureStream = resourceManager.getResource(resourceLocation).getInputStream()) {
107 | BufferedImage bufferedImage = TextureUtil.readBufferedImage(textureStream);
108 | return Pair.of(bufferedImage.getWidth(), bufferedImage.getHeight());
109 | } catch (IOException e) {
110 | throw new ReportedException(CrashReport.makeCrashReport(e,
111 | String.format("Failed to read texture \"%s\"", resourceLocation)));
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/resourceloaders/ResourceLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.resourceloaders;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.utils.ChatUtils;
27 | import com.google.gson.Gson;
28 | import com.google.gson.GsonBuilder;
29 | import net.minecraft.client.Minecraft;
30 | import net.minecraft.client.resources.IResource;
31 | import net.minecraft.client.resources.ResourcePackRepository;
32 | import net.minecraft.crash.CrashReport;
33 | import net.minecraft.crash.CrashReportCategory;
34 | import net.minecraft.util.ReportedException;
35 | import org.apache.logging.log4j.LogManager;
36 | import org.apache.logging.log4j.Logger;
37 |
38 | import java.io.IOException;
39 |
40 | // TODO: Localize long error messages?
41 | public abstract class ResourceLoader {
42 | public static final Gson gson = new GsonBuilder()
43 | .setPrettyPrinting()
44 | .create();
45 | protected static final Logger logger = LogManager.getLogger();
46 |
47 | protected static void handleResourceLoadException(IResource resource, boolean fatal, RuntimeException e) {
48 | ResourcePackRepository.Entry resourcePackEntry = Minecraft.getMinecraft().getResourcePackRepository().getRepositoryEntries().stream().filter(
49 | entry -> entry.getResourcePackName().equals(resource.getResourcePackName())).findFirst().orElse(null);
50 | String resourcePackName;
51 | String resourcePackDescription;
52 |
53 | if (resourcePackEntry != null) {
54 | resourcePackName = resource.getResourcePackName();
55 | resourcePackDescription = resourcePackEntry.getTexturePackDescription();
56 | } else {
57 | resourcePackName = FancyWarpMenu.getInstance().getModContainer().getName() + " " + FancyWarpMenu.getInstance().getModContainer().getVersion();
58 | resourcePackDescription = "Built-in resource pack";
59 | }
60 |
61 | if (!fatal) {
62 | StringBuilder stringBuilder = new StringBuilder("Your Fancy Warp Menu resource pack may be outdated.");
63 | stringBuilder.append("\n").append(String.format("Resource loading failed: %s", e.getMessage()));
64 | stringBuilder.append("\n").append(String.format("Resource Path: %s", resource.getResourceLocation().toString()));
65 | stringBuilder.append("\n").append("Resource Pack Details:");
66 | stringBuilder.append("\n").append("Name: ").append(resourcePackName);
67 | stringBuilder.append("\n").append("Description: ").append(resourcePackDescription);
68 |
69 | if (resourcePackEntry != null) {
70 | stringBuilder.append("\n").append("File: ").append(resourcePackEntry);
71 | }
72 |
73 | logger.error(stringBuilder, e);
74 |
75 | if (Minecraft.getMinecraft().ingameGUI != null) {
76 | ChatUtils.sendErrorMessageWithCopyableThrowable(stringBuilder.toString(), e);
77 | }
78 | } else {
79 | CrashReport crashReport = new CrashReport("Your Fancy Warp Menu resource pack may be outdated", e);
80 | CrashReportCategory resourceDetails = crashReport.makeCategory("Resource");
81 | CrashReportCategory resourcePackDetails = crashReport.makeCategory("Resource Pack");
82 |
83 | resourceDetails.addCrashSection("Path", resource.getResourceLocation().toString());
84 |
85 | resourcePackDetails.addCrashSection("Name", resourcePackName);
86 | resourcePackDetails.addCrashSection("Description", resourcePackDescription);
87 |
88 | if (resourcePackEntry != null) {
89 | resourcePackDetails.addCrashSection("File", resourcePackEntry.toString());
90 | }
91 |
92 | throw new ReportedException(crashReport);
93 | }
94 | }
95 |
96 | protected static void handleGetResourceException(String resourcePath, boolean fatal, IOException e) {
97 | if (!fatal) {
98 | StringBuilder stringBuilder = new StringBuilder("Your Fancy Warp Menu resource pack may be outdated.");
99 | stringBuilder.append("\n").append(String.format("Resource loading failed: %s", e.getMessage()));
100 | stringBuilder.append("\n").append(String.format("Resource Path: %s", resourcePath));
101 |
102 | logger.error(stringBuilder, e);
103 |
104 | if (Minecraft.getMinecraft().ingameGUI != null) {
105 | ChatUtils.sendErrorMessageWithCopyableThrowable(stringBuilder.toString(), e);
106 | }
107 | } else {
108 | CrashReport crashReport = new CrashReport("Your Fancy Warp Menu resource pack may be outdated", e);
109 | CrashReportCategory resourceDetails = crashReport.makeCategory("Resource");
110 | resourceDetails.addCrashSection("Path", resourcePath);
111 | throw new ReportedException(crashReport);
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/resourceloaders/SkyBlockConstantsLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.resourceloaders;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.SkyBlockConstants;
27 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.ItemMatchCondition;
28 | import com.google.gson.stream.JsonReader;
29 | import net.minecraft.client.Minecraft;
30 | import net.minecraft.client.resources.IResource;
31 | import net.minecraft.util.ResourceLocation;
32 |
33 | import java.io.IOException;
34 | import java.io.InputStream;
35 | import java.io.InputStreamReader;
36 | import java.util.Comparator;
37 | import java.util.List;
38 |
39 | public class SkyBlockConstantsLoader extends ResourceLoader {
40 | private static final ResourceLocation SKY_BLOCK_CONSTANTS_LOCATION = new ResourceLocation("fancywarpmenu",
41 | "data/skyBlockConstants.jsonc");
42 |
43 | /**
44 | * Creates a {@link SkyBlockConstants} instance from {@code SKY_BLOCK_CONSTANTS_LOCATION}.
45 | * Match conditions in {@code SkyBlockConstants#menuMatchingMap} are sorted by ascending item slot index.
46 | *
47 | * @return the created {@code SkyBlockConstants} instance
48 | */
49 | public static SkyBlockConstants loadSkyBlockConstants() {
50 | try {
51 | IResource skyBlockConstantsResource = Minecraft.getMinecraft().getResourceManager().getResource(SKY_BLOCK_CONSTANTS_LOCATION);
52 |
53 | try (InputStream stream = skyBlockConstantsResource.getInputStream();
54 | JsonReader reader = new JsonReader(new InputStreamReader(stream))) {
55 | SkyBlockConstants skyBlockConstants = gson.fromJson(reader, SkyBlockConstants.class);
56 |
57 | for (List matchConditionList : skyBlockConstants.getMenuMatchingMap().values()) {
58 | matchConditionList.sort(Comparator.comparing(ItemMatchCondition::getInventorySlotIndex));
59 | }
60 |
61 | SkyBlockConstants.validateSkyBlockConstants(skyBlockConstants);
62 |
63 | return skyBlockConstants;
64 | } catch (RuntimeException e) {
65 | boolean fatal = FancyWarpMenu.getSkyBlockConstants() == null;
66 |
67 | handleResourceLoadException(skyBlockConstantsResource, fatal, e);
68 | return null;
69 | }
70 | } catch (IOException e) {
71 | boolean fatal = FancyWarpMenu.getSkyBlockConstants() == null;
72 |
73 | handleGetResourceException(SKY_BLOCK_CONSTANTS_LOCATION.toString(), fatal, e);
74 | return null;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/state/EnvironmentDetails.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.state;
24 |
25 | /**
26 | * Information about the local environment at runtime, for constants and compatibility with other mods
27 | */
28 | public class EnvironmentDetails {
29 | public static final String SUPPORT_LINK = "https://discord.gg/tXFf9umfA9";
30 | private static boolean deobfuscatedEnvironment;
31 | /**
32 | * Whether the Sk1er Patcher mod is installed. Patcher's GUI scale feature causes the Fancy Warp Menu to not be
33 | * scaled properly so the menu must be initialized differently when Patcher is present.
34 | * */
35 | private static boolean patcherInstalled;
36 |
37 | private EnvironmentDetails() {
38 | }
39 |
40 | public static boolean isDeobfuscatedEnvironment() {
41 | return deobfuscatedEnvironment;
42 | }
43 |
44 | public static boolean isPatcherInstalled() {
45 | return patcherInstalled;
46 | }
47 |
48 | public static void setDeobfuscatedEnvironment(boolean deobfuscatedEnvironment) {
49 | EnvironmentDetails.deobfuscatedEnvironment = deobfuscatedEnvironment;
50 | }
51 |
52 | public static void setPatcherInstalled(boolean patcherInstalled) {
53 | EnvironmentDetails.patcherInstalled = patcherInstalled;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/state/FancyWarpMenuState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.state;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Layout;
26 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.Menu;
27 | import ca.tirelesstraveler.fancywarpmenu.gui.GuiFancyWarp;
28 | import net.minecraft.client.Minecraft;
29 |
30 | /**
31 | * This class stores the current state of the Fancy Warp Menu.
32 | */
33 | public class FancyWarpMenuState {
34 | private static Layout overworldLayout;
35 | private static Layout riftLayout;
36 | private static boolean openConfigMenuRequested;
37 |
38 | /**
39 | * Gets the layout corresponding to the given SkyBlock menu.
40 | *
41 | * @param menu the SkyBlock menu to get a layout for
42 | * @return {@code riftLayout} if {@code Menu.PORHTAL} is provided, {@code overworldLayout} otherwise
43 | */
44 | public static Layout getLayoutForMenu(Menu menu) {
45 | if (menu == Menu.PORHTAL) {
46 | return getRiftLayout();
47 | } else {
48 | return getOverworldLayout();
49 | }
50 | }
51 |
52 | public static Layout getOverworldLayout() {
53 | return overworldLayout;
54 | }
55 |
56 | public static Layout getRiftLayout() {
57 | return riftLayout;
58 | }
59 |
60 | public static boolean isFancyWarpMenuOpen() {
61 | return Minecraft.getMinecraft().currentScreen instanceof GuiFancyWarp;
62 | }
63 |
64 | public static boolean isOpenConfigMenuRequested() {
65 | return openConfigMenuRequested;
66 | }
67 |
68 | public static void setOverworldLayout(Layout overworldLayout) {
69 | FancyWarpMenuState.overworldLayout = overworldLayout;
70 | }
71 |
72 | public static void setRiftLayout(Layout riftLayout) {
73 | FancyWarpMenuState.riftLayout = riftLayout;
74 | }
75 |
76 | public static void setOpenConfigMenuRequested(boolean openConfigMenuRequested) {
77 | FancyWarpMenuState.openConfigMenuRequested = openConfigMenuRequested;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/state/GameState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.state;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
26 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.Menu;
27 |
28 | /**
29 | * This class stores information about the state of the SkyBlock game the player is currently in.
30 | */
31 | public class GameState {
32 | /**
33 | * Whether the player is currently on SkyBlock
34 | */
35 | private static boolean onSkyBlock;
36 | /**
37 | * The current stage of the in-game season, can be "Early", mid (null), or "Late".
38 | */
39 | private static String seasonStage;
40 | /**
41 | * The current in-game season
42 | */
43 | private static String season;
44 | /**
45 | * Current in-game menu the player has open
46 | */
47 | private static Menu currentMenu;
48 |
49 | public static boolean isOnSkyBlock() {
50 | return onSkyBlock || Settings.shouldSkipSkyBlockCheck();
51 | }
52 |
53 | public static void setOnSkyBlock(boolean onSkyBlock) {
54 | GameState.onSkyBlock = onSkyBlock;
55 | }
56 |
57 | public static String getSeasonStage() {
58 | return seasonStage;
59 | }
60 |
61 | public static void setSeasonStage(String seasonStage) {
62 | GameState.seasonStage = seasonStage;
63 | }
64 |
65 | public static String getSeason() {
66 | return season;
67 | }
68 |
69 | public static void setSeason(String season) {
70 | GameState.season = season;
71 | }
72 |
73 | public static Menu getCurrentMenu() {
74 | return currentMenu;
75 | }
76 |
77 | public static void setCurrentMenu(Menu currentMenu) {
78 | GameState.currentMenu = currentMenu;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/utils/ChatUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.utils;
24 |
25 | import net.minecraft.client.Minecraft;
26 | import net.minecraft.event.ClickEvent;
27 | import net.minecraft.event.HoverEvent;
28 | import net.minecraft.util.*;
29 | import org.apache.commons.lang3.exception.ExceptionUtils;
30 |
31 | public class ChatUtils {
32 | public static final String COPY_TO_CLIPBOARD_TRANSLATION_KEY = "fancywarpmenu.gui.buttons.copyToClipboard";
33 |
34 | /**
35 | * Sends a client-side chat message with a warning message and a clickable component used to copy the stacktrace of
36 | * the given throwable.
37 | *
38 | * @param warningMessageTranslationKey translation key of the warning message to be displayed before the clickable component
39 | * @param throwable the throwable to be copied when the prompt is clicked
40 | */
41 | public static void sendWarningMessageWithCopyableThrowable(String warningMessageTranslationKey, Throwable throwable) {
42 | ChatStyle errorMessageStyle = new ChatStyle().setColor(EnumChatFormatting.GOLD);
43 | sendMessageWithCopyableThrowable(warningMessageTranslationKey, errorMessageStyle, throwable);
44 | }
45 |
46 | /**
47 | * Sends a client-side chat message with an error message and a clickable component used to copy the stacktrace of
48 | * the given throwable.
49 | *
50 | * @param errorMessageTranslationKey translation key of the error message to be displayed before the clickable component
51 | * @param throwable the throwable to be copied when the prompt is clicked
52 | */
53 | public static void sendErrorMessageWithCopyableThrowable(String errorMessageTranslationKey, Throwable throwable) {
54 | ChatStyle errorMessageStyle = new ChatStyle().setColor(EnumChatFormatting.RED);
55 | sendMessageWithCopyableThrowable(errorMessageTranslationKey, errorMessageStyle, throwable);
56 | }
57 |
58 | /**
59 | * Sends a client-side chat message with the mod name acronym as a prefix.
60 | *
61 | * Example: [FWM] message
62 | *
63 | * @param message the message to send
64 | */
65 | public static void sendMessageWithModNamePrefix(String message) {
66 | sendMessageWithModNamePrefix(new ChatComponentText(message));
67 | }
68 |
69 | /**
70 | * Sends a client-side chat message with the mod name acronym as a prefix.
71 | *
72 | * Example: [FWM] message
73 | *
74 | * @param message the message to send
75 | */
76 | public static void sendMessageWithModNamePrefix(IChatComponent message) {
77 | IChatComponent prefixComponent = createModNamePrefixComponent();
78 | prefixComponent.appendSibling(message);
79 | Minecraft.getMinecraft().thePlayer.addChatMessage(prefixComponent);
80 | }
81 |
82 | /**
83 | * Returns an {@code IChatComponent} with the acronym of the mod name ("FWM") to be used as a prefix in chat messages
84 | * sent by the mod
85 | *
86 | * @return an {@code IChatComponent} with the acronym of the mod name ("FWM") to be used as a prefix in chat messages
87 | * sent by the mod
88 | */
89 | private static IChatComponent createModNamePrefixComponent() {
90 | ChatStyle plainStyle = new ChatStyle().setColor(EnumChatFormatting.RESET);
91 | ChatStyle acronymStyle = new ChatStyle()
92 | .setColor(EnumChatFormatting.LIGHT_PURPLE)
93 | .setChatHoverEvent(
94 | new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText("Fancy Warp Menu")));
95 |
96 | return new ChatComponentText("[")
97 | .appendSibling(new ChatComponentText("FWM").setChatStyle(acronymStyle))
98 | .appendSibling(new ChatComponentText("] ").setChatStyle(plainStyle));
99 | }
100 |
101 | /**
102 | * Sends a client-side chat message with a clickable component used to copy the stacktrace of a given throwable.
103 | *
104 | * @param messageTranslationKey translation key of the message to be displayed before the clickable component
105 | * @param messageStyle the {@link ChatStyle} to assign to the {@code IChatComponent} containing the message
106 | * @param throwable the throwable to be copied when the prompt is clicked
107 | */
108 | private static void sendMessageWithCopyableThrowable(String messageTranslationKey, ChatStyle messageStyle, Throwable throwable) {
109 | if (messageTranslationKey == null) {
110 | throw new NullPointerException("messageTranslationKey cannot be null");
111 | } else if (messageStyle == null) {
112 | throw new NullPointerException("messageStyle cannot be null");
113 | } else if (throwable == null) {
114 | throw new NullPointerException("throwable cannot be null");
115 | }
116 |
117 | ChatStyle plainStyle = new ChatStyle().setColor(EnumChatFormatting.RESET);
118 | // setInsertion gives the component a unique identifier for ca.tirelesstraveler.fancywarpmenu.listeners.ChatListener to look for
119 | ChatStyle copyThrowableStyle = new ChatStyle().setColor(EnumChatFormatting.BLUE)
120 | .setInsertion(messageTranslationKey)
121 | .setChatClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, ExceptionUtils.getStackTrace(throwable)));
122 |
123 | IChatComponent chatComponent = createModNamePrefixComponent()
124 | .appendSibling(new ChatComponentTranslation(messageTranslationKey).setChatStyle(messageStyle))
125 | .appendSibling(new ChatComponentText(" [").setChatStyle(plainStyle))
126 | .appendSibling(new ChatComponentTranslation(COPY_TO_CLIPBOARD_TRANSLATION_KEY).setChatStyle(copyThrowableStyle))
127 | .appendSibling(new ChatComponentText("]").setChatStyle(plainStyle));
128 | Minecraft.getMinecraft().thePlayer.addChatMessage(chatComponent);
129 | }
130 | }
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/utils/GameChecks.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.utils;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu;
26 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
27 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.Menu;
28 | import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.menu.ItemMatchCondition;
29 | import ca.tirelesstraveler.fancywarpmenu.state.GameState;
30 | import net.minecraft.client.Minecraft;
31 | import net.minecraft.inventory.IInventory;
32 | import net.minecraft.scoreboard.Score;
33 | import net.minecraft.scoreboard.Scoreboard;
34 | import org.apache.logging.log4j.LogManager;
35 | import org.apache.logging.log4j.Logger;
36 |
37 | import java.util.ArrayList;
38 | import java.util.List;
39 | import java.util.regex.Matcher;
40 | import java.util.regex.Pattern;
41 |
42 | /**
43 | * This class contains utility methods that determine the values to save in {@link ca.tirelesstraveler.fancywarpmenu.state.GameState}
44 | * from the current state of the SkyBlock server the player is in.
45 | */
46 | public class GameChecks {
47 | private static final Logger logger = LogManager.getLogger();
48 | private static final Matcher seasonMatcher =
49 | Pattern.compile("(?Late|Early)? ?(?[a-zA-Z]+) \\d{1,2}.*").matcher("");
50 |
51 | /**
52 | * Checks the current SkyBlock season and saves using {@link GameState#setSeason(String)}.
53 | */
54 | public static void checkSeason() {
55 | // Don't run outside of SB to prevent exceptions
56 | if (!Settings.shouldSkipSkyBlockCheck()) {
57 | try {
58 | Scoreboard sb = Minecraft.getMinecraft().theWorld.getScoreboard();
59 | // SkyBlock sidebar objective
60 | ArrayList scores = (ArrayList) sb.getSortedScores(sb.getObjectiveInDisplaySlot(1));
61 |
62 | // The date is always near the top (highest score) so we iterate backwards.
63 | for (int i = scores.size(); i > 0; i--) {
64 | Score score = scores.get(i - 1);
65 | String skyBlockScoreboardLine =
66 | sb.getPlayersTeam(score.getPlayerName()).formatString("").trim();
67 |
68 | seasonMatcher.reset(skyBlockScoreboardLine);
69 |
70 | if (seasonMatcher.matches()) {
71 | String seasonStage = seasonMatcher.group("seasonStage");
72 | String season = seasonMatcher.group("season");
73 |
74 | GameState.setSeasonStage(seasonStage);
75 |
76 | if (season != null) {
77 | GameState.setSeason(season);
78 | return;
79 | }
80 | }
81 | }
82 |
83 | GameState.setSeasonStage(null);
84 | GameState.setSeason(null);
85 | } catch (RuntimeException e) {
86 | logger.warn("Failed to check scoreboard season", e);
87 | }
88 | }
89 | }
90 |
91 | /**
92 | * Determines which SkyBlock {@code GuiChest} menu the player is in using the {@link net.minecraft.client.gui.inventory.GuiChest}
93 | * display name. This is used for initial checks when the items haven't loaded in yet.
94 | *
95 | * @param chestInventory the inventory of the chest holding the menu
96 | * @return a {@code Menu} value representing the current menu the player has open
97 | */
98 | public static Menu determineOpenMenu(IInventory chestInventory) {
99 | if (chestInventory.hasCustomName()) {
100 | String chestTitle = chestInventory.getDisplayName().getUnformattedText();
101 |
102 | for (Menu menu : FancyWarpMenu.getSkyBlockConstants().getMenuMatchingMap().keySet()) {
103 | if (chestTitle.equals(menu.getMenuDisplayName())) {
104 | return menu;
105 | }
106 | }
107 | }
108 |
109 | return Menu.NONE;
110 | }
111 |
112 | /**
113 | * Determines if the player is in the given menu by checking whether all the {@link ItemMatchCondition}s for that menu
114 | * match the given inventory. This should be used after the inventory has loaded the slot index returned by
115 | * {@link ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.SkyBlockConstants#getLastMatchConditionInventorySlotIndex(Menu)}.
116 | * If a match is found, the matched menu is saved using {@link GameState#setCurrentMenu(Menu)}
117 | *
118 | * @param menu the {@code Menu} whose match conditions will be checked
119 | * @param chestInventory the inventory to check against the match conditions
120 | * @return {@code true} if all the {@link ItemMatchCondition}s match, {@code false} otherwise
121 | */
122 | public static boolean menuItemsMatch(Menu menu, IInventory chestInventory) {
123 | List matchConditions = FancyWarpMenu.getSkyBlockConstants().getMenuMatchingMap().get(menu);
124 |
125 | for (ItemMatchCondition matchCondition : matchConditions) {
126 | logger.debug("Starting item match on slot {} for menu {}.",
127 | matchCondition.getInventorySlotIndex(), menu);
128 |
129 | if (!matchCondition.inventoryContainsMatchingItem(chestInventory)) {
130 | logger.warn("Item match on slot {} failed.", matchCondition.getInventorySlotIndex());
131 | GameState.setCurrentMenu(Menu.NONE);
132 | return false;
133 | }
134 | logger.debug("Finished item match on slot {} for menu {}.",
135 | matchCondition.getInventorySlotIndex(), menu);
136 | }
137 |
138 | GameState.setCurrentMenu(menu);
139 | return true;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/main/java/ca/tirelesstraveler/fancywarpmenu/utils/WarpVisibilityChecks.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024. TirelessTraveler
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | * OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | package ca.tirelesstraveler.fancywarpmenu.utils;
24 |
25 | import ca.tirelesstraveler.fancywarpmenu.data.Settings;
26 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Island;
27 | import ca.tirelesstraveler.fancywarpmenu.data.layout.Warp;
28 | import ca.tirelesstraveler.fancywarpmenu.state.GameState;
29 |
30 | import java.util.List;
31 |
32 | /**
33 | * Checks used to control the visibility of warps on the fancy warp menu
34 | */
35 | public class WarpVisibilityChecks {
36 |
37 | /**
38 | * Checks if the given island with a singular warp should be shown on the fancy warp menu. Throws
39 | * {@link IllegalArgumentException} if the island has multiple warps.
40 | *
41 | * @param island the island to check
42 | * @return {@code true} if the island should be visible, {@code false} if it should be hidden
43 | */
44 | public static boolean shouldShowSingleWarpIsland(Island island) {
45 | if (island.getWarpCount() > 1) {
46 | throw new IllegalArgumentException("Island has more than one warp");
47 | }
48 |
49 | return shouldShowWarp(island.getWarps().get(0));
50 | }
51 |
52 | /**
53 | * Checks if a warp should be shown on the fancy warp menu.
54 | *
55 | * @param warp the warp to check
56 | * @return {@code true} if the warp should be visible, {@code false} if it should be hidden
57 | */
58 | public static boolean shouldShowWarp(Warp warp) {
59 | List warpTags = warp.getTags();
60 |
61 | if (warpTags != null && !warpTags.isEmpty()) {
62 | for (String tag : warpTags) {
63 | if (!shouldShowWarpWithTag(tag)) {
64 | return false;
65 | }
66 | }
67 | }
68 |
69 | return true;
70 | }
71 |
72 | /**
73 | * Checks if warps with the given tag should be shown on the fancy warp menu
74 | *
75 | * @param tag the categorization tag to check
76 | * @return {@code true} if warps with this tag should be visible, {@code false} if they should be hidden
77 | */
78 | private static boolean shouldShowWarpWithTag(String tag) {
79 | switch (tag) {
80 | case "bingo":
81 | return !Settings.shouldHideUnobtainableWarps();
82 | case "jerry":
83 | if (Settings.isDebugModeEnabled() && Settings.shouldAlwaysShowJerryIsland()) {
84 | return true;
85 | }
86 |
87 | if (!Settings.shouldShowJerryIsland()) {
88 | return false;
89 | }
90 |
91 | String season = GameState.getSeason();
92 | String seasonStage = GameState.getSeasonStage();
93 |
94 | return season != null && seasonStage != null && season.equals("Winter") && seasonStage.equals("Late");
95 | default:
96 | return true;
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/data/riftLayout.json:
--------------------------------------------------------------------------------
1 | {
2 | "islandList": [
3 | {
4 | "name": "Rift",
5 | "texturePath": "textures/gui/islands/Rift.png",
6 | "gridX": 21,
7 | "gridY": 6,
8 | "zLevel": 0,
9 | "widthPercentage": 0.35,
10 | "warpList": [
11 | {
12 | "displayName": "Wizard Tower",
13 | "slotIndex": 10,
14 | "gridX": 18,
15 | "gridY": 25
16 | },
17 | {
18 | "displayName": "Lagoon Hut",
19 | "slotIndex": 11,
20 | "gridX": 8,
21 | "gridY": 23
22 | },
23 | {
24 | "displayName": "Dreadfarm",
25 | "slotIndex": 12,
26 | "gridX": 18,
27 | "gridY": 11
28 | },
29 | {
30 | "displayName": "Plaza",
31 | "slotIndex": 13,
32 | "gridX": 22,
33 | "gridY": 19
34 | },
35 | {
36 | "displayName": "Colosseum",
37 | "slotIndex": 14,
38 | "gridX": 11,
39 | "gridY": 18
40 | },
41 | {
42 | "displayName": "Stillgore Château",
43 | "slotIndex": 15,
44 | "gridX": 31,
45 | "gridY": 28
46 | }
47 | ]
48 | }
49 | ],
50 | "warpIcon": {
51 | "texturePath": "textures/gui/Portal.png",
52 | "widthPercentage": 0.02
53 | },
54 | "configButton": {
55 | "gridX": 60,
56 | "gridY": 31,
57 | "widthPercentage": 0.05
58 | },
59 | "regularWarpMenuButton": {
60 | "gridX": 60,
61 | "gridY": 29,
62 | "widthPercentage": 0.05
63 | }
64 | }
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/data/skyBlockConstants.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "menuMatchingMap": {
3 | "FAST_TRAVEL": [
4 | {
5 | "inventorySlotIndex": 45,
6 | "itemName": "Island Browser",
7 | "minecraftItemID": "minecraft:blaze_powder"
8 | },
9 | {
10 | "inventorySlotIndex": 49,
11 | "itemName": "Close",
12 | "minecraftItemID": "minecraft:barrier"
13 | },
14 | {
15 | "inventorySlotIndex": 53,
16 | "itemName": "Paper Icons",
17 | /* The item ID changes depending on whether the player has paper icons enabled */
18 | "minecraftItemIDs": [
19 | "minecraft:map",
20 | "minecraft:filled_map"
21 | ]
22 | }
23 | ],
24 | "PORHTAL": [
25 | {
26 | "inventorySlotIndex": 31,
27 | "itemName": "Close",
28 | "minecraftItemID": "minecraft:barrier"
29 | }
30 | ]
31 | },
32 | "warpMessages": {
33 | "warpSuccessMessages": [
34 | "Warping..."
35 | ],
36 | "warpFailMessages": {
37 | "Unknown destination! Check the Fast Travel menu to view options!": "fancywarpmenu.errors.unknownDestination",
38 | "You haven't unlocked this fast travel destination!": "fancywarpmenu.errors.notUnlocked",
39 | "Couldn't warp you! Try again later. (NO_DESTINATION_FOUND)": "fancywarpmenu.errors.noDestination",
40 | "You need to have visited this island at least once before fast traveling to it!": "fancywarpmenu.errors.notVisited",
41 | "Jerry's Workshop is only available during the Winter!": "fancywarpmenu.errors.notOpenYet"
42 | }
43 | },
44 | "warpCommandVariants": [
45 | {
46 | "command": "warp",
47 | "type": "ALIAS"
48 | },
49 | {
50 | "command": "travel",
51 | "type": "ALIAS"
52 | },
53 | {
54 | "command": "is",
55 | "type": "WARP"
56 | },
57 | {
58 | "command": "hub",
59 | "type": "WARP"
60 | },
61 | {
62 | "command": "warpforge",
63 | "type": "WARP"
64 | },
65 | {
66 | "command": "savethejerrys",
67 | "type": "WARP"
68 | },
69 | {
70 | "command": "garry",
71 | "type": "WARP"
72 | }
73 | ]
74 | }
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/lang/en_US.lang:
--------------------------------------------------------------------------------
1 | fancywarpmenu.config.categories.general=General
2 | fancywarpmenu.config.categories.general.tooltip=Settings that customize the functionality of the fancy warp menu
3 | fancywarpmenu.config.categories.developerSettings=Developer Settings
4 | fancywarpmenu.config.categories.developerSettings.tooltip=Settings for features used by pack developers to create custom textures and layouts for the fancy warp menu
5 | fancywarpmenu.config.categories.support=Support
6 | fancywarpmenu.config.categories.support.tooltip=Click to join the Fancy Warp Menu Discord server
7 | fancywarpmenu.config.categories.updateAvailable=Update Available
8 | fancywarpmenu.config.categories.updateAvailable.tooltip=There is a new version of Fancy Warp Menu available. Click for more details.
9 |
10 | fancywarpmenu.config.title=Fancy Warp Menu Settings
11 | fancywarpmenu.config.subtitle=Categories
12 | fancywarpmenu.config.warpMenuEnabled=Enable Fancy Warp Menu
13 | fancywarpmenu.config.warpMenuEnabled.tooltip=Replace the default warp menu with the fancy warp menu
14 | fancywarpmenu.config.showIslandLabels=Show Island Names
15 | fancywarpmenu.config.showIslandLabels.tooltip=Show each island's name below its picture
16 | fancywarpmenu.config.hideWarpLabelsUntilIslandHovered=Hide Warp Labels Until Island Hovered
17 | fancywarpmenu.config.hideWarpLabelsUntilIslandHovered.tooltip=Hide the island's warp button labels until the mouse is hovering over the island
18 | fancywarpmenu.config.hideWarpLabelForIslandsWithOneWarp=Hide Warp Label for One Warp Islands
19 | fancywarpmenu.config.hideWarpLabelForIslandsWithOneWarp.tooltip=Hide warp label for islands with only one warp
20 | fancywarpmenu.config.suggestWarpMenuOnWarpCommand=Reminders to Use Fancy Warp Menu
21 | fancywarpmenu.config.suggestWarpMenuOnWarpCommand.tooltip=Show reminders to use the fancy warp menu when the player uses a warp command
22 | fancywarpmenu.config.addWarpCommandToChatHistory=Add Warp Command to Chat History
23 | fancywarpmenu.config.addWarpCommandToChatHistory.tooltip=Add warp commands sent by the fancy warp menu to your chat history
24 | fancywarpmenu.config.showJerryIsland=Show Jerry's Workshop
25 | fancywarpmenu.config.showJerryIsland.tooltip=Show the Jerry's Workshop island on the fancy warp menu
26 | fancywarpmenu.config.hideUnobtainableWarps=Hide Unobtainable Warps
27 | fancywarpmenu.config.hideUnobtainableWarps.tooltip=Hide warps only obtainable during special game modes such as Bingo
28 | fancywarpmenu.config.enableUpdateNotification=Enable Update Notification
29 | fancywarpmenu.config.enableUpdateNotification.tooltip=Show a notification on the settings button and in the settings menu when a new version of Fancy Warp Menu is available
30 | fancywarpmenu.config.showRegularWarpMenuButton=Show Regular Warp Menu Button
31 | fancywarpmenu.config.showRegularWarpMenuButton.tooltip=Show the button to access the regular warp menu
32 |
33 | fancywarpmenu.config.developerModeEnabled=Enable Developer Mode
34 | fancywarpmenu.config.developerModeEnabled.tooltip=Enable all developer features
35 | fancywarpmenu.config.showDebugOverlay=Show Debug Overlay
36 | fancywarpmenu.config.showDebugOverlay.tooltip=Show an overlay with coordinate values and button borders over the fancy warp menu. Press TAB while the warp menu is open to toggle.
37 | fancywarpmenu.config.drawBorders=Draw Button Borders
38 | fancywarpmenu.config.drawBorders.tooltip=Show borders around island and warp buttons. Press B while the fancy warp menu is open to toggle.
39 | fancywarpmenu.config.skipSkyBlockCheck=Skip SkyBlock Check
40 | fancywarpmenu.config.skipSkyBlockCheck.tooltip=Skip checking for whether the player is on SkyBlock
41 | fancywarpmenu.config.alwaysShowJerryIsland=Always Show Jerry's Workshop
42 | fancywarpmenu.config.alwaysShowJerryIsland.tooltip=Always show Jerry's Workshop on the warp menu regardless of the value of the general > showJerryIsland setting and the in-game season
43 |
44 | fancywarpmenu.gui.buttons.config=Config
45 | fancywarpmenu.gui.buttons.copyToClipboard=Copy to Clipboard
46 | fancywarpmenu.gui.buttons.copyToClipboard.copied=Copied!
47 | fancywarpmenu.gui.buttons.regularWarpMenu=Regular Warp Menu
48 |
49 | fancywarpmenu.key.openMenu=Open the Fancy Warp Menu
50 |
51 | fancywarpmenu.key.categories.fancyWarpMenu=Fancy Warp Menu
52 |
53 | fancywarpmenu.messages.useWarpMenuInsteadOfCommand=Reminder to use the Fancy Warp Menu instead!
54 | fancywarpmenu.messages.fancyWarpMenuEnabled=Fancy Warp Menu Enabled
55 | fancywarpmenu.messages.fancyWarpMenuDisabled=Fancy Warp Menu Disabled
56 |
57 | fancywarpmenu.errors.notUnlocked=Not Unlocked
58 | fancywarpmenu.errors.unknownDestination=Unknown Destination
59 | fancywarpmenu.errors.noDestination=No Destination Found
60 | fancywarpmenu.errors.notVisited=Visit Location to Unlock Warp
61 | fancywarpmenu.errors.notOpenYet=Not Open Yet
62 | fancywarpmenu.errors.slotNumberOutOfBounds=Invalid Slot Number (%d)
63 | fancywarpmenu.errors.slotHasNoItem=Slot %d Has No Item to Click On
64 | fancywarpmenu.errors.mouseIsHoldingItem=Mouse is Already Holding an Item
65 | fancywarpmenu.errors.fancyWarpGui.initFailed=%s Initialization Failed
66 | fancywarpmenu.errors.fancyWarpGui.chestInventoryTooSmall=Chest inventory size (%d) is smaller than expected (%d), falling back to vanilla chest UI
67 | fancywarpmenu.errors.fancyWarpGui.itemMatchFailed=Chest item match check failed, falling back to vanilla chest UI
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/Logo.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/Notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/Notification.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/Portal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/Portal.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/Regular Warp Menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/Regular Warp Menu.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Barn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Barn.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Crimson Isle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Crimson Isle.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Deep Caverns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Deep Caverns.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Dungeon Hub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Dungeon Hub.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/End.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/End.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Garden.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Garden.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Gold Mine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Gold Mine.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Hub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Hub.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Jerry's Workshop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Jerry's Workshop.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Mushroom Desert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Mushroom Desert.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Park.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Park.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Private Island.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Private Island.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Rift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Rift.png
--------------------------------------------------------------------------------
/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Spider's Den.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ILikePlayingGames/FancyWarpMenu/a8aab6c29521b954e042ed6ff44da2c32c7d12f8/src/main/resources/assets/fancywarpmenu/textures/gui/islands/Spider's Den.png
--------------------------------------------------------------------------------
/src/main/resources/mcmod.info:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "modid": "fancywarpmenu",
4 | "name": "Fancy Warp Menu",
5 | "description": "A recreation of the fancy warp menu from SkyblockAddons\\nSupport: https://discord.gg/tXFf9umfA9\\nLicenses: https://github.com/ILikePlayingGames/FancyWarpMenu/wiki/Licenses",
6 | "version": "${version}",
7 | "mcversion": "${mcversion}",
8 | "url": "https://github.com/ILikePlayingGames/FancyWarpMenu",
9 | "authorList": [
10 | "TirelessTraveler"
11 | ],
12 | "credits": "Nea89, SBA contributors, Schlaumeyer, Fandom SkyBlock Wiki",
13 | "logoFile": "assets/fancywarpmenu/textures/gui/Logo.png",
14 | "screenshots": [],
15 | "dependencies": []
16 | }
17 |
18 | ]
--------------------------------------------------------------------------------
/src/main/resources/version.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2024. TirelessTraveler
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in all
12 | # copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | # OR OTHER DEALINGS IN THE SOFTWARE.
21 | #
22 |
23 | # Forge expects a mod version in the main mod class or in this file, otherwise it logs a warning on startup.
24 | # suppress inspection "UnusedProperty"
25 | fancywarpmenu.version = ${version}
--------------------------------------------------------------------------------
/version/README.md:
--------------------------------------------------------------------------------
1 | # update.json
2 | This is a Forge Update Checker file, whose format is specified [here](https://docs.minecraftforge.net/en/1.20.x/misc/updatechecker/).
3 | The mod will fetch it on Minecraft startup to check if a new version is available.
--------------------------------------------------------------------------------
/version/update.json:
--------------------------------------------------------------------------------
1 | {
2 | "homepage": "https://github.com/ILikePlayingGames/FancyWarpMenu/releases",
3 | "promos": {
4 | "1.8.9-recommended": "1.0",
5 | "1.8.9-latest": "2.0-beta.1"
6 | },
7 | "1.8.9": {
8 | "1.0": "New textures and additional language support",
9 | "0.9.0+77": "Link update available button to GitHub releases"
10 | }
11 | }
--------------------------------------------------------------------------------