diff --git a/gradle.properties b/gradle.properties index 8d94d1d..922b5e9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,15 +3,15 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use - minecraft_version=1.16.3 - yarn_mappings=1.16.3+build.9 - loader_version=0.9.3+build.207 + minecraft_version=1.16.4 + yarn_mappings=1.16.4+build.7 + loader_version=0.10.8 # Mod Properties - mod_version = 0.1.3 + mod_version = 0.1.4 maven_group = pm.j4 archives_base_name = petroleum # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api - fabric_version=0.22.1+build.409-1.16 + fabric_version=0.28.1+1.16 diff --git a/remappedSrc/pm/j4/petroleum/PetroleumMod.java b/remappedSrc/pm/j4/petroleum/PetroleumMod.java new file mode 100644 index 0000000..ce543eb --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/PetroleumMod.java @@ -0,0 +1,168 @@ +package pm.j4.petroleum; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.fabricmc.loader.api.metadata.ModMetadata; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.options.KeyBinding; +import net.minecraft.server.integrated.IntegratedServer; +import pm.j4.petroleum.modules.ExampleModule; +import pm.j4.petroleum.modules.bindings.BindingManager; +import pm.j4.petroleum.modules.list.ModList; +import pm.j4.petroleum.modules.menu.ModMenu; +import pm.j4.petroleum.modules.splash.SplashText; +import pm.j4.petroleum.modules.xray.Xray; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.ModuleBase; + + +//TODO: +// petroleum module checklist +// [ ] xray (lol) +// [ ] combat stuff. killaura, anti knockback, etc +// [ ] render stuff. tracers, nametags +// [ ] wurst taco. but a fish +// [ ] elytra fly +// [ ] movement stuff. nofall, jesus, speed +// [ ] elytra bhop +// [ ] boatfly +// [ ] anti anti cheat + +/** + * The type Petroleum mod. + */ +public class PetroleumMod implements ModInitializer { + /** + * The Mod data. + */ + public static ModMetadata modData = null; + /** + * The constant client. + */ + private static MinecraftClient client; + /** + * The constant activeMods. + */ + private static final List activeMods = Arrays.asList( + new SplashText(), + new ModMenu(), + new ModList(), + new BindingManager(), + new ExampleModule(), + new Xray() + ); + + /** + * Is active boolean. + * + * @param modName the mod name + * @return the boolean + */ + public static boolean isActive(String modName) { + return activeMods.stream().anyMatch(mod -> mod.getModuleName().equals(modName)); + } + + /** + * Gets mod. + * + * @param modName the mod name + * @return the mod + */ + public static Optional getMod(String modName) { + return activeMods.stream().filter(mod -> mod.getModuleName().equals(modName)).findFirst(); + } + + /** + * Gets active mods. + * + * @return the active mods + */ + public static List getActiveMods() { + return activeMods; + } + + /** + * The constant registeredBinds. + */ + private static final List registeredBinds = new ArrayList<>(); + + /** + * Add bind. + * + * @param b the b + */ + public static void addBind(KeyBinding b) { + registeredBinds.add(b); + } + + /** + * Remove bind. + * + * @param b the b + */ + public static void removeBind(KeyBinding b) { + registeredBinds.remove(b); + } + + /** + * Gets active keybinds. + * + * @return the active keybinds + */ + public static List getActiveKeybinds() { + return registeredBinds; + } + + /** + * Gets server address. + * + * @return the server address + */ + public static String getServerAddress() { + if (client != null && client.getServer() != null) { + IntegratedServer server = client.getServer(); + if (!server.isRemote()) { + return "localhost"; + } + if (server.isRemote() && !server.getServerIp().isEmpty()) { + return server.getServerIp(); + } + } + return null; + } + + @Override + public void onInitialize() { + + ConfigManager.initConfig(); + + // always update mod data + Optional modContainer = FabricLoader.getInstance().getModContainer("petroleum"); + modContainer.ifPresent(container -> modData = container.getMetadata()); + + Optional conf = ConfigManager.getConfig(); + + + //initialize any keybinds, data, etc. + activeMods.forEach(ModuleBase::init); + + //initialize keybind handler + conf.ifPresent(configHolder -> ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (PetroleumMod.client != client) { + PetroleumMod.client = client; + } + for (KeyBinding b : PetroleumMod.getActiveKeybinds()) { + while (b.wasPressed()) { + configHolder.globalConfig.bindings.get(b).activate(client); + } + } + })); + } +} diff --git a/remappedSrc/pm/j4/petroleum/gui/PModMenuScreen.java b/remappedSrc/pm/j4/petroleum/gui/PModMenuScreen.java new file mode 100644 index 0000000..fbc9ec8 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/gui/PModMenuScreen.java @@ -0,0 +1,70 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import java.util.Map; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.TranslatableText; +import pm.j4.petroleum.modules.menu.ModMenu; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.data.ButtonInformation; +import pm.j4.petroleum.util.data.Category; + +/** + * The type P mod menu screen. + */ +public class PModMenuScreen extends Screen { + /** + * Instantiates a new P mod menu screen. + */ + public PModMenuScreen() { + super(new TranslatableText("petroleum.modmenu")); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.renderBackground(matrices); + super.render(matrices, mouseX, mouseY, delta); + } + + @Override + protected void init() { + Map coordinateMap = ModMenu.getButtons(); + coordinateMap.forEach((category, coord) -> { + this.addButton(new PMovableButton((int) (coord.x * this.width), + (int) (coord.y * this.height), + category, + Category.getByCategory(category), + coord.open, + this)); + }); + } + + @Override + public void onClose() { + if (ConfigManager.getConfig().isPresent()) { + ConfigManager.getConfig().get().disableModule("petroleum.modmenu"); + this.buttons.forEach(button -> ((PMovableButton) button).updateCoordinate()); + ConfigManager.saveGlobalConfig(); + } + super.onClose(); + } + + @Override + public void renderBackground(MatrixStack matrices) { + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + RenderSystem.enableBlend(); + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(0, this.height, 0.0D).color(0.1F, 0.1F, 0.1F, 0.3F).next(); + buffer.vertex(this.width, this.height, 0.0D).color(0.1F, 0.1F, 0.1F, 0.3F).next(); + buffer.vertex(this.width, 0, 0.0D).color(0.1F, 0.1F, 0.1F, 0.3F).next(); + buffer.vertex(0, 0, 0.0D).color(0.1F, 0.1F, 0.1F, 0.3F).next(); + t_1.draw(); + RenderSystem.disableBlend(); + } +} diff --git a/remappedSrc/pm/j4/petroleum/gui/PModuleConfigEntry.java b/remappedSrc/pm/j4/petroleum/gui/PModuleConfigEntry.java new file mode 100644 index 0000000..3125ed1 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/gui/PModuleConfigEntry.java @@ -0,0 +1,69 @@ +package pm.j4.petroleum.gui; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.widget.EntryListWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +import pm.j4.petroleum.util.module.option.BooleanOption; +import pm.j4.petroleum.util.module.option.ConfigurationOption; +import pm.j4.petroleum.util.module.option.ListOption; + +/** + * The type P module config entry. + */ +public class PModuleConfigEntry extends EntryListWidget.Entry { + /** + * The Option. + */ + protected final ConfigurationOption option; + /** + * The Display text. + */ + protected final Text displayText; + + /** + * Instantiates a new P module config entry. + * + * @param option the option + * @param text the text + */ + public PModuleConfigEntry(ConfigurationOption option, Text text) { + this.option = option; + this.displayText = text; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (this.isMouseOver(mouseX, mouseY)) { + return true; + } + return false; + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + if (this.displayText != null) { + MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, displayText, x, y, 0xAAAAAA); + } + if (this.option != null) { + //TODO option text box (?) + // option should be centered or otherwise offset + // but not extend past the side of the pane + int fontHeight = MinecraftClient.getInstance().textRenderer.fontHeight; + MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, new LiteralText(option.getDescription() + " " + option.getStringValue()), x, y + fontHeight + 4, 0xFFFFFF); + String className = option.getClass().toString(); + if (className == BooleanOption.class.toString()) { + // boolean button + } + else if (className == ListOption.class.toString()) { + // handle list + // TODO: determine whether list options are viable, + // considering that it would be easier to split lists into multiple PModuleConfigEntries + } + else { + // string button + } + } + } +} \ No newline at end of file diff --git a/remappedSrc/pm/j4/petroleum/gui/PModuleConfigPane.java b/remappedSrc/pm/j4/petroleum/gui/PModuleConfigPane.java new file mode 100644 index 0000000..31d6160 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/gui/PModuleConfigPane.java @@ -0,0 +1,115 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.widget.EntryListWidget; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; + +/** + * The type P module config pane. + */ +public class PModuleConfigPane extends EntryListWidget { + /** + * The Parent. + */ + private final POptionsScreen parent; + /** + * The Last selected. + */ + private POptionEntry lastSelected; + + /** + * Instantiates a new P module config pane. + * + * @param client the client + * @param width the width + * @param height the height + * @param top the top + * @param bottom the bottom + * @param entryHeight the entry height + * @param screen the screen + */ + public PModuleConfigPane(MinecraftClient client, int width, int height, int top, int bottom, int entryHeight, POptionsScreen screen) { + super(client, width, height, top, bottom, entryHeight); + this.parent = screen; + /** + * The Text renderer. + */ + TextRenderer textRenderer = client.textRenderer; + } + + @Override + public PModuleConfigEntry getSelected() { + return null; + } + + @Override + public int getRowWidth() { + return this.width - 10; + } + + @Override + protected int getScrollbarPositionX() { + return this.width - 6 + left; + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + POptionEntry selectedEntry = parent.getSelected(); + if (selectedEntry != lastSelected) { + lastSelected = selectedEntry; + clearEntries(); + setScrollAmount(-Double.MAX_VALUE); + String id = lastSelected.getModId(); + if (lastSelected != null && id != null && !id.isEmpty()) { + children().addAll(lastSelected.module.getConfigEntries()); + } + } + + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + + RenderSystem.depthFunc(515); + RenderSystem.disableDepthTest(); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GlStateManager.SrcFactor.SRC_ALPHA, + GlStateManager.DstFactor.ONE_MINUS_DST_ALPHA, + GlStateManager.SrcFactor.ZERO, + GlStateManager.DstFactor.ONE); + RenderSystem.disableAlphaTest(); + RenderSystem.shadeModel(7425); + RenderSystem.disableTexture(); + + buffer.begin(7, VertexFormats.POSITION_COLOR_TEXTURE); + buffer.vertex(this.left, (this.top + 4), 0.0D).texture(0.0F, 1.0F).color(0, 0, 0, 0).next(); + buffer.vertex(this.right, (this.top + 4), 0.0D).texture(1.0F, 1.0F).color(0, 0, 0, 0).next(); + buffer.vertex(this.right, this.top, 0.0D).texture(1.0F, 0.0F).color(0, 0, 0, 255).next(); + buffer.vertex(this.left, this.top, 0.0D).texture(0.0F, 0.0F).color(0, 0, 0, 255).next(); + buffer.vertex(this.left, this.bottom, 0.0D).texture(0.0F, 1.0F).color(0, 0, 0, 255).next(); + buffer.vertex(this.right, this.bottom, 0.0D).texture(1.0F, 1.0F).color(0, 0, 0, 255).next(); + buffer.vertex(this.right, (this.bottom - 4), 0.0D).texture(1.0F, 0.0F).color(0, 0, 0, 0).next(); + buffer.vertex(this.left, (this.bottom - 4), 0.0D).texture(0.0F, 0.0F).color(0, 0, 0, 0).next(); + t_1.draw(); + + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(this.left, this.bottom, 0.0D).color(0, 0, 0, 128).next(); + buffer.vertex(this.right, this.bottom, 0.0D).color(0, 0, 0, 128).next(); + buffer.vertex(this.right, this.top, 0.0D).color(0, 0, 0, 128).next(); + buffer.vertex(this.left, this.top, 0.0D).color(0, 0, 0, 128).next(); + t_1.draw(); + + int rl = this.getRowLeft(); + int sc = this.top + 4 - (int) this.getScrollAmount(); + this.renderList(matrices, rl, sc, mouseX, mouseY, delta); + + RenderSystem.enableTexture(); + RenderSystem.shadeModel(7424); + RenderSystem.enableAlphaTest(); + RenderSystem.disableBlend(); + } +} diff --git a/remappedSrc/pm/j4/petroleum/gui/PModuleConfigurationWidget.java b/remappedSrc/pm/j4/petroleum/gui/PModuleConfigurationWidget.java new file mode 100644 index 0000000..495da1c --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/gui/PModuleConfigurationWidget.java @@ -0,0 +1,281 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Matrix4f; +import pm.j4.petroleum.mixin.EntryListWidgetAccessor; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type P module configuration widget. + */ +public class PModuleConfigurationWidget extends AlwaysSelectedEntryListWidget { + /** + * The Parent. + */ + private final POptionsScreen parent; + /** + * The Module id. + */ + private String moduleId = null; + /** + * The Mods. + */ + private List mods; + /** + * The Extra mods. + */ + private final Set extraMods = new HashSet<>(); + /** + * The Scrolling. + */ + private boolean scrolling = false; + + /** + * Instantiates a new P module configuration widget. + * + * @param client the client + * @param width the width + * @param height the height + * @param y1 the y 1 + * @param y2 the y 2 + * @param entryHeight the entry height + * @param list the list + * @param parent the parent + */ + public PModuleConfigurationWidget(MinecraftClient client, int width, int height, int y1, int y2, int entryHeight, PModuleConfigurationWidget list, POptionsScreen parent) { + super(client, width, height, y1, y2, entryHeight); + this.parent = parent; + if (list != null) { + mods = list.mods; + } + setScrollAmount(parent.getScrollPercent() * Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4))); + } + + @Override + public void setScrollAmount(double amount) { + super.setScrollAmount(amount); + int denominator = Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4)); + if (denominator <= 0) { + parent.updateScrollPercent(0); + } else { + parent.updateScrollPercent(getScrollAmount() / Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4))); + } + } + + @Override + protected boolean isFocused() { + return parent.getFocused() == this; + } + + /** + * Select. + * + * @param entry the entry + */ + public void select(POptionEntry entry) { + this.setSelected(entry); + } + + @Override + public void setSelected(POptionEntry entry) { + super.setSelected(entry); + moduleId = entry.getModId(); + parent.updateSelected(entry); + } + + @Override + protected boolean isSelectedItem(int index) { + return super.isSelectedItem(index); + } + + @Override + public int addEntry(POptionEntry entry) { + if (extraMods.contains(entry.module)) { + return 0; + } + extraMods.add(entry.module); + int i = super.addEntry(entry); + if (entry.getModId().equals(moduleId)) { + setSelected(entry); + } + return i; + } + + @Override + protected boolean removeEntry(POptionEntry entry) { + extraMods.remove(entry.module); + return super.removeEntry(entry); + } + + @Override + protected POptionEntry remove(int index) { + extraMods.remove(getEntry(index).module); + return super.remove(index); + } + + @Override + protected void renderList(MatrixStack matrices, int x, int y, int mouseX, int mouseY, float delta) { + int itemCount = this.getItemCount(); + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + + for (int index = 0; index < itemCount; ++index) { + int entryTop = this.getRowTop(index); + int entryBottom = this.getRowTop(index) + this.itemHeight; + if (entryBottom >= this.top && entryTop <= this.bottom) { + int entryHeight = this.itemHeight - 4; + POptionEntry entry = this.getEntry(index); + int rowWidth = this.getRowWidth(); + int entryLeft; + if (((EntryListWidgetAccessor) this).isRenderSelection() && this.isSelectedItem(index)) { + entryLeft = getRowLeft() - 2 + entry.getXOffset(); + int selectionRight = x + rowWidth + 2; + RenderSystem.disableTexture(); + float brightness = this.isFocused() ? 1.0F : 0.5F; + RenderSystem.color4f(brightness, brightness, brightness, 1.0F); + Matrix4f matrix = matrices.peek().getModel(); + buffer.begin(7, VertexFormats.POSITION); + buffer.vertex(matrix, entryLeft, entryTop + entryHeight + 2, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop + entryHeight + 2, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop - 2, 0.0F).next(); + buffer.vertex(matrix, entryLeft, entryTop - 2, 0.0F).next(); + t_1.draw(); + RenderSystem.color4f(0.0F, 0.0F, 0.0F, 1.0F); + buffer.begin(7, VertexFormats.POSITION); + buffer.vertex(matrix, entryLeft + 1, entryTop + entryHeight + 1, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop + entryHeight + 1, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop - 1, 0.0F).next(); + buffer.vertex(matrix, entryLeft + 1, entryTop - 1, 0.0F).next(); + t_1.draw(); + RenderSystem.enableTexture(); + } + + entryLeft = this.getRowLeft(); + entry.render(matrices, + index, + entryTop, + entryLeft, + rowWidth, + entryHeight, + mouseX, + mouseY, + this.isMouseOver(mouseX, mouseY) && Objects.equals(this.getEntryAtPos(mouseX, mouseY), entry), + delta); + } + } + } + + @Override + protected void updateScrollingState(double mouseX, double mouseY, int button) { + super.updateScrollingState(mouseX, mouseY, button); + this.scrolling = button == 0 && + mouseX >= (double) this.getScrollbarPositionX() && + mouseX < (double) (this.getScrollbarPositionX() + 6); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + this.updateScrollingState(mouseX, mouseY, button); + if (!this.isMouseOver(mouseX, mouseY)) { + return false; + } else { + POptionEntry entry = this.getEntryAtPos(mouseX, mouseY); + if (entry != null) { + if (entry.mouseClicked(mouseX, mouseY, button)) { + this.setFocused(entry); + this.setDragging(true); + return true; + } else if (button == 0) { + this.clickedHeader((int) (mouseX - (double) (this.left + this.width / 2 - this.getRowWidth() / 2)), + (int) (mouseY - (double) this.top) + (int) this.getScrollAmount() - 4); + } + } + } + + return this.scrolling; + } + + /** + * Gets entry at pos. + * + * @param x the x + * @param y the y + * @return the entry at pos + */ + public final POptionEntry getEntryAtPos(double x, double y) { + int i = MathHelper.floor(y - (double) this.top) - this.headerHeight + (int) this.getScrollAmount() - 4; + int index = i / this.itemHeight; + return x < (double) this.getScrollbarPositionX() && + x >= (double) getRowLeft() && + x <= (double) (getRowLeft() + getRowWidth()) && + index >= 0 && i >= 0 && + index < this.getItemCount() ? this.children().get(index) : null; + } + + @Override + protected int getScrollbarPositionX() { + return this.width - 6; + } + + @Override + public int getRowWidth() { + return this.width - (Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4)) > 0 ? 18 : 12); + } + + @Override + public int getRowLeft() { + return left + 6; + } + + /** + * Gets width. + * + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * Gets top. + * + * @return the top + */ + public int getTop() { + return this.top; + } + + /** + * Gets parent. + * + * @return the parent + */ + public POptionsScreen getParent() { + return parent; + } + + @Override + protected int getMaxPosition() { + return super.getMaxPosition() + 4; + } + + /** + * Gets displayed count. + * + * @return the displayed count + */ + public int getDisplayedCount() { + return children().size(); + } +} diff --git a/remappedSrc/pm/j4/petroleum/gui/PMovableButton.java b/remappedSrc/pm/j4/petroleum/gui/PMovableButton.java new file mode 100644 index 0000000..4ff84fa --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/gui/PMovableButton.java @@ -0,0 +1,389 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import java.util.List; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.widget.AbstractButtonWidget; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Matrix4f; +import pm.j4.petroleum.modules.menu.ModMenu; +import pm.j4.petroleum.util.data.ButtonInformation; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type P movable button. + */ +public class PMovableButton extends AbstractButtonWidget { + /** + * The Expanded. + */ + private boolean expanded; + /** + * The Collapsed width. + */ + private final int collapsedWidth; + /** + * The Expanded width. + */ + private int expandedWidth; + /** + * The Collapsed height. + */ + private final int collapsedHeight; + /** + * The Expanded height. + */ + private int expandedHeight; + /** + * The Module height. + */ + private final int moduleHeight; + /** + * The Modules. + */ + private final List modules; + + /** + * The Stored x. + */ + private int storedX; + /** + * The Stored y. + */ + private int storedY; + + /** + * The Spin. + */ + private double spin; + + /** + * The Arrow size. + */ + private final int arrowSize = 10; + + + /** + * The Category. + */ + private final String category; + + /** + * The Parent. + */ + private final PModMenuScreen parent; + + /** + * Instantiates a new P movable button. + * + * @param x the x + * @param y the y + * @param categoryName the category name + * @param modules the modules + * @param open the open + * @param parent the parent + */ + public PMovableButton(int x, int y, String categoryName, List modules, boolean open, PModMenuScreen parent) { + super(x, y, 0, 0, new TranslatableText(categoryName)); + this.category = categoryName; + int w = MinecraftClient.getInstance().textRenderer.getWidth(new TranslatableText(categoryName)) + 8; + int h = MinecraftClient.getInstance().textRenderer.fontHeight + 8; + this.width = w; + this.collapsedWidth = w; + this.expandedWidth = 0; + this.height = h; + this.collapsedHeight = h; + this.expandedHeight = 0; + this.moduleHeight = h; + this.expanded = open; + this.modules = modules; + this.parent = parent; + } + + @Override + public void onClick(double mouseX, double mouseY) { + this.storedX = (int) mouseX; + this.storedY = (int) mouseY; + super.onClick(mouseX, mouseY); + } + + /** + * On extra click. + * + * @param mouseX the mouse x + * @param mouseY the mouse y + */ + private void onExtraClick(double mouseX, double mouseY) { + System.out.println("extra click"); + int increment = this.moduleHeight + 4; + int location = (int)mouseY - (this.y + this.collapsedHeight); + int index = location / increment; + System.out.println("index: " + index); + if(modules.size() >= index) { + ModuleBase affectedModule = modules.get(index); + System.out.println("module: " + affectedModule); + if(affectedModule.isActivatable()) { + System.out.println("toggling"); + affectedModule.toggle(); + } + } + else { + System.out.println("index too great"); + } + //TODO module things + } + + @Override + public void onRelease(double mouseX, double mouseY) { + int mx = (int) mouseX; + int my = (int) mouseY; + /** + * The Padding. + */ + int padding = 5; + if (storedX + padding > mx && storedX - padding < mx && + storedY + padding > my && storedY - padding < my) { + this.expanded = !this.expanded; + } + } + + @Override + protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY) { + this.x += (int) deltaX; + this.y += (int) deltaY; + + // i really hate to do it but nowhere else will it properly save + this.updateCoordinate(); + } + + /** + * Update coordinate. + */ + public void updateCoordinate() { + ModMenu.updateCoord(this.category, new ButtonInformation((this.x / (double) parent.width), (this.y / (double) parent.height), this.expanded)); + } + + // fuck click sounds + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (this.active && this.visible) { + if (this.isValidClickButton(button)) { + boolean bl = this.clicked(mouseX, mouseY); + if (bl && mouseY > this.y + this.collapsedHeight && mouseY < this.y + this.expandedHeight) { + this.onExtraClick(mouseX, mouseY); + return true; + } else if (bl) { + this.onClick(mouseX, mouseY); + return true; + } + } + + } + return false; + } + + /** + * Transition max width. + * + * @param width the width + */ + private void transitionMaxWidth(int width) { + double increment = ((width - this.width) / 20.0); + int sign = (width > this.width) ? 1 : -1; + if (increment == 0) { + this.width = width; + } else if (increment < 1 && increment > -1) { + this.width += sign; + } else { + this.width += (int) increment; + } + } + + /** + * Transition max height. + * + * @param height the height + */ + private void transitionMaxHeight(int height) { + double increment = ((height - this.height) / 20.0); + int sign = (height > this.height) ? 1 : -1; + if (increment == 0) { + this.height = height; + } else if (increment < 1 && increment > -1) { + this.height += sign; + } else { + this.height += (int) increment; + } + } + + @Override + public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) { + + if (this.expandedWidth == 0 || this.expandedHeight == 0) { + this.expandedHeight = this.collapsedHeight + ((this.moduleHeight + 4) * modules.size()); + modules.forEach(module -> { + this.expandedWidth = this.width; + int w = MinecraftClient.getInstance().textRenderer.getWidth(module.getReadableName()) + arrowSize + 8; + if (w > this.expandedWidth) { + this.expandedWidth = w; + } + }); + // this should only run when opening the screen for the first time + if (this.expanded) { + this.height = expandedHeight; + this.width = expandedWidth; + } + } + + MinecraftClient minecraftClient = MinecraftClient.getInstance(); + TextRenderer textRenderer = minecraftClient.textRenderer; + minecraftClient.getTextureManager().bindTexture(WIDGETS_LOCATION); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha); + + RenderSystem.disableTexture(); + RenderSystem.defaultBlendFunc(); + float brightness = this.isFocused() ? 1.0F : 0.5F; + RenderSystem.color4f(brightness, brightness, brightness, 1.0F); + Matrix4f matrix = matrices.peek().getModel(); + + int buttonLeft = this.x; + int buttonRight = this.x + width + 2; + int buttonTop = this.y; + int buttonBottom = this.y + this.collapsedHeight; + int buttonExpandedBottom = this.y + this.height; + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + + RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F); + drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, buttonTop - 2, buttonBottom + 2); + + RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F); + drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, buttonTop - 1, buttonBottom + 1); + + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.9F); + drawEquilateralTriangle(t_1, buffer, matrix, 40, 40, 180, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 60, 60, 0, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 40, 60, 90, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 60, 40, 360, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 80, 40, 270, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 80, 60, 120, arrowSize); + + int j = this.active ? 16777215 : 10526880; + if (this.expanded) { + if (this.width != this.expandedWidth || this.height != this.expandedHeight) { + transitionMaxWidth(this.expandedWidth); + transitionMaxHeight(this.expandedHeight); + RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F); + drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, buttonBottom + 1, buttonExpandedBottom + 2); + + RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F); + drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, buttonBottom + 2, buttonExpandedBottom + 1); + if ((this.height - 8) / 2 > (this.collapsedHeight)) { + drawCenteredText(matrices, textRenderer, new LiteralText("..."), this.x + this.width / 2, this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24); + } + } else { + for (int i = 0; i < modules.size(); i++) { + int adjustedIndex = i + 1; + int previousBottom = buttonBottom + (i * (this.moduleHeight + 4)); + int currentBottom = buttonBottom + ((i + 1) * (this.moduleHeight + 4)); + + RenderSystem.defaultBlendFunc(); + RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F); + drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, previousBottom + 1, currentBottom + 2); + + RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F); + drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, previousBottom + 2, currentBottom + 1); + + drawCenteredText(matrices, + textRenderer, + modules.get(i).getReadableName(), + this.x + this.width / 2, + this.y + ((this.collapsedHeight - 8) / 2 + ((moduleHeight + 4) * adjustedIndex)), + j | MathHelper.ceil(this.alpha * 255.0F) << 24); + } + } + } else { + if (this.width != this.collapsedWidth || this.height != this.collapsedHeight) { + transitionMaxWidth(this.collapsedWidth); + transitionMaxHeight(this.collapsedHeight); + RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F); + drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, buttonBottom + 1, buttonExpandedBottom + 2); + + RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F); + drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, buttonBottom + 2, buttonExpandedBottom + 1); + if ((this.height - 8) / 2 > (this.collapsedHeight)) { + drawCenteredText(matrices, textRenderer, new LiteralText("..."), this.x + this.width / 2, this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24); + } + } + } + RenderSystem.enableTexture(); + drawCenteredText(matrices, textRenderer, this.getMessage(), this.x + this.width / 2, this.y + (this.collapsedHeight - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24); + } + + /** + * Draw equilateral triangle. + * + * @param t_1 the t 1 + * @param buffer the buffer + * @param matrix the matrix + * @param centerX the center x + * @param centerY the center y + * @param rotation the rotation + * @param distance the distance + */ + private void drawEquilateralTriangle(Tessellator t_1, BufferBuilder buffer, Matrix4f matrix, int centerX, int centerY, double rotation, int distance) { + double rotation1 = rotation; + double rotation2 = rotation + 120; + double rotation3 = rotation + 240; + int point1X = (int)(distance * Math.cos(Math.toRadians(rotation1))) + centerX; + int point1Y = (int)(distance * Math.sin(Math.toRadians(rotation1))) + centerY; + int point2X = (int)(distance * Math.cos(Math.toRadians(rotation2))) + centerX; + int point2Y = (int)(distance * Math.sin(Math.toRadians(rotation2))) + centerY; + int point3X = (int)(distance * Math.cos(Math.toRadians(rotation3))) + centerX; + int point3Y = (int)(distance * Math.sin(Math.toRadians(rotation3))) + centerY; + + //RenderSystem.enableBlend(); + RenderSystem.disableBlend(); + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(matrix, centerX, centerY, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, centerX, point1Y, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, point1X, point1Y, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next(); + + buffer.vertex(matrix, centerX, centerY, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, centerX, point2Y, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, point2X, point2Y, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next(); + + buffer.vertex(matrix, centerX, centerY, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, centerX, point3Y, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, point3X, point3Y, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next(); + t_1.draw(); + } + + /** + * Draw box. + * + * @param t_1 the t 1 + * @param buffer the buffer + * @param matrix the matrix + * @param buttonLeft the button left + * @param buttonRight the button right + * @param buttonTop the button top + * @param buttonBottom the button bottom + */ + private void drawBox(Tessellator t_1, BufferBuilder buffer, Matrix4f matrix, int buttonLeft, int buttonRight, int buttonTop, int buttonBottom) { + RenderSystem.enableBlend(); + buffer.begin(7, VertexFormats.POSITION); + buffer.vertex(matrix, buttonLeft, buttonBottom, 0.0F).next(); + buffer.vertex(matrix, buttonRight, buttonBottom, 0.0F).next(); + buffer.vertex(matrix, buttonRight, buttonTop, 0.0F).next(); + buffer.vertex(matrix, buttonLeft, buttonTop, 0.0F).next(); + t_1.draw(); + } +} diff --git a/remappedSrc/pm/j4/petroleum/gui/POptionEntry.java b/remappedSrc/pm/j4/petroleum/gui/POptionEntry.java new file mode 100644 index 0000000..4132848 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/gui/POptionEntry.java @@ -0,0 +1,94 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.StringVisitable; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Language; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type P option entry. + */ +public class POptionEntry extends AlwaysSelectedEntryListWidget.Entry { + + /** + * The Module. + */ + protected final ModuleBase module; + /** + * The Client. + */ + protected final MinecraftClient client; + /** + * The List. + */ + private final PModuleConfigurationWidget list; + + /** + * Instantiates a new P option entry. + * + * @param mod the mod + * @param list the list + */ + public POptionEntry(ModuleBase mod, PModuleConfigurationWidget list) { + this.module = mod; + this.client = MinecraftClient.getInstance(); + this.list = list; + } + + //TODO TEST move text to be centered + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + x += getXOffset(); + entryWidth -= getXOffset(); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + Text name = this.getModName(); + StringVisitable nameString = name; + int maxNameWidth = entryWidth - 32 - 3; + TextRenderer font = this.client.textRenderer; + if (font.getWidth(name) > maxNameWidth) { + StringVisitable ellipse = StringVisitable.plain("..."); + nameString = StringVisitable.concat(font.trimToWidth(nameString, maxNameWidth - font.getWidth(ellipse)), ellipse); + } + + font.draw(matrices, Language.getInstance().reorder(nameString), x + 32 + 3, y + (entryHeight / 2), 0xFFFFFF); + } + + @Override + public boolean mouseClicked(double x, double y, int b) { + this.list.select(this); + return true; + } + + /** + * Gets mod id. + * + * @return the mod id + */ + public String getModId() { + return module.getModuleName(); + } + + /** + * Gets mod name. + * + * @return the mod name + */ + public TranslatableText getModName() { + return module.getReadableName(); + } + + /** + * Gets x offset. + * + * @return the x offset + */ + public int getXOffset() { + return 0; + } +} diff --git a/remappedSrc/pm/j4/petroleum/gui/POptionsScreen.java b/remappedSrc/pm/j4/petroleum/gui/POptionsScreen.java new file mode 100644 index 0000000..de409d6 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/gui/POptionsScreen.java @@ -0,0 +1,224 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ScreenTexts; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.StringVisitable; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type P options screen. + */ +@SuppressWarnings("deprecation") +public class POptionsScreen extends Screen { + /** + * The Previous screen. + */ + private final Screen previousScreen; + /** + * The Scroll percent. + */ + private double scrollPercent = 0; + /** + * The Modules. + */ + private PModuleConfigurationWidget modules; + /** + * The Config pane. + */ + private PModuleConfigPane configPane; + /** + * The Selected. + */ + private POptionEntry selected; + /** + * The Tooltip. + */ + private Text tooltip; + + /** + * The Pane y. + */ + private int paneY; + /** + * The Right pane x. + */ + private int rightPaneX; + + /** + * Instantiates a new P options screen. + * + * @param previousScreen the previous screen + */ + public POptionsScreen(Screen previousScreen) { + super(new TranslatableText("petroleum.options")); + this.previousScreen = previousScreen; + } + + @Override + public void onClose() { + super.onClose(); + assert this.client != null; + this.client.openScreen(previousScreen); + } + + protected void init() { + paneY = 48; + int paneWidth = this.width / 2 - 8; + rightPaneX = width - paneWidth; + this.modules = new PModuleConfigurationWidget(this.client, + this.width - paneWidth, + this.height, + paneY + 19, + this.height - 36, + 36, + this.modules, + this); + this.modules.setLeftPos(0); + this.children.add(this.modules); + this.configPane = new PModuleConfigPane(this.client, + paneWidth, + this.height, + paneY + 19, + this.height - 36, + 48, + this); + this.configPane.setLeftPos(paneWidth); + this.children.add(this.configPane); + List configurableModules = new ArrayList<>(); + if (ConfigManager.getConfig().isPresent()) { + configurableModules.addAll(PetroleumMod.getActiveMods() + .stream().filter(ModuleBase::configurable) + .collect(Collectors.toList())); + } + configurableModules.forEach(module -> this.modules.addEntry(new POptionEntry(module, this.modules))); + this.addButton(new ButtonWidget(this.width / 2 - 75, this.height - 30, 150, 20, ScreenTexts.DONE, (buttonWidget) -> { + ConfigManager.saveAllModules(); + assert this.client != null; + this.client.openScreen(this.previousScreen); + })); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.renderBackground(matrices); + + this.modules.render(matrices, mouseX, mouseY, delta); + if (selected != null) { + this.configPane.render(matrices, mouseX, mouseY, delta); + } + RenderSystem.disableBlend(); + drawTextWithShadow(matrices, this.textRenderer, this.title, this.modules.getWidth() / 2, 8, 16777215); + super.render(matrices, mouseX, mouseY, delta); + + if (selected != null) { + int offset = 36; + int x = rightPaneX; + int maxNameWidth = this.width - (x + offset); + int lineSpacing = textRenderer.fontHeight + 1; + Text name = selected.getModName(); + + StringVisitable trimmedName = name; + + if (textRenderer.getWidth(name) > maxNameWidth) { + StringVisitable ellipsis = StringVisitable.plain("..."); + trimmedName = StringVisitable.concat(textRenderer.trimToWidth(name, maxNameWidth - textRenderer.getWidth(ellipsis)), ellipsis); + } + if (mouseX > x + offset && mouseY > paneY + 1 && mouseY < paneY + 1 + textRenderer.fontHeight && mouseX < x + offset + textRenderer.getWidth(trimmedName)) { + setTooltip(new LiteralText("Configure " + selected.getModName())); + } + textRenderer.draw(matrices, selected.getModName(), x + offset, paneY + 2 + lineSpacing, 0x808080); + + if (this.tooltip != null) { + this.renderOrderedTooltip(matrices, textRenderer.wrapLines(this.tooltip, Integer.MAX_VALUE), mouseX, mouseY); + } + } + } + + /** + * Sets tooltip. + * + * @param tooltip the tooltip + */ + private void setTooltip(Text tooltip) { + this.tooltip = tooltip; + } + + @Override + public void renderBackground(MatrixStack matrices) { + POptionsScreen.overlayBackground(this.width, this.height); + } + + /** + * Overlay background. + * + * @param x2 the x 2 + * @param y2 the y 2 + */ + static void overlayBackground(int x2, int y2) { + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + Objects.requireNonNull(MinecraftClient.getInstance()).getTextureManager().bindTexture(DrawableHelper.OPTIONS_BACKGROUND_TEXTURE); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR); + buffer.vertex(0, y2, 0.0D).texture(0 / 32.0F, y2 / 32.0F).color(64, 64, 64, 255).next(); + buffer.vertex(x2, y2, 0.0D).texture(x2 / 32.0F, y2 / 32.0F).color(64, 64, 64, 255).next(); + buffer.vertex(x2, 0, 0.0D).texture(x2 / 32.0F, 0 / 32.0F).color(64, 64, 64, 255).next(); + buffer.vertex(0, 0, 0.0D).texture(0 / 32.0F, 0 / 32.0F).color(64, 64, 64, 255).next(); + t_1.draw(); + } + + /** + * Gets scroll percent. + * + * @return the scroll percent + */ + double getScrollPercent() { + return scrollPercent; + } + + /** + * Update scroll percent. + * + * @param scrollPercent the scroll percent + */ + void updateScrollPercent(double scrollPercent) { + this.scrollPercent = scrollPercent; + } + + /** + * Gets selected. + * + * @return the selected + */ + POptionEntry getSelected() { + return selected; + } + + /** + * Update selected. + * + * @param entry the entry + */ + void updateSelected(POptionEntry entry) { + if (entry != null) { + this.selected = entry; + } + } +} diff --git a/remappedSrc/pm/j4/petroleum/mixin/DebugHudMixin.java b/remappedSrc/pm/j4/petroleum/mixin/DebugHudMixin.java new file mode 100644 index 0000000..2a79bdd --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/mixin/DebugHudMixin.java @@ -0,0 +1,38 @@ +package pm.j4.petroleum.mixin; + +import java.util.List; +import java.util.Optional; +import net.minecraft.client.gui.hud.DebugHud; +import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import pm.j4.petroleum.modules.splash.SplashText; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; + +/** + * The type Debug hud mixin. + */ +@Mixin(DebugHud.class) +public class DebugHudMixin { + /** + * Render text right. + * + * @param matrices the matrices + * @param ci the ci + * @param list the list + */ + @Inject(method = "renderLeftText", + at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/gui/hud/DebugHud;getLeftText()Ljava/util/List;"), + locals = LocalCapture.CAPTURE_FAILSOFT) + protected void renderTextRight(MatrixStack matrices, CallbackInfo ci, List list) { + Optional config = ConfigManager.getConfig(); + if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")) { + list.add("[Petroleum] " + SplashText.get() + " loaded"); + } + + } +} diff --git a/remappedSrc/pm/j4/petroleum/mixin/EntryListWidgetAccessor.java b/remappedSrc/pm/j4/petroleum/mixin/EntryListWidgetAccessor.java new file mode 100644 index 0000000..eea68ab --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/mixin/EntryListWidgetAccessor.java @@ -0,0 +1,19 @@ +package pm.j4.petroleum.mixin; + +import net.minecraft.client.gui.widget.EntryListWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +/** + * The interface Entry list widget accessor. + */ +@Mixin(EntryListWidget.class) +public interface EntryListWidgetAccessor { + /** + * Is render selection boolean. + * + * @return the boolean + */ + @Accessor("renderSelection") + boolean isRenderSelection(); +} diff --git a/remappedSrc/pm/j4/petroleum/mixin/ModListMixin.java b/remappedSrc/pm/j4/petroleum/mixin/ModListMixin.java new file mode 100644 index 0000000..7ee7248 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/mixin/ModListMixin.java @@ -0,0 +1,89 @@ +package pm.j4.petroleum.mixin; + + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.TranslatableText; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import pm.j4.petroleum.modules.list.ModList; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Mod list mixin. + */ +@Mixin(InGameHud.class) +public abstract class ModListMixin extends DrawableHelper { + /** + * The Scaled height. + */ + @Shadow + private int scaledHeight; + /** + * The Client. + */ + private final MinecraftClient client; + + /** + * Gets font renderer. + * + * @return the font renderer + */ + @Shadow + public abstract TextRenderer getFontRenderer(); + + + /** + * Instantiates a new Mod list mixin. + * + * @param client the client + */ + public ModListMixin(MinecraftClient client) { + this.client = client; + } + + /** + * Render. + * + * @param matrices the matrices + * @param tickDelta the tick delta + * @param ci the ci + */ + @Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;F)V", + at = @At("HEAD")) + public void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) { + Optional config = ConfigManager.getConfig(); + if (config.isPresent() && + config.get().isModuleEnabled("petroleum.modlist") && + !this.client.options.hudHidden && + !this.client.options.debugEnabled) { + renderModuleList(matrices); + } + } + + /** + * Render module list. + * + * @param matrices the matrices + */ + private void renderModuleList(MatrixStack matrices) { + List modules = ModList.getActive(); + List activeModuleList = modules.stream().map(module -> module.getReadableName()).collect(Collectors.toList()); + int fontHeight = this.getFontRenderer().fontHeight; + int startHeight = this.scaledHeight - (activeModuleList.size() * (fontHeight + 4)); + for (int i = 0; i < activeModuleList.size(); i++) { + this.getFontRenderer().drawWithShadow(matrices, activeModuleList.get(i), 10, 10 + (i * (fontHeight + 4)), -1); + } + } +} diff --git a/remappedSrc/pm/j4/petroleum/mixin/OptionsMenuMixin.java b/remappedSrc/pm/j4/petroleum/mixin/OptionsMenuMixin.java new file mode 100644 index 0000000..be27f25 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/mixin/OptionsMenuMixin.java @@ -0,0 +1,42 @@ +package pm.j4.petroleum.mixin; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.options.OptionsScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import pm.j4.petroleum.gui.POptionsScreen; + +/** + * The type Options menu mixin. + */ +@Mixin(OptionsScreen.class) +public class OptionsMenuMixin extends Screen { + + /** + * Instantiates a new Options menu mixin. + * + * @param title the title + */ + protected OptionsMenuMixin(Text title) { + super(title); + } + + /** + * Init. + * + * @param ci the ci + */ + @Inject(at = @At(value = "TAIL"), + method = "init()V") + protected void init(CallbackInfo ci) { + this.addButton(new ButtonWidget(this.width / 2 - 75, this.height / 6 + 140, 150, 20, new TranslatableText("petroleum.options"), (buttonWidget) -> { + assert this.client != null; + this.client.openScreen(new POptionsScreen(this)); + })); + } +} diff --git a/remappedSrc/pm/j4/petroleum/mixin/TitleScreenMixin.java b/remappedSrc/pm/j4/petroleum/mixin/TitleScreenMixin.java new file mode 100644 index 0000000..e915a62 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/mixin/TitleScreenMixin.java @@ -0,0 +1,132 @@ +package pm.j4.petroleum.mixin; + +import java.util.Optional; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.TitleScreen; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import pm.j4.petroleum.modules.splash.SplashText; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; + + +/** + * Mixin attached to the TitleScreen. + * Currently, it is only used to display a string of text with the mod's version. + * Any other modules will likely extend the options screen or pause screen, + * so the module is unlikely to be used elsewhere. + */ +@Mixin(TitleScreen.class) +public class TitleScreenMixin extends Screen { + /** + * The Opacity. + */ + private double opacity = 0; + /** + * The Ascending. + */ + private boolean ascending = false; + + /** + * Stub method. + * Since the mixin injects itself into the *actual* TitleScreen used by the game, + * this should never run. + * + * @param title the title + */ + protected TitleScreenMixin(Text title) { + super(title); + } + + /** + * Mixin injection into the render method. + * It captures locals so that the text can be rendered alongside the + * screen fade-in. + * It injects before the call to @link com.mojang.bridge.game.GameVersion#getName() using INVOKE_ASSIGN, + * because attempting to use a regular invoke statement on @link net.minecraft.client.gui.DrawHelper#drawStringWithShadow() + * repeatedly failed. + *

