update to 0.1.4

This commit is contained in:
jane 2020-12-19 23:25:27 -05:00
parent 17e135f3d3
commit 86c9b6e3f7
69 changed files with 4022 additions and 128 deletions

View File

@ -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

View File

@ -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<ModuleBase> 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<ModuleBase> getMod(String modName) {
return activeMods.stream().filter(mod -> mod.getModuleName().equals(modName)).findFirst();
}
/**
* Gets active mods.
*
* @return the active mods
*/
public static List<ModuleBase> getActiveMods() {
return activeMods;
}
/**
* The constant registeredBinds.
*/
private static final List<KeyBinding> 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<KeyBinding> 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> modContainer = FabricLoader.getInstance().getModContainer("petroleum");
modContainer.ifPresent(container -> modData = container.getMetadata());
Optional<ConfigHolder> 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);
}
}
}));
}
}

View File

@ -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<String, ButtonInformation> 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();
}
}

View File

@ -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<PModuleConfigEntry> {
/**
* 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
}
}
}
}

View File

@ -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<PModuleConfigEntry> {
/**
* 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();
}
}

View File

@ -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<POptionEntry> {
/**
* The Parent.
*/
private final POptionsScreen parent;
/**
* The Module id.
*/
private String moduleId = null;
/**
* The Mods.
*/
private List<ModuleBase> mods;
/**
* The Extra mods.
*/
private final Set<ModuleBase> 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();
}
}

View File

@ -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<ModuleBase> 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<ModuleBase> 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();
}
}

View File

@ -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<POptionEntry> {
/**
* 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;
}
}

View File

@ -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<ModuleBase> 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;
}
}
}

View File

@ -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<String> list) {
Optional<ConfigHolder> config = ConfigManager.getConfig();
if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")) {
list.add("[Petroleum] " + SplashText.get() + " loaded");
}
}
}

View File

@ -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();
}

View File

@ -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<ConfigHolder> 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<ModuleBase> modules = ModList.getActive();
List<TranslatableText> 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);
}
}
}

View File

@ -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));
}));
}
}

View File

@ -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.
* <p>
*
* @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<ConfigHolder> 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));
}
}

View File

@ -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<String, ConfigurationOption> getDefaultConfig() {
Map<String, ConfigurationOption> 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");
}
}

View File

@ -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;
}

View File

@ -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<PModuleConfigEntry> getConfigEntries() {
List<PModuleConfigEntry> entries = new ArrayList<>();
Map<KeybindOption, ModuleBase> mapped = new HashMap<>();
if (ConfigManager.getConfig().isPresent()) {
Map<KeyBinding, ModuleBase> 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<ModuleBase> 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());
}
}
}

View File

@ -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<ModuleBase> getActive() {
List<ModuleBase> result = new ArrayList<>();
Optional<ConfigHolder> config = ConfigManager.getConfig();
if(config.isPresent()) {
config.get().getEnabledModules().forEach((mod) -> {
if (!mod.isHidden()) {
result.add(mod);
}
});
}
return result;
}
}

View File

@ -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<String, ButtonInformation> 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<String, List<ModuleBase>> 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<String, ButtonInformation> getButtons() {
return coordinates;
}
}

View File

@ -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<PModuleConfigEntry> getConfigEntries() {
List<PModuleConfigEntry> 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";
}
}

View File

@ -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);
}
}

View File

@ -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<String> 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);
}
}
}
}
}

View File

@ -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<String, ServerConfig> 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<ModuleBase> getEnabledModules() {
List<ModuleBase> 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) {
}
}

View File

@ -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 <T> the type parameter
* @param path the path
* @param filename the filename
* @param tClass the t class
* @return the t
*/
private static <T> T load(String path, String filename, Class<T> 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 <T> the type parameter
* @param element the element
* @param tClass the t class
* @return the t
*/
public static <T> T deserializeElement(JsonElement element, Class<T> tClass) {
return GSON.fromJson(element, tClass);
}
/**
* Save.
*
* @param <T> the type parameter
* @param path the path
* @param filename the filename
* @param data the data
*/
private static <T> 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<ModuleBase> 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<ConfigHolder> getConfig() {
if (config == null) {
return Optional.empty();
}
return Optional.of(config);
}
}
/**
* The type Serialization helper.
*/
class SerializationHelper {
/**
* The constant s.
*/
private static final JsonSerializer<GlobalConfig> 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<GlobalConfig> GLOBAL_CONFIG_JSON_DESERIALIZER = ((json, typeOfT, ctx) -> {
JsonObject obj = json.getAsJsonObject();
List<BindingInfo> bindings = new ArrayList<>();
if (obj.has("bindings")) {
obj.get("bindings").getAsJsonArray().forEach(b -> bindings.add(ctx.deserialize(b, BindingInfo.class)));
}
List<String> modules = new ArrayList<>();
if (obj.has("enabled_modules")) {
obj.get("enabled_modules").getAsJsonArray().forEach(m -> modules.add(m.getAsString()));
}
GlobalConfig cfg = new GlobalConfig();
Map<String, List<OptionSerializiable>> options;
Type type = new TypeToken<Map<String, List<OptionSerializiable>>>() {
}.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<GlobalConfig> getGlobalSerializer() {
return GLOBAL_CONFIG_JSON_SERIALIZER;
}
/**
* Gets deserializer.
*
* @return the deserializer
*/
public static JsonDeserializer<GlobalConfig> getGlobalDeserializer() {
return GLOBAL_CONFIG_JSON_DESERIALIZER;
}
}

View File

@ -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");
}
}

View File

@ -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<KeyBinding, ModuleBase> 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<ModuleBase> 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<BindingInfo> serializeBindings() {
List<BindingInfo> b = new ArrayList<>();
bindings.forEach((k, f) -> b.add(extractBinding(k, f)));
return b;
}
/**
* Deserialize bindings.
*
* @param info the info
*/
public void deserializeBindings(List<BindingInfo> info) {
info.forEach(this::convertBinding);
}
/**
* Serialize module configuration list.
*
* @param module the module
* @return the list
*/
public static Map<String, OptionSerializiable> serializeModuleConfiguration(ModuleBase module) {
Map<String, OptionSerializiable> opts = new HashMap<>();
Map<String, ConfigurationOption> 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<OptionSerializiable> opts, ModuleBase module) {
opts.forEach(option -> {
if (module.hasOption(option.key)) {
module.setConfigOption(option.key, option.value);
}
});
}
/**
* The Button locations.
*/
private final Map<String, ButtonInformation> 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;
}
}