+ * + * @param matrices the matrices + * @param mouseX the mouse x + * @param mouseY the mouse y + * @param delta the delta + * @param ci the ci + * @param f the f + * @param i the + * @param j the j + * @param g the g + * @param l the l + */ + @Inject(method = "render", + at = @At( + value = "INVOKE_ASSIGN", + target = "Lcom/mojang/bridge/game/GameVersion;getName()Ljava/lang/String;", + ordinal = 0), + locals = LocalCapture.CAPTURE_FAILSOFT) + private void render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci, float f, int i, int j, float g, int l) { + Optional config = ConfigManager.getConfig(); + if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")) { + drawStringWithShadow(matrices, this.textRenderer, SplashText.get(), 2, this.height - 20, blink(13108374) | l); + } + } + + /** + * fades an integer color based on the values declared at the top of the class. + * + * @param color the integer representation of the color to fade. this should generally remain constant. + * @return the color, adjusted for "opacity". It's RGB and not RGBA, so it just lowers all color values. + */ + @SuppressWarnings("SameParameterValue") + private int blink(int color) { + /* + The Speed. + */ + int speed = 3; + /* + The Opacity max. + */ + double opacity_max = 1000; + if (ascending) { + opacity += speed; + if (opacity > opacity_max) { + opacity = opacity_max; + ascending = false; + } + } else { + opacity -= speed; + /* + The Opacity min. + */ + double opacity_min = 500; + if (opacity < opacity_min) { + opacity = opacity_min; + ascending = true; + } + } + double opacityD = (opacity / opacity_max); + /* + The R mask. + */ + int r_mask = 16711680; + int r = ((color & r_mask) / Integer.parseInt("010000", 16)); + /* + The G mask. + */ + int g_mask = 65280; + int g = ((color & g_mask) / Integer.parseInt("000100", 16)); + /* + The B mask. + */ + int b_mask = 255; + int b = ((color & b_mask)); + return ((int) (r * opacityD) * Integer.parseInt("010000", 16)) | + ((int) (g * opacityD) * Integer.parseInt("000100", 16)) | + ((int) (b * opacityD)); + } +} diff --git a/remappedSrc/pm/j4/petroleum/modules/ExampleModule.java b/remappedSrc/pm/j4/petroleum/modules/ExampleModule.java new file mode 100644 index 0000000..0bb285a --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/modules/ExampleModule.java @@ -0,0 +1,37 @@ +package pm.j4.petroleum.modules; + +import java.util.HashMap; +import java.util.Map; +import net.minecraft.client.MinecraftClient; +import pm.j4.petroleum.util.module.ModuleBase; +import pm.j4.petroleum.util.module.option.BooleanOption; +import pm.j4.petroleum.util.module.option.ConfigurationOption; + +/** + * The type Example module. + */ +public class ExampleModule extends ModuleBase { + /** + * example mod + */ + public ExampleModule() { + super("petroleum.example", + "petroleum.misc", + true, + false, + true); + } + + @Override + protected Map getDefaultConfig() { + Map options = new HashMap<>(); + options.put("petroleum.example_b_one", new BooleanOption("example")); + options.put("petroleum.example_b_two", new BooleanOption("example")); + return options; + } + + @Override + public void activate(MinecraftClient client) { + System.out.println("Example Mod Keybind Activate"); + } +} diff --git a/remappedSrc/pm/j4/petroleum/modules/bindings/BindingInfo.java b/remappedSrc/pm/j4/petroleum/modules/bindings/BindingInfo.java new file mode 100644 index 0000000..c147d8a --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/modules/bindings/BindingInfo.java @@ -0,0 +1,30 @@ +package pm.j4.petroleum.modules.bindings; + +import net.minecraft.client.util.InputUtil; + +/** + * The type Binding info. + */ +public class BindingInfo { + /** + * The Translation key. + */ + public String translationKey; + /** + * The Type. + */ + public InputUtil.Type type; + /** + * The Key. + */ + public int key; + /** + * The Category. + */ + public String category; + + /** + * The Attached function id. + */ + public String attachedModuleName; +} diff --git a/remappedSrc/pm/j4/petroleum/modules/bindings/BindingManager.java b/remappedSrc/pm/j4/petroleum/modules/bindings/BindingManager.java new file mode 100644 index 0000000..c9af1ef --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/modules/bindings/BindingManager.java @@ -0,0 +1,96 @@ +package pm.j4.petroleum.modules.bindings; + +import java.util.*; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.options.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.TranslatableText; +import org.lwjgl.glfw.GLFW; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.gui.PModuleConfigEntry; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.config.GlobalConfig; +import pm.j4.petroleum.util.module.ModuleBase; +import pm.j4.petroleum.util.module.option.KeybindOption; + +/** + * The type Binding manager. + */ +public class BindingManager extends ModuleBase { + /** + * Instantiates a new Module base. + * Parameters should be constant across restarts. + */ + public BindingManager() { + super("petroleum.bindings", + "petroleum.misc", + false, + true, + true); + } + + @Override + public void init() { + registerBindings(); + super.init(); + } + + @Override + public List getConfigEntries() { + List entries = new ArrayList<>(); + + Map mapped = new HashMap<>(); + if (ConfigManager.getConfig().isPresent()) { + Map binds = ConfigManager.getConfig().get().globalConfig.bindings; + + binds.forEach((key, func) -> { + KeybindOption option = new KeybindOption(func.getModuleName() + " " + func.getCategory()); + option.fromKeybind(key, func); + mapped.put(option, func); + }); + } + mapped.forEach((configEntry, module) -> { + PModuleConfigEntry entry = new PModuleConfigEntry(configEntry, new TranslatableText(module.getModuleName())) { + //TODO keybinding. most likely involves mixin to take direct key input + // look into how keybinding in regular options screen works + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + if (this.displayText != null) { + MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, displayText, x, y, 0xAAAAAA); + } + if (this.option != null) { + int fontHeight = MinecraftClient.getInstance().textRenderer.fontHeight; + MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, "Key Value: " + this.option.getStringValue(), x, y + fontHeight + 4, 0xFFFFFF); + } + } + }; + entries.add(entry); + }); + return entries; + } + + /** + * Register bindings. + */ + private void registerBindings() { + if (!ConfigManager.getConfig().isPresent()) { + return; + } + GlobalConfig c = ConfigManager.getConfig().get().globalConfig; + Optional mod = PetroleumMod.getMod("petroleum.modmenu"); + if (mod.isPresent() && !c.isBound(mod.get())) { + //TODO + // the only explicit keybinding (for now.) + // once the binding manager has been completed, + // this should be migrated there, as a default binding + KeyBinding binding = new KeyBinding( + "key.petroleum.togglemodmenu", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_RIGHT_CONTROL, + "category.petroleum" + ); + ConfigManager.getConfig().get().globalConfig.setBinding(binding, mod.get()); + } + } +} diff --git a/remappedSrc/pm/j4/petroleum/modules/list/ModList.java b/remappedSrc/pm/j4/petroleum/modules/list/ModList.java new file mode 100644 index 0000000..8c4bb9f --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/modules/list/ModList.java @@ -0,0 +1,44 @@ +package pm.j4.petroleum.modules.list; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import jdk.nashorn.internal.runtime.options.Option; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Mod list. + */ +public class ModList extends ModuleBase { + /** + * Instantiates a new Mod list. + */ + public ModList() { + super("petroleum.modlist", + "petroleum.misc", + true, + true, + true); + } + + /** + * Gets active. + * + * @return the active + */ + public static List getActive() { + List result = new ArrayList<>(); + Optional config = ConfigManager.getConfig(); + if(config.isPresent()) { + config.get().getEnabledModules().forEach((mod) -> { + if (!mod.isHidden()) { + result.add(mod); + } + }); + } + return result; + } +} diff --git a/remappedSrc/pm/j4/petroleum/modules/menu/ModMenu.java b/remappedSrc/pm/j4/petroleum/modules/menu/ModMenu.java new file mode 100644 index 0000000..7ed0500 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/modules/menu/ModMenu.java @@ -0,0 +1,98 @@ +package pm.j4.petroleum.modules.menu; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.minecraft.client.MinecraftClient; +import pm.j4.petroleum.gui.PModMenuScreen; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.data.ButtonInformation; +import pm.j4.petroleum.util.data.Category; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Mod menu. + */ +public class ModMenu extends ModuleBase { + + /** + * The constant coordinates. + */ + private static final Map coordinates = new HashMap<>(); + + /** + * Instantiates a new Mod menu. + */ + public ModMenu() { + super("petroleum.modmenu", + "petroleum.misc", + true, + true, + true); + } + + // TODO figure out resizing + // the number itself changes, so it should just be probably like some onResize bullshit in PModMenuScreen + @Override + public void init() { + Map> categories = Category.getCategoryMap(); + final double[] h = {.1}; + categories.forEach((category, moduleList) -> { + ButtonInformation conf = ConfigManager.getConfig().isPresent() ? + ConfigManager.getConfig().get().globalConfig.getButton(category) : + null; + ButtonInformation coord = conf != null ? conf : new ButtonInformation(.1, h[0], false); + h[0] += .01; + coordinates.put(category, coord); + if (ConfigManager.getConfig().isPresent()) { + ConfigManager.getConfig().get().globalConfig.setButton(category, coord); + } + }); + } + + /** + * Update coord. + * + * @param b the b + * @param c the c + */ + public static void updateCoord(String b, ButtonInformation c) { + if (c.x < 0.05) { + c.x = 0.05; + } + if (c.x > .95) { + c.x = .95; + } + if (c.y < 0.05) { + c.y = 0.05; + } + if (c.y > .95) { + c.y = .95; + } + if (coordinates.containsKey(b)) { + coordinates.replace(b, c); + if (ConfigManager.getConfig().isPresent()) { + ConfigManager.getConfig().get().globalConfig.setButton(b, c); + } + } + } + + @Override + public void activate(MinecraftClient client) { + this.toggle(); + if (ConfigManager.getConfig().get().isModuleEnabled(this.getModuleName())) { + client.openScreen(new PModMenuScreen()); + } else { + client.openScreen(null); + } + } + + /** + * Gets buttons. + * + * @return the buttons + */ + public static Map getButtons() { + return coordinates; + } +} \ No newline at end of file diff --git a/remappedSrc/pm/j4/petroleum/modules/splash/SplashText.java b/remappedSrc/pm/j4/petroleum/modules/splash/SplashText.java new file mode 100644 index 0000000..c5c60ae --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/modules/splash/SplashText.java @@ -0,0 +1,56 @@ +package pm.j4.petroleum.modules.splash; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.options.KeyBinding; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.gui.PModuleConfigEntry; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.ModuleBase; +import pm.j4.petroleum.util.module.option.BooleanOption; +import pm.j4.petroleum.util.module.option.ConfigurationOption; +import pm.j4.petroleum.util.module.option.KeybindOption; + +/** + * The type Splash text. + */ +public class SplashText extends ModuleBase { + /** + * Instantiates a new Splash text. + */ + public SplashText() { + super("petroleum.splashtext", + "petroleum.misc", + false, + true, + true); + } + + @Override + public List getConfigEntries() { + List entries = new ArrayList<>(); + ConfigurationOption activeToggle = new BooleanOption("Show the main menu version text:"); + PModuleConfigEntry activeEntry = new PModuleConfigEntry(activeToggle, new LiteralText("Active")); + entries.add(activeEntry); + return entries; + } + + /** + * Get string. + * + * @return the string + */ + public static String get() { + if (PetroleumMod.modData != null) { + return "Petroleum v" + PetroleumMod.modData.getVersion().getFriendlyString(); + } + return "Petroleum vUnknown"; + } +} diff --git a/remappedSrc/pm/j4/petroleum/modules/xray/Xray.java b/remappedSrc/pm/j4/petroleum/modules/xray/Xray.java new file mode 100644 index 0000000..7e31116 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/modules/xray/Xray.java @@ -0,0 +1,19 @@ +package pm.j4.petroleum.modules.xray; + +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Xray. + */ +public class Xray extends ModuleBase { + /** + * Instantiates a new Xray. + */ + public Xray() { + super("petroleum.xray", + "petroleum.render", + true, + false, + true); + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/config/Config.java b/remappedSrc/pm/j4/petroleum/util/config/Config.java new file mode 100644 index 0000000..695be65 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/config/Config.java @@ -0,0 +1,59 @@ +package pm.j4.petroleum.util.config; + +import java.util.ArrayList; +import java.util.List; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Config. + */ +public abstract class Config { + /** + * The Enabled modules. + */ + public List enabledModules = new ArrayList<>(); + + /** + * Is enabled boolean. + * + * @param mod the mod + * @return the boolean + */ + public boolean isEnabled(String mod) { + return enabledModules.contains(mod); + } + + + /** + * Disable module. + * + * @param mod the mod + */ + public void disableModule(String mod) { + if (isEnabled(mod) && PetroleumMod.isActive(mod) && PetroleumMod.getMod(mod).isPresent()) { + ModuleBase moduleInfo = PetroleumMod.getMod(mod).get(); + if (moduleInfo.isActivatable()) { + enabledModules.remove(mod); + } + } + } + + /** + * Toggle module. + * + * @param mod the mod + */ + public void toggleModule(String mod) { + if (PetroleumMod.isActive(mod) && PetroleumMod.getMod(mod).isPresent()) { + ModuleBase moduleInfo = PetroleumMod.getMod(mod).get(); + if (moduleInfo.isActivatable()) { + if (isEnabled(mod)) { + enabledModules.remove(mod); + } else { + enabledModules.add(mod); + } + } + } + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/config/ConfigHolder.java b/remappedSrc/pm/j4/petroleum/util/config/ConfigHolder.java new file mode 100644 index 0000000..531e90c --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/config/ConfigHolder.java @@ -0,0 +1,102 @@ +package pm.j4.petroleum.util.config; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Config holder. + */ +public class ConfigHolder { + /** + * The Global config. + */ + public GlobalConfig globalConfig; + /** + * The Server configs. + */ + public Map serverConfigs; + + /** + * Is module enabled boolean. + * + * @param module the module + * @return the boolean + */ + public boolean isModuleEnabled(String module) { + + if (!PetroleumMod.isActive(module)) { + return false; + } + if (globalConfig.isEnabled(module)) { + return true; + } + String server = this.getServer(); + if (serverConfigs.containsKey(server)) { + return serverConfigs.get(server).isEnabled(module); + } + return false; + } + + /** + * Gets enabled modules. + * + * @return the enabled modules + */ + public List getEnabledModules() { + List modules = PetroleumMod.getActiveMods(); + return modules.stream().filter(module -> + isModuleEnabled(module.getModuleName()) + ).collect(Collectors.toList()); + } + + /** + * Gets server. + * + * @return the server + */ + public String getServer() { + return PetroleumMod.getServerAddress(); + } + + /** + * Toggle module. + * + * @param module the module + */ + public void toggleModule(String module) { + String server = this.getServer(); + if (serverConfigs.containsKey(server)) { + System.out.println("Toggling module " + module + " on server " + server); + serverConfigs.get(server).toggleModule(module); + } else { + globalConfig.toggleModule(module); + } + } + + /** + * Disable module. + * + * @param module the module + */ + public void disableModule(String module) { + String server = this.getServer(); + if (serverConfigs.containsKey(server)) { + System.out.println("disabling module " + module + " on server " + server); + serverConfigs.get(server).disableModule(module); + } else { + globalConfig.disableModule(module); + } + } + + /** + * Save module. + * + * @param module the module + */ + public static void saveModule(ModuleBase module) { + + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/config/ConfigManager.java b/remappedSrc/pm/j4/petroleum/util/config/ConfigManager.java new file mode 100644 index 0000000..f44e8b6 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/config/ConfigManager.java @@ -0,0 +1,270 @@ +package pm.j4.petroleum.util.config; + +import com.google.common.reflect.TypeToken; +import com.google.gson.*; +import java.io.*; +import java.lang.reflect.Type; +import java.util.*; +import net.fabricmc.loader.api.FabricLoader; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.modules.bindings.BindingInfo; +import pm.j4.petroleum.modules.menu.ModMenu; +import pm.j4.petroleum.util.data.ButtonInformation; +import pm.j4.petroleum.util.data.ModuleConfig; +import pm.j4.petroleum.util.data.OptionSerializiable; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Config manager. + */ +public class ConfigManager { + /** + * The constant GSON. + */ + public static final Gson GSON = new GsonBuilder() + .registerTypeAdapter(GlobalConfig.class, SerializationHelper.getGlobalSerializer()) + .registerTypeAdapter(GlobalConfig.class, SerializationHelper.getGlobalDeserializer()) + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().create(); + /** + * The constant config. + */ + private static ConfigHolder config; + + /** + * Prepare config file. + * + * @param path the path + * @param filename the filename + * @return the file + */ + private static File prepareConfigFile(String path, String filename) { + if (path != "") { + File directory = new File(FabricLoader.getInstance().getConfigDir().toString(), path); + if (!directory.exists()) directory.mkdir(); + } + return new File(FabricLoader.getInstance().getConfigDir().toString(), path + filename); + } + + /** + * Init config. + */ + public static void initConfig() { + if (config != null) { + return; + } + + config = new ConfigHolder(); + config.globalConfig = new DefaultConfig(); + config.serverConfigs = new HashMap<>(); + + config = load("petroleum/", "petroleum.json", ConfigHolder.class); + initModules(); + } + + /** + * Init modules. + */ + public static void initModules() { + PetroleumMod.getActiveMods().forEach(module -> { + ModuleConfig options = load("petroleum/modules/", module.getModuleName() + ".json", ModuleConfig.class); + if (options != null && options.options != null) { + options.options.forEach((key, option) -> { + if (module.hasOption(option.key)) { + module.setConfigOption(option.key, option.value); + } + }); + } + }); + } + + /** + * Load. + * + * @param the type parameter + * @param path the path + * @param filename the filename + * @param tClass the t class + * @return the t + */ + private static T load(String path, String filename, Class tClass) { + File file = prepareConfigFile(path, filename); + + try { + if (!file.exists()) { + save(path, filename, tClass.newInstance()); + } + if (file.exists()) { + BufferedReader reader = new BufferedReader(new FileReader(file)); + T parsedConfig = null; + try { + parsedConfig = GSON.fromJson(reader, tClass); + } catch (Exception e) { + System.out.println("Couldn't parse config file"); + e.printStackTrace(); + } + if (parsedConfig != null) { + return parsedConfig; + } + } + } catch (FileNotFoundException | InstantiationException | IllegalAccessException e) { + System.out.println("Couldn't load configuration file at " + path); + e.printStackTrace(); + } + return null; + } + + /** + * Deserialize element t. + * + * @param the type parameter + * @param element the element + * @param tClass the t class + * @return the t + */ + public static T deserializeElement(JsonElement element, Class tClass) { + return GSON.fromJson(element, tClass); + } + + /** + * Save. + * + * @param the type parameter + * @param path the path + * @param filename the filename + * @param data the data + */ + private static void save(String path, String filename, T data) { + File file = prepareConfigFile(path, filename); + + String json = GSON.toJson(data); + try (FileWriter fileWriter = new FileWriter(file)) { + fileWriter.write(json); + } catch (IOException e) { + System.out.println("Couldn't save configuration file at " + path); + e.printStackTrace(); + } + } + + /** + * Save module. + * + * @param b the b + */ + public static void saveModule(ModuleBase b) { + ModuleConfig c = new ModuleConfig(); + c.options = GlobalConfig.serializeModuleConfiguration(b); + save("petroleum/modules/", b.getModuleName() + ".json", c); + } + + /** + * Save all modules. + */ + public static void saveAllModules() { + List mods = PetroleumMod.getActiveMods(); + mods.forEach(ConfigManager::saveModule); + } + + /** + * Save global config. + */ + public static void saveGlobalConfig() { + save("petroleum/", "petroleum.json", config); + } + + /** + * Gets config. + * + * @return the config + */ + public static Optional getConfig() { + if (config == null) { + return Optional.empty(); + } + return Optional.of(config); + } +} + +/** + * The type Serialization helper. + */ +class SerializationHelper { + + /** + * The constant s. + */ + private static final JsonSerializer GLOBAL_CONFIG_JSON_SERIALIZER = (src, typeOfSrc, ctx) -> { + JsonObject jsonConfig = new JsonObject(); + + JsonArray bindings = ctx.serialize(src.serializeBindings()).getAsJsonArray(); + jsonConfig.add("bindings", bindings); + + JsonArray modules = ctx.serialize(src.enabledModules).getAsJsonArray(); + jsonConfig.add("enabled_modules", modules); + + JsonObject tabCoordinates = new JsonObject(); + ModMenu.getButtons().forEach((category, coordinates) -> { + tabCoordinates.add(category, ctx.serialize(coordinates)); + }); + jsonConfig.add("button_coordinates", tabCoordinates); + + return jsonConfig; + }; + + /** + * The constant ds. + */ + private static final JsonDeserializer GLOBAL_CONFIG_JSON_DESERIALIZER = ((json, typeOfT, ctx) -> { + JsonObject obj = json.getAsJsonObject(); + + List bindings = new ArrayList<>(); + if (obj.has("bindings")) { + obj.get("bindings").getAsJsonArray().forEach(b -> bindings.add(ctx.deserialize(b, BindingInfo.class))); + } + List modules = new ArrayList<>(); + if (obj.has("enabled_modules")) { + obj.get("enabled_modules").getAsJsonArray().forEach(m -> modules.add(m.getAsString())); + } + GlobalConfig cfg = new GlobalConfig(); + Map> options; + Type type = new TypeToken>>() { + }.getType(); + if (obj.has("module_configuration")) { + options = ctx.deserialize(obj.get("module_configuration"), type); + } else { + options = new HashMap<>(); + } + if (obj.has("button_coordinates")) { + obj.get("button_coordinates").getAsJsonObject().entrySet().forEach( + value -> { + cfg.setButton(value.getKey(), ctx.deserialize(value.getValue(), ButtonInformation.class)); + } + ); + } + PetroleumMod.getActiveMods().forEach(module -> { + if (options.containsKey(module.getModuleName())) { + cfg.deserializeModuleConfiguration(options.get(module.getModuleName()), module); + } + }); + cfg.deserializeBindings(bindings); + cfg.enabledModules = modules; + return cfg; + }); + + /** + * Gets serializer. + * + * @return the serializer + */ + public static JsonSerializer getGlobalSerializer() { + return GLOBAL_CONFIG_JSON_SERIALIZER; + } + + /** + * Gets deserializer. + * + * @return the deserializer + */ + public static JsonDeserializer getGlobalDeserializer() { + return GLOBAL_CONFIG_JSON_DESERIALIZER; + } +} \ No newline at end of file diff --git a/remappedSrc/pm/j4/petroleum/util/config/DefaultConfig.java b/remappedSrc/pm/j4/petroleum/util/config/DefaultConfig.java new file mode 100644 index 0000000..f50bea2 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/config/DefaultConfig.java @@ -0,0 +1,15 @@ +package pm.j4.petroleum.util.config; + +import java.util.Collections; + +/** + * The type Default config. + */ +public class DefaultConfig extends GlobalConfig { + /** + * Instantiates a new Default config. + */ + public DefaultConfig() { + this.enabledModules = Collections.singletonList("petroleum.splashtext"); + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/config/GlobalConfig.java b/remappedSrc/pm/j4/petroleum/util/config/GlobalConfig.java new file mode 100644 index 0000000..91d7b07 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/config/GlobalConfig.java @@ -0,0 +1,189 @@ +package pm.j4.petroleum.util.config; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import net.minecraft.client.options.KeyBinding; +import net.minecraft.client.util.InputUtil; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.modules.bindings.BindingInfo; +import pm.j4.petroleum.util.data.ButtonInformation; +import pm.j4.petroleum.util.data.OptionSerializiable; +import pm.j4.petroleum.util.module.ModuleBase; +import pm.j4.petroleum.util.module.option.ConfigurationOption; + +/** + * The type Global config. + */ +public class GlobalConfig extends Config { + /** + * The Bindings. + */ + public final Map bindings = new HashMap<>(); + + /** + * Is bound boolean. + * + * @param func the func + * @return the boolean + */ + public boolean isBound(ModuleBase func) { + AtomicBoolean found = new AtomicBoolean(false); + bindings.forEach((key, binding) -> { + if (binding.equals(func)) { + found.set(true); + } + }); + return found.get(); + } + + /** + * Sets binding. + * + * @param bind the bind + * @param func the func + */ + public void setBinding(KeyBinding bind, ModuleBase func) { + if (bindings.containsValue(func)) { + bindings.forEach((key, binding) -> { + if (binding.equals(func)) { + PetroleumMod.removeBind(key); + bindings.remove(key); + } + }); + } + + if (PetroleumMod.isActive(func.getModuleName())) { + PetroleumMod.addBind(bind); + bindings.put(bind, func); + } + } + + /** + * Convert binding. + * + * @param info the info + */ + private void convertBinding(BindingInfo info) { + Optional match = PetroleumMod.getMod(info.attachedModuleName); + match.ifPresent(moduleBase -> setBinding(reconstructBinding(info), + moduleBase)); + } + + /** + * Reconstruct binding key binding. + * + * @param info the info + * @return the key binding + */ + public static KeyBinding reconstructBinding(BindingInfo info) { + return new KeyBinding( + info.translationKey, + info.type, + info.key, + info.category + ); + } + + /** + * Extract binding info. + * + * @param b the b + * @param f the f + * @return the binding info + */ + public static BindingInfo extractBinding(KeyBinding b, ModuleBase f) { + BindingInfo res = new BindingInfo(); + res.attachedModuleName = f.getModuleName(); + + res.translationKey = b.getTranslationKey(); + InputUtil.Key k = b.getDefaultKey(); + res.type = k.getCategory(); + res.key = k.getCode(); + res.category = b.getCategory(); + + return res; + } + + /** + * Serialize bindings list. + * + * @return the list + */ + public List serializeBindings() { + List b = new ArrayList<>(); + bindings.forEach((k, f) -> b.add(extractBinding(k, f))); + return b; + } + + /** + * Deserialize bindings. + * + * @param info the info + */ + public void deserializeBindings(List info) { + info.forEach(this::convertBinding); + } + + /** + * Serialize module configuration list. + * + * @param module the module + * @return the list + */ + public static Map serializeModuleConfiguration(ModuleBase module) { + Map opts = new HashMap<>(); + Map configuration = module.getModuleConfiguration(); + configuration.forEach((key, value) -> { + opts.put(key, new OptionSerializiable(key, value.toJson())); + }); + return opts; + } + + /** + * Deserialize module configuration. + * + * @param opts the opts + * @param module the module + */ + public void deserializeModuleConfiguration(List opts, ModuleBase module) { + opts.forEach(option -> { + if (module.hasOption(option.key)) { + module.setConfigOption(option.key, option.value); + } + }); + } + + /** + * The Button locations. + */ + private final Map buttonLocations = new HashMap<>(); + + /** + * Sets button. + * + * @param category the category + * @param buttonInformation the button information + */ + public void setButton(String category, ButtonInformation buttonInformation) { + if (buttonLocations.containsKey(category)) { + buttonLocations.replace(category, buttonInformation); + } else { + buttonLocations.put(category, buttonInformation); + } + } + + /** + * Gets button. + * + * @param category the category + * @return the button + */ + public ButtonInformation getButton(String category) { + if (buttonLocations.containsKey(category)) { + return buttonLocations.get(category); + } + System.out.println("Could not find button of category " + category); + return null; + } +} + diff --git a/remappedSrc/pm/j4/petroleum/util/config/ServerConfig.java b/remappedSrc/pm/j4/petroleum/util/config/ServerConfig.java new file mode 100644 index 0000000..9df6464 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/config/ServerConfig.java @@ -0,0 +1,11 @@ +package pm.j4.petroleum.util.config; + +/** + * The type Server config. + */ +public class ServerConfig extends Config { + /** + * The Address. + */ + public String address = ""; +} diff --git a/remappedSrc/pm/j4/petroleum/util/data/ButtonInformation.java b/remappedSrc/pm/j4/petroleum/util/data/ButtonInformation.java new file mode 100644 index 0000000..e4ff031 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/data/ButtonInformation.java @@ -0,0 +1,32 @@ +package pm.j4.petroleum.util.data; + +/** + * The type Button information. + */ +public class ButtonInformation { + /** + * The X. + */ + public double x; + /** + * The Y. + */ + public double y; + /** + * The Open. + */ + public boolean open; + + /** + * Instantiates a new Button information. + * + * @param x the x + * @param y the y + * @param open the open + */ + public ButtonInformation(double x, double y, boolean open) { + this.x = x; + this.y = y; + this.open = open; + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/data/Category.java b/remappedSrc/pm/j4/petroleum/util/data/Category.java new file mode 100644 index 0000000..c2210a5 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/data/Category.java @@ -0,0 +1,47 @@ +package pm.j4.petroleum.util.data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Category. + */ +public class Category { + /** + * Gets category map. + * + * @return the category map + */ + public static Map> getCategoryMap() { + List modules = PetroleumMod.getActiveMods(); + Map> categoryMap = new HashMap<>(); + modules.forEach(module -> { + if (!categoryMap.containsKey(module.getCategory())) { + List m = new ArrayList<>(); + m.add(module); + categoryMap.put(module.getCategory(), m); + } else { + List m = categoryMap.get(module.getCategory()); + List nm = new ArrayList<>(); + nm.addAll(m); + nm.add(module); + categoryMap.replace(module.getCategory(), nm); + } + }); + return categoryMap; + } + + /** + * Gets by category. + * + * @param category the category + * @return the by category + */ + public static List getByCategory(String category) { + return getCategoryMap().containsKey(category) ? getCategoryMap().get(category) : new ArrayList<>(); + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/data/ModuleConfig.java b/remappedSrc/pm/j4/petroleum/util/data/ModuleConfig.java new file mode 100644 index 0000000..33c1365 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/data/ModuleConfig.java @@ -0,0 +1,13 @@ +package pm.j4.petroleum.util.data; + +import java.util.Map; + +/** + * The type Module config. + */ +public class ModuleConfig { + /** + * The Options. + */ + public Map options; +} diff --git a/remappedSrc/pm/j4/petroleum/util/data/OptionSerializiable.java b/remappedSrc/pm/j4/petroleum/util/data/OptionSerializiable.java new file mode 100644 index 0000000..197332f --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/data/OptionSerializiable.java @@ -0,0 +1,28 @@ +package pm.j4.petroleum.util.data; + +import com.google.gson.JsonElement; + +/** + * The type Option serializiable. + */ +public class OptionSerializiable { + /** + * Instantiates a new Option serializiable. + * + * @param key the key + * @param value the value + */ + public OptionSerializiable(String key, JsonElement value) { + this.value = value; + this.key = key; + } + + /** + * The Value. + */ + public final JsonElement value; + /** + * The Key. + */ + public final String key; +} diff --git a/remappedSrc/pm/j4/petroleum/util/module/ModuleBase.java b/remappedSrc/pm/j4/petroleum/util/module/ModuleBase.java new file mode 100644 index 0000000..514405c --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/module/ModuleBase.java @@ -0,0 +1,229 @@ +package pm.j4.petroleum.util.module; + +import com.google.gson.JsonElement; +import java.util.*; +import net.minecraft.client.MinecraftClient; +import net.minecraft.text.TranslatableText; +import pm.j4.petroleum.gui.PModuleConfigEntry; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.option.ConfigurationOption; + +/** + * The Basis for all mods, used so that modules all have a common activation point and settings. + */ +public abstract class ModuleBase { + + /** + * Instantiates a new Module base. + * Parameters should be constant across restarts. + * + * @param name The name of the module + * @param category the category + * @param activatable Whether a module can be activated, or if it will remain in the state it was upon startup + * @param hidden Whether the module will show up in @link pm.j4.petroleum.modules.menu.ModMenu or the active module list + * @param hasConfigMenu whether a button in the configuration menu will show + */ + public ModuleBase(String name, String category, boolean activatable, boolean hidden, boolean hasConfigMenu) { + this.moduleName = name; + this.category = category; + this.readableName = new TranslatableText(name); + this.activatable = activatable; + this.hidden = hidden; + this.hasConfigMenu = hasConfigMenu; + this.moduleOptions = this.getDefaultConfig(); + } + + /** + * Init. + */ + public void init() { + + } + + /** + * Activate. Should be overridden. + * + * @param client the client + */ + public void activate(MinecraftClient client) { + this.toggle(); + } + + /** + * Toggle mod. + */ + public void toggle() { + Optional config = ConfigManager.getConfig(); + config.ifPresent(configHolder -> configHolder.toggleModule(this.moduleName)); + } + + /** + * The Module's name. + */ + private final String moduleName; + + /** + * Gets module name. + * + * @return the module name + */ + public String getModuleName() { + return this.moduleName; + } + + /** + * The Category. + */ + private final String category; + + /** + * Gets category. + * + * @return the category + */ + public String getCategory() { + return this.category; + } + + /** + * The Readable name. + */ + private final TranslatableText readableName; + + /** + * Gets readable name. + * + * @return the readable name + */ + public TranslatableText getReadableName() { + return this.readableName; + } + + /** + * The Activatable. + */ + private final boolean activatable; + + /** + * Is activatable boolean. + * + * @return the boolean + */ + public boolean isActivatable() { + return activatable; + } + + /** + * The Hidden. + */ + private final boolean hidden; + + /** + * Is hidden boolean. + * + * @return the boolean + */ + public boolean isHidden() { + return hidden; + } + + + /** + * The Has config menu. + */ + private final boolean hasConfigMenu; + + /** + * Configurable boolean. + * + * @return the boolean + */ + public boolean configurable() { + return hasConfigMenu; + } + + /** + * The Module options. + */ + private final Map moduleOptions; + + /** + * Gets module configuration. + * + * @return the module configuration + */ + public Map getModuleConfiguration() { + return moduleOptions; + } + + /** + * Sets config option. + * This will fail if the option is not already present in a module. + *

+ * + * @param key the key + * @param value the value + * @return whether the operation was successful. + */ + public boolean setConfigOption(String key, JsonElement value) { + if (moduleOptions.containsKey(key)) { + moduleOptions.get(key).fromJson(value); + return true; + } + return false; + } + + /** + * Has option boolean. + * + * @param key the key + * @return the boolean + */ + public boolean hasOption(String key) { + return moduleOptions.containsKey(key); + } + + /** + * Gets default config. + * + * @return the default config + */ + protected Map getDefaultConfig() { + return new HashMap<>(); + } + + /** + * Gets config option. + * + * @param key the key + * @return the config option + */ + public Optional getConfigOption(String key) { + if (moduleOptions.containsKey(key)) { + return Optional.of(moduleOptions.get(key)); + } + return Optional.empty(); + } + + /** + * Gets config entries. + * + * @return the config entries + */ + public List getConfigEntries() { + List entries = new ArrayList<>(); + this.getModuleConfiguration().forEach((name, option) -> entries.add(new PModuleConfigEntry(option, new TranslatableText(name)))); + return entries; + } + + /** + * Equals boolean. + * + * @param other the other + * @return the boolean + */ + public boolean equals(ModuleBase other) { + return Objects.equals(this.moduleName, other.getModuleName()); + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/module/option/BooleanOption.java b/remappedSrc/pm/j4/petroleum/util/module/option/BooleanOption.java new file mode 100644 index 0000000..1a33c41 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/module/option/BooleanOption.java @@ -0,0 +1,38 @@ +package pm.j4.petroleum.util.module.option; + +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; + +/** + * The type Boolean value. + */ +public class BooleanOption extends ConfigurationOption { + /** + * The Value. + */ + private boolean value; + + /** + * Instantiates a new Boolean option. + * + * @param description the description + */ + public BooleanOption(String description) { + super(description); + } + + @Override + public String getStringValue() { + return Boolean.toString(value); + } + + @Override + public void fromJson(JsonElement e) { + this.value = e.getAsBoolean(); + } + + @Override + public JsonElement toJson() { + return new JsonPrimitive(value); + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/module/option/ConfigurationOption.java b/remappedSrc/pm/j4/petroleum/util/module/option/ConfigurationOption.java new file mode 100644 index 0000000..629cc35 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/module/option/ConfigurationOption.java @@ -0,0 +1,59 @@ +package pm.j4.petroleum.util.module.option; + +import com.google.gson.JsonElement; + +/** + * The type Configuration option. + */ +public abstract class ConfigurationOption { + /** + * The Description. + */ + private final String description; + + /** + * Instantiates a new Configuration option. + * + * @param description the description + */ + protected ConfigurationOption(String description) { + this.description = description; + } + + /** + * Gets description. + * + * @return the description + */ + public final String getDescription() { + return this.description; + } + + /** + * Gets string value. + * + * @return the string value + */ + public abstract String getStringValue(); + + /** + * From json. + * + * @param e the e + */ + public abstract void fromJson(JsonElement e); + + /** + * To json json element. + * + * @return the json element + */ + public abstract JsonElement toJson(); + + /** + * Update. + */ + public void update() { + + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/module/option/IntegerOption.java b/remappedSrc/pm/j4/petroleum/util/module/option/IntegerOption.java new file mode 100644 index 0000000..b39718d --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/module/option/IntegerOption.java @@ -0,0 +1,38 @@ +package pm.j4.petroleum.util.module.option; + +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; + +/** + * The type Integer value. + */ +public class IntegerOption extends ConfigurationOption { + /** + * The Value. + */ + private int value; + + /** + * Instantiates a new Integer option. + * + * @param description the description + */ + protected IntegerOption(String description) { + super(description); + } + + @Override + public String getStringValue() { + return Integer.toString(value); + } + + @Override + public void fromJson(JsonElement e) { + this.value = e.getAsInt(); + } + + @Override + public JsonElement toJson() { + return new JsonPrimitive(value); + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/module/option/KeybindOption.java b/remappedSrc/pm/j4/petroleum/util/module/option/KeybindOption.java new file mode 100644 index 0000000..b39f6ab --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/module/option/KeybindOption.java @@ -0,0 +1,60 @@ +package pm.j4.petroleum.util.module.option; + +import com.google.gson.JsonElement; +import net.minecraft.client.options.KeyBinding; +import pm.j4.petroleum.modules.bindings.BindingInfo; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.config.GlobalConfig; +import pm.j4.petroleum.util.module.ModuleBase; + +/** + * The type Keybind value. + */ +public class KeybindOption extends ConfigurationOption { + + /** + * The Value. + */ + private KeyBinding value; + /** + * The Converted value. + */ + private BindingInfo convertedValue; + + /** + * Instantiates a new Keybind option. + * + * @param description the description + */ + public KeybindOption(String description) { + super(description); + } + + @Override + public String getStringValue() { + return value.getDefaultKey().getLocalizedText().getString(); + } + + @Override + public void fromJson(JsonElement e) { + BindingInfo bindingInfo = ConfigManager.deserializeElement(e, BindingInfo.class); + this.convertedValue = bindingInfo; + this.value = GlobalConfig.reconstructBinding(bindingInfo); + } + + @Override + public JsonElement toJson() { + return null; + } + + /** + * From keybind. + * + * @param bind the bind + * @param base the base + */ + public void fromKeybind(KeyBinding bind, ModuleBase base) { + this.value = bind; + this.convertedValue = GlobalConfig.extractBinding(bind, base); + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/module/option/ListOption.java b/remappedSrc/pm/j4/petroleum/util/module/option/ListOption.java new file mode 100644 index 0000000..2b37c29 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/module/option/ListOption.java @@ -0,0 +1,32 @@ +package pm.j4.petroleum.util.module.option; + +import com.google.gson.JsonElement; + +/** + * The type List option. + */ +public class ListOption extends ConfigurationOption { + /** + * Instantiates a new List option. + * + * @param description the description + */ + protected ListOption(String description) { + super(description); + } + + @Override + public String getStringValue() { + return "ListObject"; + } + + @Override + public void fromJson(JsonElement e) { + + } + + @Override + public JsonElement toJson() { + return null; + } +} diff --git a/remappedSrc/pm/j4/petroleum/util/module/option/StringOption.java b/remappedSrc/pm/j4/petroleum/util/module/option/StringOption.java new file mode 100644 index 0000000..174d056 --- /dev/null +++ b/remappedSrc/pm/j4/petroleum/util/module/option/StringOption.java @@ -0,0 +1,38 @@ +package pm.j4.petroleum.util.module.option; + +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; + +/** + * The type String value. + */ +public class StringOption extends ConfigurationOption { + + /** + * The Value. + */ + private String value; + + /** + * Instantiates a new String option. + * + * @param description the description + */ + protected StringOption(String description) { + super(description); + } + + public String getStringValue() { + return value; + } + + @Override + public void fromJson(JsonElement e) { + this.value = e.getAsString(); + } + + @Override + public JsonElement toJson() { + return new JsonPrimitive(value); + } +} diff --git a/src/main/java/pm/j4/petroleum/PetroleumMod.java b/src/main/java/pm/j4/petroleum/PetroleumMod.java index bba2464..ce543eb 100644 --- a/src/main/java/pm/j4/petroleum/PetroleumMod.java +++ b/src/main/java/pm/j4/petroleum/PetroleumMod.java @@ -17,6 +17,7 @@ import pm.j4.petroleum.modules.bindings.BindingManager; import pm.j4.petroleum.modules.list.ModList; import pm.j4.petroleum.modules.menu.ModMenu; import pm.j4.petroleum.modules.splash.SplashText; +import pm.j4.petroleum.modules.xray.Xray; import pm.j4.petroleum.util.config.ConfigHolder; import pm.j4.petroleum.util.config.ConfigManager; import pm.j4.petroleum.util.module.ModuleBase; @@ -54,7 +55,8 @@ public class PetroleumMod implements ModInitializer { new ModMenu(), new ModList(), new BindingManager(), - new ExampleModule() + new ExampleModule(), + new Xray() ); /** @@ -135,10 +137,10 @@ public class PetroleumMod implements ModInitializer { } return null; } - + @Override public void onInitialize() { - + ConfigManager.initConfig(); // always update mod data diff --git a/src/main/java/pm/j4/petroleum/gui/PModMenuScreen.java b/src/main/java/pm/j4/petroleum/gui/PModMenuScreen.java index e9eac22..4ea2711 100644 --- a/src/main/java/pm/j4/petroleum/gui/PModMenuScreen.java +++ b/src/main/java/pm/j4/petroleum/gui/PModMenuScreen.java @@ -7,7 +7,6 @@ import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexFormats; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.LiteralText; import net.minecraft.text.TranslatableText; import pm.j4.petroleum.modules.menu.ModMenu; import pm.j4.petroleum.util.config.ConfigManager; @@ -22,12 +21,11 @@ public class PModMenuScreen extends Screen { * Instantiates a new P mod menu screen. */ public PModMenuScreen() { - super(new TranslatableText("petroleum.modlist")); + super(new TranslatableText("petroleum.modmenu")); } @Override public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { - this.client.textRenderer.drawWithShadow(matrices, new LiteralText("Menu Open"), 10, 50, -1); this.renderBackground(matrices); super.render(matrices, mouseX, mouseY, delta); } diff --git a/src/main/java/pm/j4/petroleum/gui/PModuleConfigEntry.java b/src/main/java/pm/j4/petroleum/gui/PModuleConfigEntry.java index 7a16310..0d99ed0 100644 --- a/src/main/java/pm/j4/petroleum/gui/PModuleConfigEntry.java +++ b/src/main/java/pm/j4/petroleum/gui/PModuleConfigEntry.java @@ -1,34 +1,109 @@ package pm.j4.petroleum.gui; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.widget.EntryListWidget; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.widget.AbstractButtonWidget; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.ElementListWidget; +import net.minecraft.client.options.KeyBinding; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.option.BooleanOption; import pm.j4.petroleum.util.module.option.ConfigurationOption; +import pm.j4.petroleum.util.module.option.KeybindOption; +import pm.j4.petroleum.util.module.option.ListOption; /** * The type P module config entry. */ -public class PModuleConfigEntry extends EntryListWidget.Entry { +public class PModuleConfigEntry extends ElementListWidget.Entry { /** * The Option. */ - protected final ConfigurationOption option; + protected ConfigurationOption option; /** * The Display text. */ protected final Text displayText; + private PModuleConfigPane parent; + + private List elements = new ArrayList<>(); + + private String trueValue; + private String falseValue; + + private Element selected; + /** * Instantiates a new P module config entry. * * @param option the option * @param text the text */ - public PModuleConfigEntry(ConfigurationOption option, Text text) { + public PModuleConfigEntry(ConfigurationOption option, Text text, PModuleConfigPane parent) { this.option = option; this.displayText = text; + this.parent = parent; + this.trueValue = "Yes"; + this.falseValue = "No"; + } + + public PModuleConfigEntry(ConfigurationOption option, Text text, PModuleConfigPane parent, String trueValue, String falseValue) { + this.option = option; + this.displayText = text; + this.parent = parent; + this.trueValue = trueValue; + this.falseValue = falseValue; + } + + @Override + public List children() { + return elements; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (this.isMouseOver(mouseX, mouseY)) { + this.parent.setSelected(this); + System.out.println(displayText.getString() + " clicked"); + String className = option.getClass().toString(); + elements.forEach((widget) -> { + if (widget.mouseClicked(mouseX, mouseY, button)) { + System.out.println("Button clicked"); + selected = widget; + } + }); + return true; + } + return false; + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + return this.isMouseOver(mouseX, mouseY); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if(this.selected != null) { + return this.selected.keyPressed(keyCode, scanCode, modifiers); + } + return false; + } + + @Override + public boolean keyReleased(int keyCode, int scanCode, int modifiers) { + if(this.selected != null) { + return this.selected.keyReleased(keyCode, scanCode, modifiers); + } + return false; } @Override @@ -36,12 +111,84 @@ public class PModuleConfigEntry extends EntryListWidget.Entry { + button.setMessage(new LiteralText((!((BooleanOption)option).getValue()) ? this.trueValue : this.falseValue)); + BooleanOption newValue = new BooleanOption(option.getConfigKey(), option.getDescription(), option.getParent()); + newValue.setValue((!((BooleanOption)option).getValue())); + option.getParent().updateConfigOption(newValue.getConfigKey(), newValue); + this.option = newValue; + })); + } + else if (className.equals(ListOption.class.toString())) { + // TODO: determine whether list options are viable, + // considering that it would be easier to split lists into multiple PModuleConfigEntries + System.out.println("list"); + } + else if (className.equals(KeybindOption.class.toString())) { + System.out.println("keybind"); + ButtonWidget bindButton = new ButtonWidget(x, y + (int)(fontHeight * 2.5), + entryWidth, + fontHeight * 2, + new LiteralText(option.getStringValue().toUpperCase()), (button) -> { + button.setMessage(new LiteralText("Press any key...")); + }) { + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (this.active && this.visible) { + //TODO + if (keyCode != 257 && keyCode != 32 && keyCode != 335) { + KeybindOption newValue = new KeybindOption(option.getConfigKey(), option.getDescription(), option.getParent()); + KeyBinding bind = new KeyBinding(((KeybindOption)option).getTranslationKey(), keyCode, "category.petroleum"); + newValue.fromKeybind(bind, option.getParent()); + Optional config = ConfigManager.getConfig(); + assert config.isPresent(); + config.get().globalConfig.setBinding(bind, option.getParent()); + option = newValue; + this.setMessage(new LiteralText(option.getStringValue().toUpperCase())); + selected = null; + return false; + } else { + this.playDownSound(MinecraftClient.getInstance().getSoundManager()); + this.onPress(); + return true; + } + } else { + return false; + } + } + }; + elements.add(bindButton); + } + else { + System.out.println("other/string"); + //TODO + } + } + else { + elements.forEach((widget) -> { + if (widget instanceof AbstractButtonWidget) { + ((AbstractButtonWidget)widget).render(matrices, mouseX, mouseY, tickDelta); + } + }); + } } } } \ No newline at end of file diff --git a/src/main/java/pm/j4/petroleum/gui/PModuleConfigPane.java b/src/main/java/pm/j4/petroleum/gui/PModuleConfigPane.java index 72273ba..a5242fd 100644 --- a/src/main/java/pm/j4/petroleum/gui/PModuleConfigPane.java +++ b/src/main/java/pm/j4/petroleum/gui/PModuleConfigPane.java @@ -4,6 +4,7 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.widget.ElementListWidget; import net.minecraft.client.gui.widget.EntryListWidget; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; @@ -13,7 +14,7 @@ import net.minecraft.client.util.math.MatrixStack; /** * The type P module config pane. */ -public class PModuleConfigPane extends EntryListWidget { +public class PModuleConfigPane extends ElementListWidget { /** * The Parent. */ @@ -23,6 +24,8 @@ public class PModuleConfigPane extends EntryListWidget { */ private POptionEntry lastSelected; + private PModuleConfigEntry selectedConfigEntry; + /** * Instantiates a new P module config pane. * @@ -37,15 +40,15 @@ public class PModuleConfigPane extends EntryListWidget { public PModuleConfigPane(MinecraftClient client, int width, int height, int top, int bottom, int entryHeight, POptionsScreen screen) { super(client, width, height, top, bottom, entryHeight); this.parent = screen; - /** - * The Text renderer. - */ - TextRenderer textRenderer = client.textRenderer; + } + + public void setSelected(PModuleConfigEntry entry) { + selectedConfigEntry = entry; } @Override public PModuleConfigEntry getSelected() { - return null; + return selectedConfigEntry; } @Override @@ -67,7 +70,7 @@ public class PModuleConfigPane extends EntryListWidget { setScrollAmount(-Double.MAX_VALUE); String id = lastSelected.getModId(); if (lastSelected != null && id != null && !id.isEmpty()) { - children().addAll(lastSelected.module.getConfigEntries()); + children().addAll(lastSelected.module.getConfigEntries(this)); } } @@ -85,15 +88,17 @@ public class PModuleConfigPane extends EntryListWidget { RenderSystem.shadeModel(7425); RenderSystem.disableTexture(); - buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR); - buffer.vertex(this.left, (this.top + 4), 0.0D).texture(0.0F, 1.0F).color(0, 0, 0, 0).next(); - buffer.vertex(this.right, (this.top + 4), 0.0D).texture(1.0F, 1.0F).color(0, 0, 0, 0).next(); - buffer.vertex(this.right, this.top, 0.0D).texture(1.0F, 0.0F).color(0, 0, 0, 255).next(); - buffer.vertex(this.left, this.top, 0.0D).texture(0.0F, 0.0F).color(0, 0, 0, 255).next(); - buffer.vertex(this.left, this.bottom, 0.0D).texture(0.0F, 1.0F).color(0, 0, 0, 255).next(); - buffer.vertex(this.right, this.bottom, 0.0D).texture(1.0F, 1.0F).color(0, 0, 0, 255).next(); - buffer.vertex(this.right, (this.bottom - 4), 0.0D).texture(1.0F, 0.0F).color(0, 0, 0, 0).next(); - buffer.vertex(this.left, (this.bottom - 4), 0.0D).texture(0.0F, 0.0F).color(0, 0, 0, 0).next(); + // darken config pane area + + buffer.begin(7, VertexFormats.POSITION_COLOR_TEXTURE); + buffer.vertex(this.left, (this.top + 4), 0.0D).color(0, 0, 0, 0).texture(0.0F, 1.0F).next(); + buffer.vertex(this.right, (this.top + 4), 0.0D).color(0, 0, 0, 0).texture(1.0F, 1.0F).next(); + buffer.vertex(this.right, this.top, 0.0D).color(0, 0, 0, 255).texture(1.0F, 0.0F).next(); + buffer.vertex(this.left, this.top, 0.0D).color(0, 0, 0, 255).texture(0.0F, 0.0F).next(); + buffer.vertex(this.left, this.bottom, 0.0D).color(0, 0, 0, 255).texture(0.0F, 1.0F).next(); + buffer.vertex(this.right, this.bottom, 0.0D).color(0, 0, 0, 255).texture(1.0F, 1.0F).next(); + buffer.vertex(this.right, (this.bottom - 4), 0.0D).color(0, 0, 0, 0).texture(1.0F, 0.0F).next(); + buffer.vertex(this.left, (this.bottom - 4), 0.0D).color(0, 0, 0, 0).texture(0.0F, 0.0F).next(); t_1.draw(); buffer.begin(7, VertexFormats.POSITION_COLOR); diff --git a/src/main/java/pm/j4/petroleum/gui/PMovableButton.java b/src/main/java/pm/j4/petroleum/gui/PMovableButton.java index 7b55441..abcb8b3 100644 --- a/src/main/java/pm/j4/petroleum/gui/PMovableButton.java +++ b/src/main/java/pm/j4/petroleum/gui/PMovableButton.java @@ -59,8 +59,25 @@ public class PMovableButton extends AbstractButtonWidget { */ private int storedY; + /** + * The Spin. + */ + private double spin; + + /** + * The Arrow size. + */ + private final int arrowSize = 10; + + + /** + * The Category. + */ private final String category; + /** + * The Parent. + */ private final PModMenuScreen parent; /** @@ -70,11 +87,13 @@ public class PMovableButton extends AbstractButtonWidget { * @param y the y * @param categoryName the category name * @param modules the modules + * @param open the open + * @param parent the parent */ public PMovableButton(int x, int y, String categoryName, List modules, boolean open, PModMenuScreen parent) { super(x, y, 0, 0, new TranslatableText(categoryName)); this.category = categoryName; - int w = MinecraftClient.getInstance().textRenderer.getWidth(categoryName) + 8; + int w = MinecraftClient.getInstance().textRenderer.getWidth(new TranslatableText(categoryName)) + 8; int h = MinecraftClient.getInstance().textRenderer.fontHeight + 8; this.width = w; this.collapsedWidth = w; @@ -95,8 +114,29 @@ public class PMovableButton extends AbstractButtonWidget { super.onClick(mouseX, mouseY); } + /** + * On extra click. + * + * @param mouseX the mouse x + * @param mouseY the mouse y + */ private void onExtraClick(double mouseX, double mouseY) { System.out.println("extra click"); + int increment = this.moduleHeight + 4; + int location = (int)mouseY - (this.y + this.collapsedHeight); + int index = location / increment; + System.out.println("index: " + index); + if(modules.size() >= index) { + ModuleBase affectedModule = modules.get(index); + System.out.println("module: " + affectedModule); + if(affectedModule.isActivatable()) { + System.out.println("toggling"); + affectedModule.toggle(); + } + } + else { + System.out.println("index too great"); + } //TODO module things } @@ -123,6 +163,9 @@ public class PMovableButton extends AbstractButtonWidget { this.updateCoordinate(); } + /** + * Update coordinate. + */ public void updateCoordinate() { ModMenu.updateCoord(this.category, new ButtonInformation((this.x / (double) parent.width), (this.y / (double) parent.height), this.expanded)); } @@ -186,7 +229,8 @@ public class PMovableButton extends AbstractButtonWidget { if (this.expandedWidth == 0 || this.expandedHeight == 0) { this.expandedHeight = this.collapsedHeight + ((this.moduleHeight + 4) * modules.size()); modules.forEach(module -> { - int w = MinecraftClient.getInstance().textRenderer.getWidth(module.getReadableName()) + 8; + this.expandedWidth = this.width; + int w = MinecraftClient.getInstance().textRenderer.getWidth(module.getReadableName()) + arrowSize + 8; if (w > this.expandedWidth) { this.expandedWidth = w; } @@ -204,7 +248,6 @@ public class PMovableButton extends AbstractButtonWidget { RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha); RenderSystem.disableTexture(); - RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); float brightness = this.isFocused() ? 1.0F : 0.5F; RenderSystem.color4f(brightness, brightness, brightness, 1.0F); @@ -224,6 +267,14 @@ public class PMovableButton extends AbstractButtonWidget { RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F); drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, buttonTop - 1, buttonBottom + 1); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.9F); + drawEquilateralTriangle(t_1, buffer, matrix, 40, 40, 180, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 60, 60, 0, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 40, 60, 90, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 60, 40, 360, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 80, 40, 270, arrowSize); + drawEquilateralTriangle(t_1, buffer, matrix, 80, 60, 120, arrowSize); + int j = this.active ? 16777215 : 10526880; if (this.expanded) { if (this.width != this.expandedWidth || this.height != this.expandedHeight) { @@ -243,7 +294,6 @@ public class PMovableButton extends AbstractButtonWidget { int previousBottom = buttonBottom + (i * (this.moduleHeight + 4)); int currentBottom = buttonBottom + ((i + 1) * (this.moduleHeight + 4)); - RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F); drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, previousBottom + 1, currentBottom + 2); @@ -277,6 +327,44 @@ public class PMovableButton extends AbstractButtonWidget { drawCenteredText(matrices, textRenderer, this.getMessage(), this.x + this.width / 2, this.y + (this.collapsedHeight - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24); } + /** + * Draw equilateral triangle. + * + * @param t_1 the t 1 + * @param buffer the buffer + * @param matrix the matrix + * @param centerX the center x + * @param centerY the center y + * @param rotation the rotation + * @param distance the distance + */ + private void drawEquilateralTriangle(Tessellator t_1, BufferBuilder buffer, Matrix4f matrix, int centerX, int centerY, double rotation, int distance) { + double rotation2 = rotation + 120; + double rotation3 = rotation + 240; + int point1X = (int)(distance * Math.cos(Math.toRadians(rotation))) + centerX; + int point1Y = (int)(distance * Math.sin(Math.toRadians(rotation))) + centerY; + int point2X = (int)(distance * Math.cos(Math.toRadians(rotation2))) + centerX; + int point2Y = (int)(distance * Math.sin(Math.toRadians(rotation2))) + centerY; + int point3X = (int)(distance * Math.cos(Math.toRadians(rotation3))) + centerX; + int point3Y = (int)(distance * Math.sin(Math.toRadians(rotation3))) + centerY; + + //RenderSystem.enableBlend(); + RenderSystem.disableBlend(); + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(matrix, centerX, centerY, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, centerX, point1Y, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, point1X, point1Y, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next(); + + buffer.vertex(matrix, centerX, centerY, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, centerX, point2Y, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, point2X, point2Y, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next(); + + buffer.vertex(matrix, centerX, centerY, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, centerX, point3Y, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next(); + buffer.vertex(matrix, point3X, point3Y, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next(); + t_1.draw(); + } + /** * Draw box. * @@ -289,6 +377,7 @@ public class PMovableButton extends AbstractButtonWidget { * @param buttonBottom the button bottom */ private void drawBox(Tessellator t_1, BufferBuilder buffer, Matrix4f matrix, int buttonLeft, int buttonRight, int buttonTop, int buttonBottom) { + RenderSystem.enableBlend(); buffer.begin(7, VertexFormats.POSITION); buffer.vertex(matrix, buttonLeft, buttonBottom, 0.0F).next(); buffer.vertex(matrix, buttonRight, buttonBottom, 0.0F).next(); diff --git a/src/main/java/pm/j4/petroleum/gui/POptionsScreen.java b/src/main/java/pm/j4/petroleum/gui/POptionsScreen.java index f1f91a5..6384ac7 100644 --- a/src/main/java/pm/j4/petroleum/gui/POptionsScreen.java +++ b/src/main/java/pm/j4/petroleum/gui/POptionsScreen.java @@ -14,10 +14,7 @@ import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexFormats; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.LiteralText; -import net.minecraft.text.StringVisitable; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableText; +import net.minecraft.text.*; import pm.j4.petroleum.PetroleumMod; import pm.j4.petroleum.util.config.ConfigManager; import pm.j4.petroleum.util.module.ModuleBase; @@ -109,7 +106,6 @@ public class POptionsScreen extends Screen { } configurableModules.forEach(module -> this.modules.addEntry(new POptionEntry(module, this.modules))); this.addButton(new ButtonWidget(this.width / 2 - 75, this.height - 30, 150, 20, ScreenTexts.DONE, (buttonWidget) -> { - //TODO see PModMenuScreen ConfigManager.saveAllModules(); assert this.client != null; this.client.openScreen(this.previousScreen); @@ -142,7 +138,8 @@ public class POptionsScreen extends Screen { trimmedName = StringVisitable.concat(textRenderer.trimToWidth(name, maxNameWidth - textRenderer.getWidth(ellipsis)), ellipsis); } if (mouseX > x + offset && mouseY > paneY + 1 && mouseY < paneY + 1 + textRenderer.fontHeight && mouseX < x + offset + textRenderer.getWidth(trimmedName)) { - setTooltip(new LiteralText("Configure " + selected.getModName())); + //TODO tooltop + //selected.getModName() } textRenderer.draw(matrices, selected.getModName(), x + offset, paneY + 2 + lineSpacing, 0x808080); diff --git a/src/main/java/pm/j4/petroleum/mixin/ModMenuMixin.java b/src/main/java/pm/j4/petroleum/mixin/ModMenuMixin.java deleted file mode 100644 index 36b9851..0000000 --- a/src/main/java/pm/j4/petroleum/mixin/ModMenuMixin.java +++ /dev/null @@ -1,11 +0,0 @@ -package pm.j4.petroleum.mixin; - -/** - * Mixin for in-game module management menu. - * Includes module activation/deactivation, as well as some configuration options. - * A separate menu for advanced configurations should also be added eventually. - * This module should handle the rendering of the menu and all of its buttons, - * while delegating button presses to @link pm.j4.petroleum.modules.menu.ModMenu - */ -public class ModMenuMixin { -} diff --git a/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java b/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java index e915a62..e8a7b45 100644 --- a/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java +++ b/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java @@ -10,9 +10,13 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import pm.j4.petroleum.PetroleumMod; import pm.j4.petroleum.modules.splash.SplashText; import pm.j4.petroleum.util.config.ConfigHolder; import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.module.ModuleBase; +import pm.j4.petroleum.util.module.option.BooleanOption; +import pm.j4.petroleum.util.module.option.ConfigurationOption; /** @@ -71,8 +75,13 @@ public class TitleScreenMixin extends Screen { locals = LocalCapture.CAPTURE_FAILSOFT) private void render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci, float f, int i, int j, float g, int l) { Optional config = ConfigManager.getConfig(); - if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")) { - drawStringWithShadow(matrices, this.textRenderer, SplashText.get(), 2, this.height - 20, blink(13108374) | l); + Optional splashText = PetroleumMod.getMod("petroleum.splashtext"); + if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext") + && splashText.isPresent()) { + Optional isActive = splashText.get().getConfigOption("petroleum.splashtext.active"); + if(isActive.isPresent() && ((BooleanOption)isActive.get()).getValue()) { + drawStringWithShadow(matrices, this.textRenderer, SplashText.get(), 2, this.height - 20, blink(13108374) | l); + } } } diff --git a/src/main/java/pm/j4/petroleum/modules/ExampleModule.java b/src/main/java/pm/j4/petroleum/modules/ExampleModule.java index 0bb285a..eceefac 100644 --- a/src/main/java/pm/j4/petroleum/modules/ExampleModule.java +++ b/src/main/java/pm/j4/petroleum/modules/ExampleModule.java @@ -1,8 +1,13 @@ package pm.j4.petroleum.modules; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import net.minecraft.client.MinecraftClient; +import net.minecraft.text.LiteralText; +import pm.j4.petroleum.gui.PModuleConfigEntry; +import pm.j4.petroleum.gui.PModuleConfigPane; import pm.j4.petroleum.util.module.ModuleBase; import pm.j4.petroleum.util.module.option.BooleanOption; import pm.j4.petroleum.util.module.option.ConfigurationOption; @@ -23,10 +28,10 @@ public class ExampleModule extends ModuleBase { } @Override - protected Map getDefaultConfig() { - Map options = new HashMap<>(); - options.put("petroleum.example_b_one", new BooleanOption("example")); - options.put("petroleum.example_b_two", new BooleanOption("example")); + public List getDefaultConfig() { + List options = new ArrayList<>(); + options.add(new BooleanOption("petroleum.example.b_one","example", this)); + options.add(new BooleanOption("petroleum.example.b_two","example", this)); return options; } diff --git a/src/main/java/pm/j4/petroleum/modules/bindings/BindingManager.java b/src/main/java/pm/j4/petroleum/modules/bindings/BindingManager.java index bcd25eb..33d4c39 100644 --- a/src/main/java/pm/j4/petroleum/modules/bindings/BindingManager.java +++ b/src/main/java/pm/j4/petroleum/modules/bindings/BindingManager.java @@ -9,9 +9,11 @@ import net.minecraft.text.TranslatableText; import org.lwjgl.glfw.GLFW; import pm.j4.petroleum.PetroleumMod; import pm.j4.petroleum.gui.PModuleConfigEntry; +import pm.j4.petroleum.gui.PModuleConfigPane; import pm.j4.petroleum.util.config.ConfigManager; import pm.j4.petroleum.util.config.GlobalConfig; import pm.j4.petroleum.util.module.ModuleBase; +import pm.j4.petroleum.util.module.option.ConfigurationOption; import pm.j4.petroleum.util.module.option.KeybindOption; /** @@ -37,7 +39,11 @@ public class BindingManager extends ModuleBase { } @Override - public List getConfigEntries() { + public List getConfigEntries(PModuleConfigPane sourcePane) { + + //TODO multiple binds per module + // thoughts: have modules include a list of module triggers/functions + // which replace the ModuleBase in bindings? List entries = new ArrayList<>(); Map mapped = new HashMap<>(); @@ -45,26 +51,13 @@ public class BindingManager extends ModuleBase { Map binds = ConfigManager.getConfig().get().globalConfig.bindings; binds.forEach((key, func) -> { - KeybindOption o = new KeybindOption(func.getModuleName() + " " + func.getCategory()); - o.fromKeybind(key, func); - mapped.put(o, func); + KeybindOption option = new KeybindOption(func.getModuleName() + " " + func.getCategory(), func.getModuleName() + " " + func.getCategory(), func); + option.fromKeybind(key, func); + mapped.put(option, func); }); } - mapped.forEach((bind, module) -> { - PModuleConfigEntry entry = new PModuleConfigEntry(bind, new TranslatableText(module.getModuleName())) { - //TODO keybinding. most likely involves mixin to take direct key input - // look into how keybinding in regular options screen works - @Override - public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - if (this.displayText != null) { - MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, displayText, x, y, 0xAAAAAA); - } - if (this.option != null) { - int fontHeight = MinecraftClient.getInstance().textRenderer.fontHeight; - MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, "Key Value: " + this.option.getStringValue(), x, y + fontHeight + 4, 0xFFFFFF); - } - } - }; + mapped.forEach((configEntry, module) -> { + PModuleConfigEntry entry = new PModuleConfigEntry(configEntry, new TranslatableText(module.getModuleName()), sourcePane); entries.add(entry); }); return entries; diff --git a/src/main/java/pm/j4/petroleum/modules/list/ModList.java b/src/main/java/pm/j4/petroleum/modules/list/ModList.java index a6933d3..cc473b3 100644 --- a/src/main/java/pm/j4/petroleum/modules/list/ModList.java +++ b/src/main/java/pm/j4/petroleum/modules/list/ModList.java @@ -2,7 +2,9 @@ package pm.j4.petroleum.modules.list; import java.util.ArrayList; import java.util.List; -import pm.j4.petroleum.PetroleumMod; +import java.util.Optional; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; import pm.j4.petroleum.util.module.ModuleBase; /** @@ -27,11 +29,12 @@ public class ModList extends ModuleBase { */ public static List getActive() { List result = new ArrayList<>(); - PetroleumMod.getActiveMods().forEach((mod) -> { + Optional config = ConfigManager.getConfig(); + config.ifPresent(configHolder -> configHolder.getEnabledModules().forEach((mod) -> { if (!mod.isHidden()) { result.add(mod); } - }); + })); return result; } } diff --git a/src/main/java/pm/j4/petroleum/modules/menu/ModMenu.java b/src/main/java/pm/j4/petroleum/modules/menu/ModMenu.java index d973c2a..7ed0500 100644 --- a/src/main/java/pm/j4/petroleum/modules/menu/ModMenu.java +++ b/src/main/java/pm/j4/petroleum/modules/menu/ModMenu.java @@ -15,6 +15,9 @@ import pm.j4.petroleum.util.module.ModuleBase; */ public class ModMenu extends ModuleBase { + /** + * The constant coordinates. + */ private static final Map coordinates = new HashMap<>(); /** @@ -47,6 +50,12 @@ public class ModMenu extends ModuleBase { }); } + /** + * Update coord. + * + * @param b the b + * @param c the c + */ public static void updateCoord(String b, ButtonInformation c) { if (c.x < 0.05) { c.x = 0.05; @@ -78,6 +87,11 @@ public class ModMenu extends ModuleBase { } } + /** + * Gets buttons. + * + * @return the buttons + */ public static Map getButtons() { return coordinates; } diff --git a/src/main/java/pm/j4/petroleum/modules/splash/SplashText.java b/src/main/java/pm/j4/petroleum/modules/splash/SplashText.java index e018387..c5b6f88 100644 --- a/src/main/java/pm/j4/petroleum/modules/splash/SplashText.java +++ b/src/main/java/pm/j4/petroleum/modules/splash/SplashText.java @@ -1,7 +1,14 @@ package pm.j4.petroleum.modules.splash; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.text.LiteralText; import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.gui.PModuleConfigEntry; +import pm.j4.petroleum.gui.PModuleConfigPane; import pm.j4.petroleum.util.module.ModuleBase; +import pm.j4.petroleum.util.module.option.BooleanOption; +import pm.j4.petroleum.util.module.option.ConfigurationOption; /** * The type Splash text. @@ -13,9 +20,16 @@ public class SplashText extends ModuleBase { public SplashText() { super("petroleum.splashtext", "petroleum.misc", + false, true, - true, - false); + true); + } + + @Override + public List getDefaultConfig() { + List options = new ArrayList<>(); + options.add(new BooleanOption("petroleum.splashtext.active", "Show the main menu version text.", this)); + return options; } /** diff --git a/src/main/java/pm/j4/petroleum/modules/xray/Xray.java b/src/main/java/pm/j4/petroleum/modules/xray/Xray.java index ff4b961..7e31116 100644 --- a/src/main/java/pm/j4/petroleum/modules/xray/Xray.java +++ b/src/main/java/pm/j4/petroleum/modules/xray/Xray.java @@ -2,7 +2,13 @@ package pm.j4.petroleum.modules.xray; import pm.j4.petroleum.util.module.ModuleBase; +/** + * The type Xray. + */ public class Xray extends ModuleBase { + /** + * Instantiates a new Xray. + */ public Xray() { super("petroleum.xray", "petroleum.render", diff --git a/src/main/java/pm/j4/petroleum/util/config/ConfigHolder.java b/src/main/java/pm/j4/petroleum/util/config/ConfigHolder.java index 4d6d6e8..f4a68ba 100644 --- a/src/main/java/pm/j4/petroleum/util/config/ConfigHolder.java +++ b/src/main/java/pm/j4/petroleum/util/config/ConfigHolder.java @@ -91,7 +91,4 @@ public class ConfigHolder { } } - public static void saveModule(ModuleBase module) { - - } } diff --git a/src/main/java/pm/j4/petroleum/util/config/ConfigManager.java b/src/main/java/pm/j4/petroleum/util/config/ConfigManager.java index a9e2e5a..f44e8b6 100644 --- a/src/main/java/pm/j4/petroleum/util/config/ConfigManager.java +++ b/src/main/java/pm/j4/petroleum/util/config/ConfigManager.java @@ -32,9 +32,13 @@ public class ConfigManager { /** * Prepare config file. + * + * @param path the path + * @param filename the filename + * @return the file */ private static File prepareConfigFile(String path, String filename) { - if(path != "") { + if (path != "") { File directory = new File(FabricLoader.getInstance().getConfigDir().toString(), path); if (!directory.exists()) directory.mkdir(); } @@ -53,14 +57,17 @@ public class ConfigManager { config.globalConfig = new DefaultConfig(); config.serverConfigs = new HashMap<>(); - config = load("", "petroleum.json", ConfigHolder.class); + config = load("petroleum/", "petroleum.json", ConfigHolder.class); initModules(); } + /** + * Init modules. + */ public static void initModules() { PetroleumMod.getActiveMods().forEach(module -> { - ModuleConfig options = load("modules/", module.getModuleName() + ".json", ModuleConfig.class); - if(options != null && options.options != null) { + ModuleConfig options = load("petroleum/modules/", module.getModuleName() + ".json", ModuleConfig.class); + if (options != null && options.options != null) { options.options.forEach((key, option) -> { if (module.hasOption(option.key)) { module.setConfigOption(option.key, option.value); @@ -72,6 +79,12 @@ public class ConfigManager { /** * Load. + * + * @param the type parameter + * @param path the path + * @param filename the filename + * @param tClass the t class + * @return the t */ private static T load(String path, String filename, Class tClass) { File file = prepareConfigFile(path, filename); @@ -100,21 +113,31 @@ public class ConfigManager { return null; } + /** + * Deserialize element t. + * + * @param the type parameter + * @param element the element + * @param tClass the t class + * @return the t + */ public static T deserializeElement(JsonElement element, Class tClass) { return GSON.fromJson(element, tClass); } /** * Save. + * + * @param the type parameter + * @param path the path + * @param filename the filename + * @param data the data */ private static void save(String path, String filename, T data) { File file = prepareConfigFile(path, filename); String json = GSON.toJson(data); try (FileWriter fileWriter = new FileWriter(file)) { - System.out.println("FILE WRITE ATTEMPT"); - System.out.println(path); - System.out.println(json); fileWriter.write(json); } catch (IOException e) { System.out.println("Couldn't save configuration file at " + path); @@ -122,19 +145,30 @@ public class ConfigManager { } } + /** + * Save module. + * + * @param b the b + */ public static void saveModule(ModuleBase b) { ModuleConfig c = new ModuleConfig(); c.options = GlobalConfig.serializeModuleConfiguration(b); - save("modules/", b.getModuleName() + ".json", c); + save("petroleum/modules/", b.getModuleName() + ".json", c); } + /** + * Save all modules. + */ public static void saveAllModules() { List mods = PetroleumMod.getActiveMods(); mods.forEach(ConfigManager::saveModule); } + /** + * Save global config. + */ public static void saveGlobalConfig() { - save("","petroleum.json", config); + save("petroleum/", "petroleum.json", config); } /** diff --git a/src/main/java/pm/j4/petroleum/util/config/GlobalConfig.java b/src/main/java/pm/j4/petroleum/util/config/GlobalConfig.java index ffa62c7..97a5d16 100644 --- a/src/main/java/pm/j4/petroleum/util/config/GlobalConfig.java +++ b/src/main/java/pm/j4/petroleum/util/config/GlobalConfig.java @@ -2,6 +2,7 @@ package pm.j4.petroleum.util.config; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import net.minecraft.client.options.KeyBinding; import net.minecraft.client.util.InputUtil; import pm.j4.petroleum.PetroleumMod; @@ -43,15 +44,20 @@ public class GlobalConfig extends Config { * @param func the func */ public void setBinding(KeyBinding bind, ModuleBase func) { + AtomicReference match = new AtomicReference<>(); if (bindings.containsValue(func)) { bindings.forEach((key, binding) -> { if (binding.equals(func)) { PetroleumMod.removeBind(key); - bindings.remove(key); + match.set(key); } }); } + if (match.get() != null) { + bindings.remove(match.get()); + } + if (PetroleumMod.isActive(func.getModuleName())) { PetroleumMod.addBind(bind); bindings.put(bind, func); @@ -69,6 +75,12 @@ public class GlobalConfig extends Config { moduleBase)); } + /** + * Reconstruct binding key binding. + * + * @param info the info + * @return the key binding + */ public static KeyBinding reconstructBinding(BindingInfo info) { return new KeyBinding( info.translationKey, @@ -79,7 +91,7 @@ public class GlobalConfig extends Config { } /** - * Extract binding binding info. + * Extract binding info. * * @param b the b * @param f the f @@ -147,8 +159,17 @@ public class GlobalConfig extends Config { }); } + /** + * The Button locations. + */ private final Map buttonLocations = new HashMap<>(); + /** + * Sets button. + * + * @param category the category + * @param buttonInformation the button information + */ public void setButton(String category, ButtonInformation buttonInformation) { if (buttonLocations.containsKey(category)) { buttonLocations.replace(category, buttonInformation); @@ -157,6 +178,12 @@ public class GlobalConfig extends Config { } } + /** + * Gets button. + * + * @param category the category + * @return the button + */ public ButtonInformation getButton(String category) { if (buttonLocations.containsKey(category)) { return buttonLocations.get(category); diff --git a/src/main/java/pm/j4/petroleum/util/data/ButtonInformation.java b/src/main/java/pm/j4/petroleum/util/data/ButtonInformation.java index b229bd2..3eb4834 100644 --- a/src/main/java/pm/j4/petroleum/util/data/ButtonInformation.java +++ b/src/main/java/pm/j4/petroleum/util/data/ButtonInformation.java @@ -1,10 +1,29 @@ package pm.j4.petroleum.util.data; +/** + * The type Button information. + */ public class ButtonInformation { + /** + * The X. + */ public double x; + /** + * The Y. + */ public double y; - public boolean open; + /** + * The Open. + */ + public final boolean open; + /** + * Instantiates a new Button information. + * + * @param x the x + * @param y the y + * @param open the open + */ public ButtonInformation(double x, double y, boolean open) { this.x = x; this.y = y; diff --git a/src/main/java/pm/j4/petroleum/util/data/Category.java b/src/main/java/pm/j4/petroleum/util/data/Category.java index 1605615..c2210a5 100644 --- a/src/main/java/pm/j4/petroleum/util/data/Category.java +++ b/src/main/java/pm/j4/petroleum/util/data/Category.java @@ -7,7 +7,15 @@ import java.util.Map; import pm.j4.petroleum.PetroleumMod; import pm.j4.petroleum.util.module.ModuleBase; +/** + * The type Category. + */ public class Category { + /** + * Gets category map. + * + * @return the category map + */ public static Map> getCategoryMap() { List modules = PetroleumMod.getActiveMods(); Map> categoryMap = new HashMap<>(); @@ -27,6 +35,12 @@ public class Category { return categoryMap; } + /** + * Gets by category. + * + * @param category the category + * @return the by category + */ public static List getByCategory(String category) { return getCategoryMap().containsKey(category) ? getCategoryMap().get(category) : new ArrayList<>(); } diff --git a/src/main/java/pm/j4/petroleum/util/data/ModuleConfig.java b/src/main/java/pm/j4/petroleum/util/data/ModuleConfig.java index c96ead0..33c1365 100644 --- a/src/main/java/pm/j4/petroleum/util/data/ModuleConfig.java +++ b/src/main/java/pm/j4/petroleum/util/data/ModuleConfig.java @@ -2,6 +2,12 @@ package pm.j4.petroleum.util.data; import java.util.Map; +/** + * The type Module config. + */ public class ModuleConfig { + /** + * The Options. + */ public Map options; } diff --git a/src/main/java/pm/j4/petroleum/util/data/OptionSerializiable.java b/src/main/java/pm/j4/petroleum/util/data/OptionSerializiable.java index c57f57e..197332f 100644 --- a/src/main/java/pm/j4/petroleum/util/data/OptionSerializiable.java +++ b/src/main/java/pm/j4/petroleum/util/data/OptionSerializiable.java @@ -9,13 +9,14 @@ public class OptionSerializiable { /** * Instantiates a new Option serializiable. * - * @param value the value * @param key the key + * @param value the value */ public OptionSerializiable(String key, JsonElement value) { this.value = value; this.key = key; } + /** * The Value. */ diff --git a/src/main/java/pm/j4/petroleum/util/module/ModuleBase.java b/src/main/java/pm/j4/petroleum/util/module/ModuleBase.java index 6869f60..012d550 100644 --- a/src/main/java/pm/j4/petroleum/util/module/ModuleBase.java +++ b/src/main/java/pm/j4/petroleum/util/module/ModuleBase.java @@ -5,6 +5,7 @@ import java.util.*; import net.minecraft.client.MinecraftClient; import net.minecraft.text.TranslatableText; import pm.j4.petroleum.gui.PModuleConfigEntry; +import pm.j4.petroleum.gui.PModuleConfigPane; import pm.j4.petroleum.util.config.ConfigHolder; import pm.j4.petroleum.util.config.ConfigManager; import pm.j4.petroleum.util.module.option.ConfigurationOption; @@ -19,6 +20,7 @@ public abstract class ModuleBase { * Parameters should be constant across restarts. * * @param name The name of the module + * @param category the category * @param activatable Whether a module can be activated, or if it will remain in the state it was upon startup * @param hidden Whether the module will show up in @link pm.j4.petroleum.modules.menu.ModMenu or the active module list * @param hasConfigMenu whether a button in the configuration menu will show @@ -30,7 +32,7 @@ public abstract class ModuleBase { this.activatable = activatable; this.hidden = hidden; this.hasConfigMenu = hasConfigMenu; - this.moduleOptions = this.getDefaultConfig(); + this.moduleOptions = this.convertDefaultConfig(); } /** @@ -71,8 +73,16 @@ public abstract class ModuleBase { return this.moduleName; } + /** + * The Category. + */ private final String category; + /** + * Gets category. + * + * @return the category + */ public String getCategory() { return this.category; } @@ -165,6 +175,21 @@ public abstract class ModuleBase { return false; } + public void updateConfigOption(String key, ConfigurationOption option) { + System.out.println("update config option" + key + option.getStringValue()); + System.out.println(moduleOptions.keySet()); + if(moduleOptions.containsKey(key)) { + System.out.println("matched"); + moduleOptions.replace(key, option); + } + } + + /** + * Has option boolean. + * + * @param key the key + * @return the boolean + */ public boolean hasOption(String key) { return moduleOptions.containsKey(key); } @@ -174,8 +199,17 @@ public abstract class ModuleBase { * * @return the default config */ - protected Map getDefaultConfig() { - return new HashMap<>(); + protected List getDefaultConfig() { + return new ArrayList<>(); + } + + private Map convertDefaultConfig() { + List options = this.getDefaultConfig(); + Map mapped = new HashMap<>(); + options.forEach((option) -> { + mapped.put(option.getConfigKey(), option); + }); + return mapped; } /** @@ -196,9 +230,9 @@ public abstract class ModuleBase { * * @return the config entries */ - public List getConfigEntries() { + public List getConfigEntries(PModuleConfigPane sourcePane) { List entries = new ArrayList<>(); - this.getModuleConfiguration().forEach((name, option) -> entries.add(new PModuleConfigEntry(option, new TranslatableText(name)))); + this.getModuleConfiguration().forEach((name, option) -> entries.add(new PModuleConfigEntry(option, new TranslatableText(name), sourcePane))); return entries; } diff --git a/src/main/java/pm/j4/petroleum/util/module/option/BooleanOption.java b/src/main/java/pm/j4/petroleum/util/module/option/BooleanOption.java index 8b797dd..c68e08a 100644 --- a/src/main/java/pm/j4/petroleum/util/module/option/BooleanOption.java +++ b/src/main/java/pm/j4/petroleum/util/module/option/BooleanOption.java @@ -2,16 +2,32 @@ package pm.j4.petroleum.util.module.option; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; +import pm.j4.petroleum.util.module.ModuleBase; /** * The type Boolean value. */ public class BooleanOption extends ConfigurationOption { + /** + * The Value. + */ private boolean value; - public BooleanOption(String description) { - super(description); + + /** + * Instantiates a new Configuration option. + * + * @param key + * @param description the description + */ + public BooleanOption(String key, String description, ModuleBase parent) { + super(key, description, parent); } + public boolean getValue() { + return value; + } + public void setValue(boolean value) { this.value = value; } + @Override public String getStringValue() { return Boolean.toString(value); diff --git a/src/main/java/pm/j4/petroleum/util/module/option/ConfigurationOption.java b/src/main/java/pm/j4/petroleum/util/module/option/ConfigurationOption.java index 0ec0f39..31005db 100644 --- a/src/main/java/pm/j4/petroleum/util/module/option/ConfigurationOption.java +++ b/src/main/java/pm/j4/petroleum/util/module/option/ConfigurationOption.java @@ -1,27 +1,59 @@ package pm.j4.petroleum.util.module.option; import com.google.gson.JsonElement; +import pm.j4.petroleum.util.module.ModuleBase; /** * The type Configuration option. - * */ public abstract class ConfigurationOption { + /** + * The Description. + */ private final String description; + private final String key; + private final ModuleBase parent; - protected ConfigurationOption(String description) { + /** + * Instantiates a new Configuration option. + * + * @param description the description + */ + public ConfigurationOption(String key, String description, ModuleBase parent) { this.description = description; + this.key = key; + this.parent = parent; } - + /** + * Gets description. + * + * @return the description + */ public final String getDescription() { return this.description; } + public final String getConfigKey() { return key; } + public final ModuleBase getParent() { return parent; } + /** + * Gets string value. + * + * @return the string value + */ public abstract String getStringValue(); + + /** + * From json. + * + * @param e the e + */ public abstract void fromJson(JsonElement e); + + /** + * To json json element. + * + * @return the json element + */ public abstract JsonElement toJson(); - public void update() { - - } } diff --git a/src/main/java/pm/j4/petroleum/util/module/option/IntegerOption.java b/src/main/java/pm/j4/petroleum/util/module/option/IntegerOption.java index 2d8faf2..ea938e6 100644 --- a/src/main/java/pm/j4/petroleum/util/module/option/IntegerOption.java +++ b/src/main/java/pm/j4/petroleum/util/module/option/IntegerOption.java @@ -2,16 +2,29 @@ package pm.j4.petroleum.util.module.option; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; +import pm.j4.petroleum.util.module.ModuleBase; /** * The type Integer value. */ public class IntegerOption extends ConfigurationOption { + /** + * The Value. + */ private int value; - protected IntegerOption(String description) { - super(description); + + /** + * Instantiates a new Configuration option. + * + * @param key + * @param description the description + * @param parent + */ + public IntegerOption(String key, String description, ModuleBase parent) { + super(key, description, parent); } + @Override public String getStringValue() { return Integer.toString(value); diff --git a/src/main/java/pm/j4/petroleum/util/module/option/KeybindOption.java b/src/main/java/pm/j4/petroleum/util/module/option/KeybindOption.java index eeab653..7fe2d6e 100644 --- a/src/main/java/pm/j4/petroleum/util/module/option/KeybindOption.java +++ b/src/main/java/pm/j4/petroleum/util/module/option/KeybindOption.java @@ -12,10 +12,28 @@ import pm.j4.petroleum.util.module.ModuleBase; */ public class KeybindOption extends ConfigurationOption { + /** + * The Value. + */ private KeyBinding value; + /** + * The Converted value. + */ private BindingInfo convertedValue; - public KeybindOption(String description) { - super(description); + + /** + * Instantiates a new Configuration option. + * + * @param key + * @param description the description + * @param parent + */ + public KeybindOption(String key, String description, ModuleBase parent) { + super(key, description, parent); + } + + public String getTranslationKey() { + return value.getTranslationKey(); } @Override @@ -35,6 +53,12 @@ public class KeybindOption extends ConfigurationOption { return null; } + /** + * From keybind. + * + * @param bind the bind + * @param base the base + */ public void fromKeybind(KeyBinding bind, ModuleBase base) { this.value = bind; this.convertedValue = GlobalConfig.extractBinding(bind, base); diff --git a/src/main/java/pm/j4/petroleum/util/module/option/ListOption.java b/src/main/java/pm/j4/petroleum/util/module/option/ListOption.java index c1f6b5a..204eed6 100644 --- a/src/main/java/pm/j4/petroleum/util/module/option/ListOption.java +++ b/src/main/java/pm/j4/petroleum/util/module/option/ListOption.java @@ -1,10 +1,23 @@ package pm.j4.petroleum.util.module.option; import com.google.gson.JsonElement; +import pm.j4.petroleum.util.module.ModuleBase; +/** + * The type List option. + */ public class ListOption extends ConfigurationOption { - protected ListOption(String description) { - super(description); + + + /** + * Instantiates a new Configuration option. + * + * @param key + * @param description the description + * @param parent + */ + public ListOption(String key, String description, ModuleBase parent) { + super(key, description, parent); } @Override diff --git a/src/main/java/pm/j4/petroleum/util/module/option/StringOption.java b/src/main/java/pm/j4/petroleum/util/module/option/StringOption.java index b276650..590a5de 100644 --- a/src/main/java/pm/j4/petroleum/util/module/option/StringOption.java +++ b/src/main/java/pm/j4/petroleum/util/module/option/StringOption.java @@ -2,18 +2,30 @@ package pm.j4.petroleum.util.module.option; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; +import pm.j4.petroleum.util.module.ModuleBase; /** * The type String value. */ public class StringOption extends ConfigurationOption { + /** + * The Value. + */ private String value; - protected StringOption(String description) { - super(description); + /** + * Instantiates a new Configuration option. + * + * @param key + * @param description the description + * @param parent + */ + public StringOption(String key, String description, ModuleBase parent) { + super(key, description, parent); } + public String getStringValue() { return value; } diff --git a/src/main/resources/assets/petroleum/lang/en_us.json b/src/main/resources/assets/petroleum/lang/en_us.json new file mode 100644 index 0000000..4c689ba --- /dev/null +++ b/src/main/resources/assets/petroleum/lang/en_us.json @@ -0,0 +1,13 @@ +{ + "petroleum.bindings": "Binding Manager", + "petroleum.example": "Test Module", + "petroleum.splashtext": "Splash Text", + "petroleum.modlist": "Module List", + "petroleum.modmenu": "Mod Menu", + + "petroleum.xray": "X-ray", + + "petroleum.misc": "Miscellaneous", + "petroleum.render": "Render", + "petroleum.options": "Petroleum Options" +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 849ab35..f31455b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -12,10 +12,8 @@ "homepage": "https://j4.pm/", "sources": "https://gitdab.com/jane/petroleum" }, - "license": "WTFPL", "icon": "assets/petroleum/icon.png", - "environment": "*", "entrypoints": { "main": [ @@ -25,11 +23,11 @@ "mixins": [ "petroleum.mixins.json" ], - "depends": { "fabricloader": ">=0.7.4", "fabric": "*", - "minecraft": "1.16.x" + "minecraft": "1.16.x", + "kerosene": ">=0.1.5" }, "suggests": { "flamingo": "*" diff --git a/src/main/resources/petroleum.mixins.json b/src/main/resources/petroleum.mixins.json index 2c458f3..1601ae6 100644 --- a/src/main/resources/petroleum.mixins.json +++ b/src/main/resources/petroleum.mixins.json @@ -6,11 +6,11 @@ "mixins": [ ], "client": [ - "TitleScreenMixin", - "OptionsMenuMixin", - "EntryListWidgetAccessor", "DebugHudMixin", - "ModListMixin" + "EntryListWidgetAccessor", + "ModListMixin", + "OptionsMenuMixin", + "TitleScreenMixin" ], "injectors": { "defaultRequire": 1