View File

@ -0,0 +1,11 @@
package pm.j4.petroleum.util.config;
/**
* The type Server config.
*/
public class ServerConfig extends Config {
/**
* The Address.
*/
public String address = "";
}

View File

@ -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;
}
}

View File

@ -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<String, List<ModuleBase>> getCategoryMap() {
List<ModuleBase> modules = PetroleumMod.getActiveMods();
Map<String, List<ModuleBase>> categoryMap = new HashMap<>();
modules.forEach(module -> {
if (!categoryMap.containsKey(module.getCategory())) {
List<ModuleBase> m = new ArrayList<>();
m.add(module);
categoryMap.put(module.getCategory(), m);
} else {
List<ModuleBase> m = categoryMap.get(module.getCategory());
List<ModuleBase> 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<ModuleBase> getByCategory(String category) {
return getCategoryMap().containsKey(category) ? getCategoryMap().get(category) : new ArrayList<>();
}
}

View File

@ -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<String, OptionSerializiable> options;
}

View File

@ -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;
}

View File

@ -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<ConfigHolder> 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<String, ConfigurationOption> moduleOptions;
/**
* Gets module configuration.
*
* @return the module configuration
*/
public Map<String, ConfigurationOption> getModuleConfiguration() {
return moduleOptions;
}
/**
* Sets config option.
* This will fail if the option is not already present in a module.
* <p>
*
* @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<String, ConfigurationOption> getDefaultConfig() {
return new HashMap<>();
}
/**
* Gets config option.
*
* @param key the key
* @return the config option
*/
public Optional<ConfigurationOption> 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<PModuleConfigEntry> getConfigEntries() {
List<PModuleConfigEntry> 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());
}
}

View File

@ -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);
}
}

View File

@ -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() {
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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<PModuleConfigEntry> {
public class PModuleConfigEntry extends ElementListWidget.Entry<PModuleConfigEntry> {
/**
* The Option.
*/
protected final ConfigurationOption option;
protected ConfigurationOption option;
/**
* The Display text.
*/
protected final Text displayText;
private PModuleConfigPane parent;
private List<Element> 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<? extends Element> 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<PModuleConfigEntry
if (this.displayText != null) {
MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, displayText, x, y, 0xAAAAAA);
}
System.out.println(option);
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.getStringValue()), x, y + fontHeight + 4, 0xFFFFFF);
//TODO use TranslatableText instead of LiteralText
MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, new LiteralText(option.getDescription() + " " + option.getStringValue()), x, y + fontHeight + 4, 0xFFFFFF);
System.out.println(elements.size());
if(elements.size() == 0) {
String className = option.getClass().toString();
System.out.println(className);
if (className.equals(BooleanOption.class.toString())) {
System.out.println("boolean");
elements.add(new ButtonWidget(x, y + (int)(fontHeight * 2.5),
entryWidth,
fontHeight * 2,
new LiteralText(((BooleanOption)option).getValue() ? this.trueValue : this.falseValue), (button) -> {
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<ConfigHolder> 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);
}
});
}
}
}
}

View File

@ -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<PModuleConfigEntry> {
public class PModuleConfigPane extends ElementListWidget<PModuleConfigEntry> {
/**
* The Parent.
*/
@ -23,6 +24,8 @@ public class PModuleConfigPane extends EntryListWidget<PModuleConfigEntry> {
*/
private POptionEntry lastSelected;
private PModuleConfigEntry selectedConfigEntry;
/**
* Instantiates a new P module config pane.
*
@ -37,15 +40,15 @@ public class PModuleConfigPane extends EntryListWidget<PModuleConfigEntry> {
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<PModuleConfigEntry> {
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<PModuleConfigEntry> {
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);

View File

@ -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<ModuleBase> 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();

View File

@ -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);

View File

@ -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 {
}

View File

@ -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<ConfigHolder> 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<ModuleBase> splashText = PetroleumMod.getMod("petroleum.splashtext");
if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")
&& splashText.isPresent()) {
Optional<ConfigurationOption> 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);
}
}
}

View File

@ -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<String, ConfigurationOption> getDefaultConfig() {
Map<String, ConfigurationOption> options = new HashMap<>();
options.put("petroleum.example_b_one", new BooleanOption("example"));
options.put("petroleum.example_b_two", new BooleanOption("example"));
public List<ConfigurationOption> getDefaultConfig() {
List<ConfigurationOption> 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;
}

View File

@ -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<PModuleConfigEntry> getConfigEntries() {
public List<PModuleConfigEntry> 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<PModuleConfigEntry> entries = new ArrayList<>();
Map<KeybindOption, ModuleBase> mapped = new HashMap<>();
@ -45,26 +51,13 @@ public class BindingManager extends ModuleBase {
Map<KeyBinding, ModuleBase> 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;

View File

@ -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<ModuleBase> getActive() {
List<ModuleBase> result = new ArrayList<>();
PetroleumMod.getActiveMods().forEach((mod) -> {
Optional<ConfigHolder> config = ConfigManager.getConfig();
config.ifPresent(configHolder -> configHolder.getEnabledModules().forEach((mod) -> {
if (!mod.isHidden()) {
result.add(mod);
}
});
}));
return result;
}
}

View File

@ -15,6 +15,9 @@ import pm.j4.petroleum.util.module.ModuleBase;
*/
public class ModMenu extends ModuleBase {
/**
* The constant coordinates.
*/
private static final Map<String, ButtonInformation> 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<String, ButtonInformation> getButtons() {
return coordinates;
}

View File

@ -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<ConfigurationOption> getDefaultConfig() {
List<ConfigurationOption> options = new ArrayList<>();
options.add(new BooleanOption("petroleum.splashtext.active", "Show the main menu version text.", this));
return options;
}
/**

View File

@ -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",

View File

@ -91,7 +91,4 @@ public class ConfigHolder {
}
}
public static void saveModule(ModuleBase module) {
}
}

View File

@ -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 <T> the type parameter
* @param path the path
* @param filename the filename
* @param tClass the t class
* @return the t
*/
private static <T> T load(String path, String filename, Class<T> tClass) {
File file = prepareConfigFile(path, filename);
@ -100,21 +113,31 @@ public class ConfigManager {
return null;
}
/**
* Deserialize element t.
*
* @param <T> the type parameter
* @param element the element
* @param tClass the t class
* @return the t
*/
public static <T> T deserializeElement(JsonElement element, Class<T> tClass) {
return GSON.fromJson(element, tClass);
}
/**
* Save.
*
* @param <T> the type parameter
* @param path the path
* @param filename the filename
* @param data the data
*/
private static <T> 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<ModuleBase> mods = PetroleumMod.getActiveMods();
mods.forEach(ConfigManager::saveModule);
}
/**
* Save global config.
*/
public static void saveGlobalConfig() {
save("","petroleum.json", config);
save("petroleum/", "petroleum.json", config);
}
/**

View File

@ -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<KeyBinding> 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<String, ButtonInformation> 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);

View File

@ -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;

View File

@ -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<String, List<ModuleBase>> getCategoryMap() {
List<ModuleBase> modules = PetroleumMod.getActiveMods();
Map<String, List<ModuleBase>> 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<ModuleBase> getByCategory(String category) {
return getCategoryMap().containsKey(category) ? getCategoryMap().get(category) : new ArrayList<>();
}

View File

@ -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<String, OptionSerializiable> options;
}

View File

@ -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.
*/

View File

@ -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<String, ConfigurationOption> getDefaultConfig() {
return new HashMap<>();
protected List<ConfigurationOption> getDefaultConfig() {
return new ArrayList<>();
}
private Map<String, ConfigurationOption> convertDefaultConfig() {
List<ConfigurationOption> options = this.getDefaultConfig();
Map<String, ConfigurationOption> 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<PModuleConfigEntry> getConfigEntries() {
public List<PModuleConfigEntry> getConfigEntries(PModuleConfigPane sourcePane) {
List<PModuleConfigEntry> 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;
}

View File

@ -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);

View File

@ -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() {
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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"
}

View File

@ -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": "*"

View File

@ -6,11 +6,11 @@
"mixins": [
],
"client": [
"TitleScreenMixin",
"OptionsMenuMixin",
"EntryListWidgetAccessor",
"DebugHudMixin",
"ModListMixin"
"EntryListWidgetAccessor",
"ModListMixin",
"OptionsMenuMixin",
"TitleScreenMixin"
],
"injectors": {
"defaultRequire": 1